diff --git a/etc/common-primes.txt b/etc/common-primes.txt new file mode 100644 index 0000000..e9230b8 --- /dev/null +++ b/etc/common-primes.txt @@ -0,0 +1,372 @@ + +## taken from https://svn.nmap.org/nmap/scripts/ssl-dh-params.nse + +# "mod_ssl 2.0.x/512-bit MODP group with safe prime modulus" +D4BCD52406F69B35994B88DE5DB89682C8157F62D8F33633EE5772F11F05AB22D6B5145B9F241E5ACC31FF090A4BC71148976F76795094E71E7903529F5A824B + +# "mod_ssl 2.2.x/512-bit MODP group with safe prime modulus" +E6969D3D495BE32C7CF180C3BDD4798E91B7818251BB055E2A2064904A79A770FA15A259CBD523A6A6EF09C43048D5A22F971F3C20129B48000E6EDD061CBC053E371D794E5327DF611EBBBE1BAC9B5C6044CF023D76E05EEA9BAD991B13A63C974E9EF1839EB5DB125136F7262E56A8871538DFD823C6505085E21F0DD5C86B + +# "mod_ssl 2.2.x/512-bit MODP group with safe prime modulus" +9FDB8B8A004544F0045F1737D0BA2E0B274CDF1A9F588218FB435316A16E374171FD19D8D8F37C39BF863FD60E3E300680A3030C6E4C3757D08F70E6AA871033 + +# "mod_ssl 2.2.x/1024-bit MODP group with safe prime modulus" +D67DE440CBBBDC1936D693D34AFD0AD50C84D239A45F520BB88174CB98BCE951849F912E639C72FB13B4B4D7177E16D55AC179BA420B2A29FE324A467A635E81FF5901377BEDDCFD33168A461AAD3B72DAE8860078045B07A7DBCA7874087D1510EA9FCC9DDD330507DD62DB88AEAA747DE0F4D6E2BD68B0E7393E0F24218EB3 + +# "nginx/1024-bit MODP group with safe prime modulus" +BBBC2DCAD84674907C43FCF580E9CFDBD958A3F568B42D4B08EED4EB0FB3504C6C030276E710800C5CCBBAA8922614C5BEECA565A5FDF1D287A2BC049BE6778060E91A92A757E3048F68B076F7D36CC8F29BA5DF81DC2CA725ECE66270CC9A5035D8CECEEF9EA0274A63AB1E58FAFD4988D0F65D146757DA071DF045CFE16B9B + +# "sun.security.provider/512-bit DSA group with 160-bit prime order subgroup" +FCA682CE8E12CABA26EFCCF7110E526DB078B05EDECBCD1EB4A208F3AE1617AE01F35B91A47E6DF63413C5E12ED0899BCD132ACD50D99151BDC43EE737592E17 + +# "sun.security.provider/768-bit DSA group with 160-bit prime order subgroup" +E9E642599D355F37C97FFD3567120B8E25C9CD43E927B3A9670FBEC5D890141922D2C3B3AD2480093799869D1E846AAB49FAB0AD26D2CE6A22219D470BCE7D777D4A21FBE9C270B57F607002F3CEF8393694CF45EE3688C11A8C56AB127A3DAF + +# "sun.security.provider/1024-bit DSA group with 160-bit prime order subgroup" +FD7F53811D75122952DF4A9C2EECE4E7F611B7523CEF4400C31E3F80B6512669455D402251FB593D8D58FABFC5F5BA30F6CB9B556CD7813B801D346FF26660B76B9950A5A49F9FE8047B1022C24FBBA9D7FEB7C61BF83B57E7C6A8A6150F04FB83F6D3C51EC3023554135A169132F675F3AE2B61D72AEFF22203199DD14801C7 + +# "openssl/512-bit MODP group with safe prime modulus" +DA583C16D9852289D0E4AF756F4CCA92DD4BE533B804FB0FED94EF9C8A4403ED574650D36999DB29D776276BA2D3D412E218F4DD1E084CF6D8003E7C4774E833 + +# "openssl/1024-bit MODP group with safe prime modulus" +97F64261CAB505DD2828E13F1D68B6D3DBD0F313047F40E856DA58CB13B8A1BF2B783A4C6D59D5F92AFC6CFF3D693F78B23D4F3160A9502E3EFAF7AB5E1AD5A65E554313828DA83B9FF2D941DEE95689FADAEA0936ADDF1971FE635B20AF470364603C2DE059F54B650AD8FA0CF70121C74799D7587132BE9B999BB9B787E8AB + +# "openssl/2048-bit MODP group with safe prime modulus" +ED928935824555CB3BFBA2765A690461BF21F3AB53D2CD21DAFF78191152F10EC1E255BD686F680053B9226A2FE49A341F65CC59328ABDB1DB49EDDFA71266C3FD21047018F07FD6F758511972827B22A934181D2FCB21CF6D92AE43B6A829C727A3CB00C5F2E5FB0AA45985A2BDAD45F0B3ADF9E08135EED983B3CCAEEAEB66E6A95766B9F128A53F2280D70BA6F671939B810EF85A90E6CCCA6F665F7AC0101A1EF0FC2DB6080C6228B0ECDB8928EE0CA83D6594691669533C536013B02BA7D48287AD1C729E4135FCC27CE951DE6185FC199B76600F33F86BB3CA520E29C307E89016CCCC0019B6ADC3A4308B33A1AFD88C8D9D01DBA4C4DD7F0BBD6F38C3 + +# "openssl/2048-bit MODP group with safe prime modulus" +AED037C3BDF33FA2EEDC4390B70A20897B770175E9B92EB20F8061CCD4B5A591723C7934FDA9F9F3274490F8506472835BE059271C4F2C035A4EE756A36613F1382DBD474DE8A4A0322122E8C730A83C3E4800EEBD6F8548A5181711BA545231C843FAC4175FFAF849C440DB446D8462C1C3451B49EFA829F5C48A4C7BAC7F647EE000151AA9ED81101B36AB5C39AAFFEC54A3F8F97C1B7BF406DCB42DC092A5BAA06259EFEB3FAB12B426982E8F3EF4B3F7B4C3302A24C8AA4213D845035CE4A8ADD31F816616F19E21A5C95080597F8980AD6B814E35855B79E6844491527D552B72B7C78D8D6B993A736F8486B30588B8F1B87E89668A8BD3F13DDC517D4B + +# "openssl/4096-bit MODP group with safe prime modulus" +FEEAD19DBEAF90F61CFCA1065D69DB08839A2A2B6AEF2488ABD7531FBB3E462E7DCECEFBCEDCBBBDF56549EE951530568188C3D97294166B6AABA0AA5CC8555F9125503A180E90324C7F39C6A3452F3142EE72AB7DFFC74C528DB6DA76D9C644F55D083E9CDE74F7E742413B69476617D2670F2BF6D59FFCD7C3BDDEED41E2BD2CCDD9E612F1056CAB88C441D7F9BA74651ED1A84D407A27D71895F777AB6C7763CC00E6F1C30B2FE79446927E74BC73B8431B53011AF5AD1515E63DC1DE83CC802ECE7DFC71FBDF179F8E41D7F1B43EBA75D5A9C3B11D4F1B0B5A0988A9AACBCCC1051226DC8410E41693EC8591E31EE2F5AFDFAEDE122D1277FC270BE4D25C1137A58BE961EAC9F27D4C71E2391904DD6AB27BECE5BD6C64C79B146C2D208CD63A4B74F8DAE638DBE2C8806BA107738A8DF5CFE214A4B73D03C91275FBA5728146CE5FEC01775B74481ADF86F4854D65F5DA4BB67F882A60CE0BCA0ACD157AA377F10B091AD0B568893039ECA33CDCB61BA8C9E32A87A2F5D8B7FD26734D2F096792352D70ADE9F4A51D8488BC57D32A638E0B14D6693F6776FFFB355FEDF652201FA70CB8DB34FB549490951A701E04AD49D671B74D089CAA8C0E5E833A21291D6978F918F25D5C769BDBE4BB72A84A1AFE6A0BBAD18D3EACC7B454AF408D4F1CCB23B9AE576FDAE2D1A68F43D275741DB19EEDC3B81B5E56964F5F8C3363 + +# "RFC2409/Oakley Group 1" +FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF + +# "RFC2409/Oakley Group 2" +FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF + +# "RFC3526/Oakley Group 5" +FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF + +# "RFC3526/Oakley Group 14" +FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF + +# "RFC3526/Oakley Group 15" +FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF + +# "RFC3526/Oakley Group 16" +FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF + +# "RFC5114/1024-bit DSA group with 160-bit prime order subgroup" +B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371 + +# "RFC5114/2048-bit DSA group with 224-bit prime order subgroup" +AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC2129037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708B3BF8A317091883681286130BC8985DB1602E714415D9330278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486DCDF93ACC44328387315D75E198C641A480CD86A1B9E587E8BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71CF9DE5384E71B81C0AC4DFFE0C10E64F + +# "RFC5114/2048-bit DSA group with 256-bit prime order subgroup" +87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597 + +# "weakdh.org/1024-bit MODP group with non-safe prime modulus" +D6C094AD57F5374F68D58C7B096872D945CEE1F82664E0594421E1D5E3C8E98BC3F0A6AF8F92F19E3FEF9337B99B9C93A055D55A96E425734005A68ED47040FDF00A55936EBA4B93F64CBA1A004E4513611C9B217438A703A2060C2038D0CFAAFFBBA48FB9DAC4B2450DC58CB0320A0317E2A31B44A02787C657FB0C0CBEC11D + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +C9BBF5F774A8297B0F97CDDA3A3468C7117B6BF799A13D9F1F5DAC487B2241FE95EFB13C2855DFD2F898B3F99188E24EDF326DD68C76CC85537283512D46F1953129C693364D8C71202EABB3EBC85C1DF53907FBD0B7EB490AD0BC99289686800C46AB04BF7CDD9AD425E6FB25592EB6258A0655D75E93B2671746AE349E721B + +"weakdh.org/1024-bit MODP group with safe prime modulus" +829FEBFCE3EE0434862D3364A62BDE7B65F0C74A3A53B555291414FCAE5E86D734B16DBDCC952B1C5EB443B154B3B46662E811E11D8BC73134018A5EA7B5B6A9720D84BC28B74822C5AF24C904E5BB5ADABF8FF2A5ED7B456688D6CAB82F8AF0188A456C3ED62D2FEACF6BD3FD47337D884DFA09F0A3D69675E35806E3AE9593 + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +92402435C3A12E44D3730D8E78CADFA78E2F5B51A956BFF4DB8E56523E9695E63E32506CFEB912F2A77D22E71BB54C8680893B82AD1BCF337F7F7796D3FB968181D9BA1F7034ABFB1F97B3104CF3203F663E81990B7E090F6C4C5EE1A0E57EC174D3E84AD9E72E6AC7DA6AEA12DF297C131854FBF21AC4E879C23BBC60B4F753 + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +A9A34811446C7B69A29FF9997C2181ECFAAAD139CCDE2455755D42F42E700AFD86779D548A7C07CA5DE4233261117D0A5773F2459C331AF1A1B08EF8360A14DE4046F27462DA36AA47D9FDE292B8815D598C3A9C546E7ED395D22EC39119F5B922CC41B30AF220FF47BDE1B88334AD2981DDC5ED923F11C3DDD3B22C949DC41B + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +CA6B85646DC217657605DACFE801FAD7598453834AF126C8CC765E0F81014F2493546AB7DDE5C677C32D5B0605B1BBFA4C5DBFA3253ADB33205B7D8C67DF98C4BCE81C7813F9FC2615F1C332F953AB39CE8B7FE7E3951FB73131407F4D5489B6B17C68759A2EAF8B195A8DE80A165E4EB7520774B167A00FA5629FDC5A9A25F3 + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +EB373E94AB618DF820D233ED93E3EBCB319BDAC20994C1DF003986A79FAFFF7654151CC9E064131492698B47496F5FDCFAF12892679D8BC31580D7D41CD83F81529C79513D58EC672E0E87FCD008C137E3E5861AB2D3A02F4D372CEE4F220FEB2C9039AC997664A7EBB754446AA69EB3E0EF3C60F91C26392B54EC35A970A7BB + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +80A68ADC5327E05CAAD07C4464B8ADEA908432AF9651B237F47A7A8BF84D568FDFDAFAB06621C0C428450F1C55F7D4A8ECE383F27D6055ADDF60C4B837DCC1E3B8374E379951792939FDC3BBB4285112C8B4A9F6FCE4DD53AA23F99E2647C394CE4D8BB82E773F41EB786CE84CD0C3DD4C31D755D1CF9E9B70C45EE28ECDABAB + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +C0EB5F3A4CB30A9FFE3786E84C03814169B520305AD49F54EFD8CAAC31A69B2973CC9F57B4B8F80D2C5FB68B3913B6172042D2E5BD53381A5E597696C9E97BD6488DB3395581320DDD4AF9CDE4A4EBE29118C68828E5B39289C267280B4FDC2510C288B2174D77EE0AAD9C1E17EA5ED37CF971B6B19A87118E529826591CA14B + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +8FC0E1E20574D6AB3C76DDEA64524C2076446B6798E5B6BD2614F9669A5061D699034DB4819780EC8EE28A4E66B5C4E0A634E47BF9C981A5EC4908EE1B83A410813165AC0AB6BDCFD3257188AC49399D541C16F2960F9D64B9C51EC085AD0BB4FE38901318F0CD6165D4B1B31C723953B83217F8B3EBF8708160E82D7911754B + +# "haproxy 1.5 builtin" +EC86F870A03316EC051A7359CD1F8BF829E4D2CF52DDC2248DB5389AFB5CA4E4B2DACE665074A6854D4B1D30B82BF310E9A72D0571E781DF8B59523B5F430B68F1DB07BE086B1B23EE4DCC9E0E43A01EDF438CECBEBE90B45154B92F7B64764E5DD42EAEC29EAE514359C7779C503C0EED73045FF14C762AD8F8CFFC3440D1B442618466423904F868B262D755ED1B747591E0C569C1315CDB7B442ECE84580D1E660CC8449EFD4008675DFBA7768F001187E993F97DC4BC745520D44A412F43421AC1F297174927376B2F887E1CA0A1899227D9565A71C156377E3A9D05E7EE5D8F8217BCE9C2933082F9F4C9AE49DBD054B4D9754DFA06B8D63841B71F77F3 + +# "postfix builtin" +B0FEB4CFD45507E7CC88590D1726C50CA54A92238178DA88AA4C1306BF5D2F9EBC96B851009D0C0D75ADFD3BB17E714F3F91541444B830251CEBDF729C4CF1890D683F948EA4FB768918B29116900199668C53814E273D99E75A7AAFD5ECE27EFAED0118C2782559065C39F6CD4954AFC1B1EA4AF953D0DF6DAFD493E7BAAE9B + +# "IronPort SMTPD builtin" +F8D5CCE87A3961B5F5CBC83440C51856E0E6FA6D5AB2831078C867621CA46CA87D7FA3B1AF75B8343C699374D36920F2E39A653DE8F0725AA6E2D2977537558CE27E784F4B549BEFB558927BA30C8BD81DACDCAE93027B5DCE1BC17670AF7DECE81149ABD7D632D9B80A6397CEBCC7A9619CCF38288EA3D523287743B04E6FB3 + + +## taken from https://github.com/cryptosense/diffie-hellman-groups/blob/master/gen/common.json +# to be continued + +# "Oakley 1 from RFC 2409" +1552518092300708935130918131258481755631334049434514313202351194902966239949102107258669453876591642442910007680288864229150803718918046342632727613031282983744380820890196288509170691316593175367469551763119843371637221007210577919 + +# "Oakley 2 from RFC 2409" +179769313486231590770839156793787453197860296048756011706444423684197180216158519368947833795864925541502180565485980503646440548199239100050792877003355816639229553136239076508735759914822574862575007425302077447712589550957937778424442426617334727629299387668709205606050270810842907692932019128194467627007 + +# "MODP from RFC 3526" +2410312426921032588552076022197566074856950548502459942654116941958108831682612228890093858261341614673227141477904012196503648957050582631942730706805009223062734745341073406696246014589361659774041027169249453200378729434170325843778659198143763193776859869524088940195577346119843545301547043747207749969763750084308926339295559968882457872412993810129130294592999947926365264059284647209730384947211681434464714438488520940127459844288859336526896320919633919 + +# "MODP from RFC 3526" +32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559 + +# "MODP from RFC 3526" +5809605995369958062791915965639201402176612226902900533702900882779736177890990861472094774477339581147373410185646378328043729800750470098210924487866935059164371588168047540943981644516632755067501626434556398193186628990071248660819361205119793693985433297036118232914410171876807536457391277857011849897410207519105333355801121109356897459426271845471397952675959440793493071628394122780510124618488232602464649876850458861245784240929258426287699705312584509625419513463605155428017165714465363094021609290561084025893662561222573202082865797821865270991145082200656978177192827024538990239969175546190770645685893438011714430426409338676314743571154537142031573004276428701433036381801705308659830751190352946025482059931306571004727362479688415574702596946457770284148435989129632853918392117997472632693078113129886487399347796982772784615865232621289656944284216824611318709764535152507354116344703769998514148343807 + +# "MODP from RFC 3526" +1044388881413152506679602719846529545831269060992135009022588756444338172022322690710444046669809783930111585737890362691860127079270495454517218673016928427459146001866885779762982229321192368303346235204368051010309155674155697460347176946394076535157284994895284821633700921811716738972451834979455897010306333468590751358365138782250372269117968985194322444535687415522007151638638141456178420621277822674995027990278673458629544391736919766299005511505446177668154446234882665961680796576903199116089347634947187778906528008004756692571666922964122566174582776707332452371001272163776841229318324903125740713574141005124561965913888899753461735347970011693256316751660678950830027510255804846105583465055446615090444309583050775808509297040039680057435342253926566240898195863631588888936364129920059308455669454034010391478238784189888594672336242763795138176353222845524644040094258962433613354036104643881925238489224010194193088911666165584229424668165441688927790460608264864204237717002054744337988941974661214699689706521543006262604535890998125752275942608772174376107314217749233048217904944409836238235772306749874396760463376480215133461333478395682746608242585133953883882226786118030184028136755970045385534758453247 + +# "MODP from RFC 3526" +33751521821438561184518523159967412330064897805741846548173890474429429901326672445203235101919165483964194359460994881062089387893762814044257438204432573941083014827006090258925875161018096327732335800595831915976014208822304007327848132734933297885803213675261564962603340457220776826322500058091310967253976619973988033663666385188155212656268079501726223369693427999804134467810120772356498596945532366527400517575471969335854905274504119509592366013711954148258884879224599915203456315881034776553083676995718335598586395591169999570824515035017543533352697525287753332500527176569576894926734950469293596134095086603716860086302051544539652689091299099784588919052383463057789440565460681441902442399956419060521629604697347879024654313800186078316526964529288062740879011035175920059192178561473199006205896719435014765345518490882366607110905303449152556221163232127426440691921134648766635695850239231304591744215610985029636895406718880766308249227315984267542266259489684372223916445411015900506239419267909716320331208988978180868987431623710347617992356201449023892203230133009421463914291201346063125219636964261683591541014344239275340735690997732222069758773963390876360546515755280517042160525487302898122311669799679447530453600399342697032714458549591285939453949034981248114322322367238645042515984447890788917823576330019151696568654314153058547592091366014550143819685170068343700104677609041166369760080933413605498962382077778845599834907475953430787446201384567328530675275792962354883770806900827183685718353469574731680520621944540947734619035177180057973022652571032196598229259194875709994709721793154158686515748507274224181316948797104601068212015232921691482496346854413698719750190601102705274481050543239815130686073601076304512284549218459846046082253596762433827419060089029417044871218316020923109988915707117567 + +# "MODP from RFC 3526" +1090748135619415929450294929359784500348155124953172211774101106966150168922785639028532473848836817769712164169076432969224698752674677662739994265785437233596157045970922338040698100507861033047312331823982435279475700199860971612732540528796554502867919746776983759391475987142521315878719577519148811830879919426939958487087540965716419167467499326156226529675209172277001377591248147563782880558861083327174154014975134893125116015776318890295960698011614157721282527539468816519319333337503114777192360412281721018955834377615480468479252748867320362385355596601795122806756217713579819870634321561907813255153703950795271232652404894983869492174481652303803498881366210508647263668376514131031102336837488999775744046733651827239395353540348414872854639719294694323450186884189822544540647226987292160693184734654941906936646576130260972193280317171696418971553954161446191759093719524951116705577362073481319296041201283516154269044389257727700289684119460283480452306204130024913879981135908026983868205969318167819680850998649694416907952712904962404937775789698917207356355227455066183815847669135530549755439819480321732925869069136146085326382334628745456398071603058051634209386708703306545903199608523824513729625136659128221100967735450519952404248198262813831097374261650380017277916975324134846574681307337017380830353680623216336949471306191686438249305686413380231046096450953594089375540285037292470929395114028305547452584962074309438151825437902976012891749355198678420603722034900311364893046495761404333938686140037848030916292543273684533640032637639100774502371542479302473698388692892420946478947733800387782741417786484770190108867879778991633218628640533982619322466154883011452291890252336487236086654396093853898628805813177559162076363154436494477507871294119841637867701722166609831201845484078070518041336869808398454625586921201308185638888082699408686536045192649569198110353659943111802300636106509865023943661829436426563007917282050894429388841748885398290707743052973605359277515749619730823773215894755121761467887865327707115573804264519206349215850195195364813387526811742474131549802130246506341207020335797706780705406945275438806265978516209706795702579244075380490231741030862614968783306207869687868108423639971983209077624758080499988275591392787267627182442892809646874228263172435642368588260139161962836121481966092745325488641054238839295138992979335446110090325230955276870524611359124918392740353154294858383359 + +# "MODP from RFC 5114" +124325339146889384540494091085456630009856882741872806181731279018491820800119460022367403769795008250021191767583423221479185609066059226301250167164084041279837566626881119772675984258163062926954046545485368458404445166682380071370274810671501916789361956272226105723317679562001235501455748016154805420913 + +# "MODP from RFC 5114" +21847359589888208475506724917162265063571401985325370367631361781114029653025956815157605328190411141044160689815741319381196532979871500038979862309158738250945118554961626824152307536605872616502884288878062467052777605227846709781850614792748458838951342204812601838112937805371782600380106020522884406452823818824455683982042882928183431194593189171431066371138510252979648513553078762584596147427456837289623008879364829477705183636149304120998948654278133874026711188494311770883514889363351380064520413459602696141353949407971810071848354127868725934057811052285511726070951954828625761984797831079801857828431 + +# "MODP from RFC 5114" +17125458317614137930196041979257577826408832324037508573393292981642667139747621778802438775238728592968344613589379932348475613503476932163166973813218698343816463289144185362912602522540494983090531497232965829536524507269848825658311420299335922295709743267508322525966773950394919257576842038771632742044142471053509850123605883815857162666917775193496157372656195558305727009891276006514000409365877218171388319923896309377791762590614311849642961380224851940460421710449368927252974870395873936387909672274883295377481008150475878590270591798350563488168080923804611822387520198054002990623911454389104774092183 + +# "FFDHE group from RFC 7919" +32317006071311007300153513477825163362488057133489075174588434139269806834136210002792056362640164685458556357935330816928829023080573472625273554742461245741026202527916572972862706300325263428213145766931414223654220941111348629991657478268034230553086349050635557712219187890332729569696129743856241741236237225197346402691855797767976823014625397933058015226858730761197532436467475855460715043896844940366130497697812854295958659597567051283852132784468522925504568272879113720098931873959143374175837826000278034973198552060607533234122603254684088120031105907484281003994966956119696956248629032338072839127039 + +# "FFDHE group from RFC 7919" +5809605995369958062758586654274580047791722104970656507438869740087793294939022179753100900150316602414836960597893531254315756065700170507943025794723871619068282822579148207659984331724286057133800207014820356957933334364535176201393094406964280368146360322417397201921556656310696298417414318434929392806928868314831784332237038568260988712237196665742900353512788403877776568945491183287529096888884348887176901995757588549340219807606149955056871781046117195453427070254533858964729101754281121787330325506574928503501334937579191349178901801866451262831560570379780282604068262795024384318599710948857446185134652829941527736472860172354516733867877780829051346167153594329592339252295871976889069885964128038593002336846153522149026229984394781638501125312676451837144945451331832522946684620954184360294871798125320434686136230055213248587935623124338652624786221871129902570119964134282018641257113252046271726747647 + +# "FFDHE group from RFC 7919" +1044388881413152506673611132423542708364181673367771525125030890756881099188024532056304793061869328458723091803972939229793654985168401497491717574483844225116618212565649899896238061528255690984013755361148305106047581812557457571303413897964307070369153233034916545609049161117676542252417034306148432734874401682098205055813065377495410934435776008569464677021023433005437163880753068613673525551966829473007537177831003494630326494021352410947409155250518131329542947165352164089215019548909074312164647627938366550236314760864116934087960021077839688388383033906117940935023026686459274599124189299486771919466921436930468113859003854695674493896608503326776616230412252016237753188005160515672431703429026925450722225213972891936880551722374424500117253400391608019951133386097176734162660461073160502839490488652900367939577292447038637156268014222959401811270825513710710113193757653852931049810187522670964988718456427706279024201400130351029277257873323362974483425793829163819060563081096261611614988801585554385004830748976181157545121697905898543562330970182151097394600286811868072516047394404389555706298311761588649133904051123770516767707951778179308436153604841663369568605395358405635911568855382987714763476172799 + +# "FFDHE group from RFC 7919" +33751521821438561184324892992841956031256524096764762523080427484131368183681238652286303439277919364419605375975741556865385545908845926426890806171934808386673338677817446992026011784349026750519375730205067498701350657030856602039247991829540145540001367697563530312238373189195859410680196740818496273776863982316239487439125584973486191474973070378586678136324790578680454630958344992260559731819239256040561423139407134895441043521777796400880951101664061960549417775619248830729218197463598192224062477224088661984618875141239361375810191700348746470517603586330742337739315086785758610522626080327305070861763732997096646270232538049631764978124370714033713690749348727603833565215088374348155839869467418301934486261774031333194202002514049598635757051715292153270068806927857370077400854342621469193035173582620808395011965872285119963665326566931152118419683195410230531880091058340135241442529412915698052541447285219904877547903853970539536057866360165883117245413187530187706879654021604384751733362734886086447963479243086334556742008371133320333144330529868075901065270101499033142677098456216621473599132476055885593228992805674421717912030137492923124370487889214032208165952268509981501451774970889626262931401169981636584425302941104561318586295950568633223864381392065855785614286866466034588630668284169362643876828113430270351563540045399616908093185001539414731258530233312567034617287652871707877648601789117465138822759448972467259851264567429611605233655993068745892528795005477239451835762239158148450946495583269774730192968123453831376884299400027264972551783838651516361577307080496493669697500674115993933560984134638146861375527138211765789496434131148421504162050232089029807657513443213647811723915569891007483031985943458980395910188354328838067537352640645494922975415613895710751245784814785127169311178294820863 + +# "FFDHE group from RFC 7919" +1090748135619415929444037382073202164125305063117061359021210911270577744302484095783585256262132857867507012151327745319420949480631077659230943007731372290338916318467056551341312388724237204552630979526938946243971958249567992270660707645223444998212375042421215776901548713954608377879903140801084739259304885738884241557789963639848414142435545413461220375392883746746009571997041033445022502762816331857033727315823681421531580986559568582495054304419334754793864359536511580585755680437972489876200744058648895832633694632513670176667389094435272527511943458451278617893700596377728765952665861962906447628133961178002643746220845591569312550242539556477924846824431386227398784372946565741502410953510925086230339755945668395462836859386976915262545264219099083866412323338929445556193690276085130255735707017517324908584556020047122304601806052013210478673966121765822384984613134062610932880821764360557629800471942620120350089258471142266672486905811824890197561222168259425622075380074970894661940191022351313937794403179128925897399112543950028771599485900567258712506491423242565563135524281249329012935005778031068703683453260896098798641811119050812310043452672866472626886632040451127891259822859833579017734578653167790168028670602474730129723339966367629299069464612922206043242915619930604287973659968151168649532362252217391606094542229202850891990149423286722373933582772946978151293864418092658361871788530836011433246848517279350728403540496593224145424561966649653985963026020941223187837459880455379494869707430746485961836217272806165182791750397289355418934743450060932235238237908010122017218143239665855653767803345566744660974127130587188591627469364051467546830550982678041483517603551345004201416166657317979133177076850863915723452487089990921274837044452675718747451622274394568025709298240157360143554038242669443266557467589294627069491899039816156659993760960331555864960579941903669595533661959937683218286259759942024512967175841717416769943853374953316002333533954475281180536503757029544656828281916590129722443603212328905281386443054134068074845098476931062612287259260077268525729384552957078890543508903050684066466350832645258291471581992414681774952272964607180615323323707230823981670673369901279153005955624089037761236230721391005676907275360233030103877306374767486038871773571307196997482447151534288054433129088702568193019402125710114040359224543481208871491986232520827933323475832217514514887471827867630829567 + +# "OpenSSL" +11435638110073884015312138951374632602058080675070521707579703088370446597672067452229024566834732449017970455481029703480957707976441965258194321262569523 + +# "Apache httpd" +11141973616799305182672125953821539621789863864652082189484418383755797726500394212227314338509410225240621127512913527972129628050063918116985983184044619 + +# "Apache httpd" +161924636724157236995539194603424135829045460791094305399572880130740597902511283656435607474782334562452295847429354234894102736530695296652601242468041123426186888474417097353027907965636446587415802158180476224678572126072378632347236490658815309740591429281572158171557380347843452583426729104575168890987 + +# "Apache httpd" +8372421755538377327377912526045445423027732035562313241965800453667849685158691589507936013805295187219621475007123900107532269487803598942841993804845107 + +# "Apache httpd" +150621238998402554141426358892807528070450929584024050594746304264729573805267992507071188730865440785012329520820489313721494359461887733932969896388657569112847289565683617995554301683431835378300250205597326665273328905597509521195196490490065048848345935446963329447852572726043146337361398005701852368563 + +# "Nginx" +131832052042219009527839525934268128127355300704472845128573174908898587826481581974548040446189688518070214483643209695723925616113897243950922364670371766056432630785982773485713108424273657672047098239473476944390258716112687012012440120129627988472009949456811428528912427249964927042573604085259319733147 + +# "SKIP" +171718397966129586011229151993178480901904202533705695869569760169920539808075437788747086722975900425740754301098468647941395164593810074170462799608062493021989285837416815548721035874378548121236050948528229416139585571568998066586304075565145536350296006867635076744949977849997684222020336013226588207303 + +# "SKIP" +31087337795061487877547416545715496334920954980132212151448781444321393445568157959166911302972918628838917381555939620290244963511997037011253946065678925033455872043721454426215650798450188675325621498188688302603627388365642425546473761584899398546726625631228589029183157123265299738241899897560139599077166257814263354432724020387267456594044458497157226037520021564951601668256091905149808373739011153824316842260356584928931097012930709279713696588076097146536216639697002502410139891180002231258705541413293860269631209702305813614701588402302998104362562812340366960005570331931340105075488237470969553357627 + +# "SUN JDK" +13232376895198612407547930718267435757728527029623408872245156039757713029036368719146452186041204237350521785240337048752071462798273003935646236777459223 + +# "SUN JDK" +1418488780399624169246918906980830188668962659968489177172519612007411971965075884911751185624649475197807409457369163882960326663412481439463507475025544888587052733646843233033458377686354235239579046252542291754237282749312023983 + +# "SUN JDK" +178011905478542266528237562450159990145232156369120674273274450314442865788737020770612695252123463079567156784778466449970650770920727857050009668388144034129745221171818506047231150039301079959358067395348717066319802262019714966524135060945913707594956514672855690606794135837542707371727429551343320695239 + +# "Postfix" +11351928295969362153680318143899638392634652084406809180721126850912534429957010348519890331306577360308702381391458869083885638571113632680200730760851979 + +# "Postfix" +24131293777886374118584606661678552444065113984688942136778980647818164970852105655088429124396761599838827087514740364394273667387502830998781367142799184218851559149661801594513163362372771874046737233840092368303597660206162593808771774336440959680029703901794663844140996661787853155797815168383327259460283094609626756009315263214901338027934420086863770577133358328638467072634923150631754665130537846660356778764277584029327763941442223552847441902193518153870526066148265594588320847125072665688996554047265314983737297427106179945662121632266549409922372350824775582437869586864262636578117679890847409111979 + +# "Postfix" +7135787487680160723158987360172009509857780973879356519050893028700610616910042141909504379139750530669840288414588708459507347709411497939019689914055259 + +# "Postfix" +124290078192881725888826880475608268121546479080319401588411202759306021711058769574616590974367222833180545066528602465043919413058514740355249599358163921882995239255028847197529491772541340375114213691923735762979921709723984230280341119838110698845565638766769901880452341248731603339034272624514428481179 + +# "Postfix" +10096187981066053559335535449169282457945760362469786309557937686443731234028465097513776908358954978429010128113292083701478593065474911189952431940546219 + +# "Postfix" +1089090311023821486807062646667755441663974766415146023889746307964280220954453097088413985218587552379044355794097665552117500934098507055783139454648372005227264905074027069250089786740659823130740976279817510828079511169071325147 + +# "Postfix" +136123388004568009176875286135055183919622133760505398783397401047902962378621318101100481790979982216519828483232429970364693220922572981049575270176219908104060081734736799288400844770528117178481382626351711182233806272597979705666996232841536687325828096814721669135261423885453987983624180097457782693179 + +# "Postfix" +2056362021987869040866222775971525526713848817411256130367970754396969557869817702606903423615283059303930616438676624104640204217164473099856199216305279508718747202276171819868432314839088974911801002129018672739575945202076259230302103370863451826447174518117143102638489276724376611076549917224491477706108610356540170718925518289818980666063927549928069325768537343367153162067020241995073818799850549182710199952635278668959071457969808520304484680273215899 + +# "Postfix" +26371476087150474532132008655311203525984191621650037797335673054271351883338792851526864908736384515015553905714370466910888328281569556512680757420248619460502802406103896590120987564792497073052858573915284877543392830972701922295410164673203260676695786443597509581751209037220443274164352656996468549138046641990095766583932817878707309357841837078365072329679282667717608853872093084680474764076406402800742626159266353107911079809322117978690117000544919386308980746878875294902444713440174790300512221828280260208844137639082842338734111456679990753248043046594738798915627967835625360741492443851601099267219 + +# "Postfix" +13337623048342799034827489986910318393008849763036733997149839779963204489425757309012715340523200875542318060972273326641217824631730700039857742855624939 + +# "Postfix" +1533772406382956570152763108431991954831079405833258610827703555135606586893527939272614759361191561110646045114047738154033517920758341678370617073220477513898951427441733234099780163358327483548965595558112565701277519466897981283 + +# "Postfix" +144637424961850425159905784027136014061880826531818983352585061296526368581179214296922065913823633724228503264147831887830254308079169948903074953931411083056118836353233843818642834810107342452429640402033606357719495510563519638658174142659182338760323238086948118168424439691568418572594944219477298153263 + +# "Postfix" +2042713559934185643384327549527952458750622217167335751028047396411788957162246741725543190665668416817031839560334887966601364296103416314875607373600606218726870529318758852284243260138607080937306070901820694908266357001271027028958097194186248177918896517910126113641694455442417769493899505072159312860025674661873706392362014784672110060931972136138821276444318148803052032775491121430546126966329795445327961129787860725363402062777363244414680356473486443 + +# "Postfix" +9759154167025958083571250365552992993534466195928785797208140837064455011559008409756152457212745575772062478546361342515389863167056447063023865399211283 + +# "Postfix" +1364948145886991617895978559358903167966290416143667578394285325644381185372799885861597343368522645272011717362014967121205629440617659315582294484305490057030886926126158500711976814177825019653800069743928883494887162161622087307 + +# "Postfix" +170509805985945428967563804421085700024309580001072283516862390953398284789689265180987459434776023075205610950717188546433293071493512609789324612714292386941858855686900608567108340703947439969571374674464812699728499679347745006429584325043673764959755753323095048465275743217839659384932866032300078439107 + +# "Postfix" +1399756687522921964208442265587277224590999291970020878117413585753624587517145241012458149142229516760446050107835226455178997986671341265900784797102850306784040754165031733011704700434845054226208232294383130796490713540743213929432845289812563992089777728134866354306530112982376728691670345857960914971155568106763073589329112068058914650276150476331492500275579709331992458078664551226290003097390552576077474939787303074332596329599148724157114197518536243 + +# "Postfix" +30665078773665433984679390022488424719778975164146202083131251833892119277576018817470613424046186801389172270027910937409609108491794879785967303818331364169223881734218065480981193865887637105068086059746777211418404547623912175779761293496184572560489062892861925196800372347853683709369252088792223794330075784696968081981902086985383387978231015947493852904756936918233163868719135240372874496529063971007348736606704972376420631489422417247291206292728386525387923483221986802035152273686134933880580692993177449671583228524148903686102484113995181746319098939406274514609994062637696036007964340964533117834243 + +# "ProFTPD" +132996212497555757714839577520009599982229563766990814349170419213831793150518344581415624091585295362723791618044438047032948658522696342563919889163541989736011703719977966038136834855002285771085403405914099274079071528415842277349009763640550881468502896685974195502523576590837887774944220227692918505803 + +# "ProFTPD" +18858581929742317527029478184638854842724462225720836179117188808917671531240871347611118225573584796605541571727033806983637845587663011540549398931093362137864722376547296516821251924303406852009430817109406449016925627536728768913299637717356641023929230337606449236348118535296673960534958260471470936207746899744229699227402402594684686990419598035403972292138232693389441133450887303721307090039985977409326551114653393248153491003945999649497125303737739578242143102865505268997450435612946830940154792978896702775943651552752271560923011637181201283076815030600233147165141152749108754455161316496472774445347 + +# "ProFTPD" +1690599963976092471219037714997293855906302310875281420968063614328589925828056077695246555017889987035500367344808224338477443561578625431475483707580988822589648483623980475499118810285212591091135830604537640714865512873460169015344343192483199148216608008625051676959634598080985210766854387762630074527385892020512178705520293062481006218780660207277235008828769064469617081682669959711930850913832434916213132582786972860232373841378773014990861911716877783 + +# "ProFTPD" +104550704091518462875794517239932803228795640080961293447673045687504879049730788416000819314820105958147984905210586942301309304289196753528645175163277955936437052460041407055113432460397792985373298283729666329986343854287860035912543769966125530991956674119731252342212248133977944642911919848432245755403 + +# "ProFTPD" +123120551618399898699275185207010546211742537321803360244900958280768207448346752310214792790377162714025492878116518422402416452790435000574976635965888758275326899087155471405218243739016862932542478973649475145841047404561698683215439607643411122685696959117693582083223293718196252180492595190774509386403 + +# "ProFTPD" +2072532323310501692602322388268833396123289164730332267469573021914276523184450666618978234290563818735721031645764083012063719326736169342391072129575572421888510449733093943436432405362027186491718086792358334086233189779026493592066693945045050284042918422370589842816833223211080055541474219925354652062740315569261166622364419630766422792649520961544329870455119648896215813081694106880913531338140089714955197662175239587929209024190072822404107630757857067 + +# "ProFTPD" +104853848541625611565027567937000048853298267079325188824720224546354701006518045430304636072499713382704797349764784338122087988075844159399738334488490583340241104498736369527027446023860951495356349935003007271644770819847539446840368531546048297372864850341715016643407939469252235645642453257754265084027 + +# "ProFTPD" +2147497872306889053504904888759358275602695222009945054108052972067120354595691834400135034995896341236547003124573230676535767835278508796798134916404709542900609890895920026678765629400534329817345465508784448555078707537307882450019948089258345775683170910399405732489472619533026653306913904331961818133065102121154500321487478024465642145780362841606890007568595945037955647568957020977173073532849222461327972617348846814678566932700323274394446127558666907 + +# "ProFTPD" +111213710907361843217505524310927976465342092915425056395273336147179504107691110941903277407929302520103543347451222500858487011084274592106195452422261247548928103551991676417076675303218099117588229418345583422831960086789112908165814516444053324246610424153249337581410600100580389709994157679621299828623 + +# "ProFTPD" +30654731759923165109068549394646174606854727560270885171118455001834361039508262661339420809312767964610651844011506730705488517327796540861106897019325049871148405402236945049178642616972180268973325675055028097791829107978290394470119050766353933419488529294688328656740595673735495568398070771353558240253633506948715867154144045422013754218964484403591502950454747491574863086439822125629822452768189179177186539594550005550512898625828856416703741709780468562505839527127374406418271774990679091276656962041750605852553264770538287381580788100834107772346595084204530201157938144045756467942963206230969457893123 + +# "ProFTPD" +560453074889691084801508706747087803540613692838919659785572557415210631700643171604008221497013769908348013955874542884136354619137507720741899179238077988760004797077407812589900838688215076167450301205296447158745926229854739807818394106988261586396065090531475950636513903415267816803946418255520553693928436321340106430173695312279494235116237531042948629210283927454523812977173250155350409330845643548406174146370597398556675488785763553330369703618129430493080622359701457094947003591314994652685327155023420916183839907422844528253242557377002612852746197024635489493049498059762863383013077143319094717952017020036623946911388362291925754554145419902368333149508480700775304575863975993149105461894793388252798498052849927907736752612092770718880461605439373769712890534662083206525052790244797011392130835414585618712008750755694714606901923862380817372512163207489817525845729942023195028797148511734227873744682215926584339267728914054388398633829371406140091339600806643048726940156953947581944854744710145129208742582630965096415508072574658541836819320370543388222808743323853519111716840418501630881509493931126128051519749175014728034045603456558927435106155725323305574697528346609104862763919932824531184872477603 + +# "ProFTPD" +150247087203561355396392008605529599655265834016635685469479449170859963959446007961115768712036600163521320731233612979799726616542001443845031140881081476904672802767897302854393730990568959543431711914873544079199847213133315505824087329022680038499751501391472888045916637294419666350825877503188897147459 + +# "ProFTPD" +18755180141969143456719975490837299591661486864459177699347875191706943914337986945386993995828353706677617962649773753118865573252060087883492944819935042481061008351675891635789201271724722361772070519804796837601882165443561099647909860614358193001345124267045197407694355612018622267446950565235314913858029731861206146245083838508844063168098555243333600136059862005176947895926651361888272982357941329686992778843183857144326689862707154576500901134210456017229817418566122925198531060399072996158681589950738698582455848231588244562186580518380274577297965754367635749015721785225113626288303327758476594353492369673848915934227183776466162783119384190746961294042730022282533429474416217028782256985135499635186282818066176169066342864593516738317060183918641512104154959421700551502662531671060038685015232875757774746837013433410576301022052765766846360448260461798693323354583565275772757616487405118046473468040823807511862525841580430993366421786369713630767092491474732889477248883458413461697623532468385915560450742063076541098142596017865409212782228095291119074456755890648431348998467982439387249601358951311235550685074753771953235731292210445082899805267502606627215954297070962074179567656154781185995223610364040992233060243700690008404416268632104351187679644467896703035503011582445888585285643676624860824735219703168909443935692401339337973046031557855017438946499678302281454753221394836333932887051009032097287981799112327592659498982018134507815905529545600073217344336226176431386420504173713460602953964086767062800509341512637491432576105574511855949772755697886081233241895351608225518868884105051920163797783211704251614835795783619509187811273307721738804469716604103147736420435819693891673679549229810732077298529434732256753519128140787901554575275042084335576301463248436034910144072894694989973553779093182267 + +# "ProFTPD" +932614255716527426954194994893899443909587134717378000432839868236070873898603890199268954946230437836347598137289981490576265408987539907417814723830713466576148733233948875588872099899259973963876962911687774757252586321413731977669018933516110752356399918199969341105291513921295107439970501327003341880045051040607453969130527403651621523642867493175187109244410649447543051923977286351228641391584836232388340490928501453737056493642959144891566665266741989939395777161562837874922032904822211886432052992526410005023212811670921327701168514850842580610390961290804165151896351027698919616772111286176110774619757231843037570261318458683119146718530026599865420373898076199297113860513124130129642439162193625573382190306693208066775159336188992433884373423283888634990227229613290062353442882883814897613354162938799905014787766831590510683978574804178530566885876139182208112335475740743645358444335923578926581553787899507658135759969179665698240446604058961836540194721926903451607542473634061286487416075337212225270050252982709979003118673510823200519580882640921942656114863134103393093830299287983604073902542901481419517401448876432673164347319122212645087187893760841941747029826837455871820207021713457766359649664872755306267250016087958888262104061954114160281469417045032466897125681180954407864004854588273392554731639697744811495996158775565749253746509502712462630592967709761458213810401561164084981049795535139007859077837868799585937381155086342987588522510916597567815798713371610392396558783587268291276315638899899271483796418864808847875941402509378066344818876245109902804629626172034939807792153692477664189232944054519301986365498402204268869738103542360867827692774295351629924678870083278850942327036492706939882094521489455174654743338377916502241034245292826876438640977079089793026036061471920052264377503480373876982968241791339245438947719115558656378512512497926881726706471637308636797054646492009814335204611503870814749526336662640726950102818501582045460849840054285207453216588715750257633261109807491738295865709442594697074958538342316716407046367490887001556105415594262664900743919039268744236208927920962742626010051103113451721549101718874466476463653295775409095876118838803444475368968314681435270565439725470847559140534126935810393547990516635875286265092731940469309826898122583490810764696585155594623850610509624688744894442844171181116789538336468889633772702399667673046560254172554006933134177498414986043 + +# "ProFTPD" +128460946572822262057359109306605120772451327533031647046625697221005732816665725901582946504212374736582818589836761178529999012485342871381674433934353393937303106712438735820534568896236420093178574902954502039513652666078431761586990279191008772869049831986918279797303432637267752244583339163523262623643 + +# "ProFTPD" +144925986429746329552319820211520001198989689176458552347438337389405507299463218365770747208357804009826749164370407427351276485954367950795093335821830458863503379180661384347840601756810647040055797609071953593697579555534066046571617409999432650177627552951650427754499891734160186052184139722486900923483 + +# "ProFTPD" +115162289007948959755657135233438729113808855787722937014935613706821575983337028768883681648388956686229161829703909111979084624504403672089018965372485741289747502371975937088906812611362368895727043787370958107098559031733347943729595606679849892712753349171734318745015574338866049075316732439658885274307 + +# "ProFTPD" +136796884348914309433608566178313687173477692302500107653566211211886143478606291610252339969266161044433128956125387787447345706509140162356735699069609133141538999649842144594045984234748008239998576251245899854136813090217059279013819988558531082979779602360431032271817804377771999740652865493583728547303 + +# "ProFTPD" +167751911251691477400879168696973893472387251048307155134997654386932267855467967675338388425759898758981392239026462776070750197535524070674716116167771442673416216658566234928237166647224963890836829465768360527937853986670204218960020207654931004080097826367749677059265522971537599345586589563008771305059 + +# "ProFTPD" +90164112263583338872045552783608529087937979270683138336948143992111523095218561519057070103401534340240697917506462801522299075514460931473642651447181996848483449888359288699250956320806573454874473973166568685155864072031363366921611564598072165832915957792883701137348264610414343290967731930063824725523 + +# "ProFTPD" +1442082006420025285159048195407350832162451354970727441133114815200914015675297262845335883189790640384931267049070886793124058848180908982173726908054069855043135110045340492943413515577525797209781974671102061281077459318689101368052740455819513045346254302071645059475553268741739489000477622236056274600429885650766582188185564690881741381462043125996673253248961545216598867257791307298215427433001483949235232717793476313459024860432728272050874931213595543 + +# "ProFTPD" +1585267470767244273044107663411169303444883303191939904174462520657404014028566831965120807716340792526253441221740134643826007654998109460881572295636122928199853275034486996345453512356656712709629564297195683210604077436291604158194789653214040565692878135040130963708681515701288131697612156474638618573223280842292723454482563231109090559440909013349743163959067476699032060125379522318966848788470719660815660412055027428122460054977514444278077846789140699 + +# "ProFTPD" +2027766136735054769692379678403255418818352577167303861335714333049379030090903093887869111474427579026561918086896224997168323675945249165494863186546471863929461941407265046037911955365720627362818156592478752178915959040090408810560235675280619805603404439626888305039177460099695421975520079420001810213018995340062647953760877418185168989345014659622446222339712804272314984374647918446112020640013288816174836923301139404463463159658546593644846797623482923 + +# "ProFTPD" +29484431161230878152548870180958612754250230197705809571290478589909187981720717685327735273387416511274057781294076748771444807842553242819102107757103675878102175387855561386503916507221692084302102359372588227910590771528112112856108416996288552081116686364356381435943745142719402860898585982794136162970587185956742225497736703577210839049706015718648500509085628043135139402801209501498241421336809228371150021215528408022319773340435671934310371912646075629079601730607295032571519366354063983890572309223314476915221032441338898377696388617564377362158157334188156699167381895735324335732582041667913252512339 + +# "ProFTPD" +20688119750554625784709846317430718604169888731173941060581442021098396942101427300358256348908553454806288636971267059394068813630582665414307851229838617027065211823085367080874124091537030423091584189698731707608557359950179235778276430021081065695196384877883587752768974269274074180903734141862488218377743758988416168389576813181864016049843544101343494860617717109149721309615800057724024705772317174615817205727113392329227090895224468437228745291852197014264433563112388673140491448319770113906687867727988355155701700335344209966921434310712825277548504570050704170163646175008580262305320441541340196602703 + +# "ProFTPD" +645868159978225073498704495697101773837481732083889030828697397430998185294944185818778800364926531087610270569949609446772452302904635644201670284146523758813217144725041150244115308384750705236253076075188453436625954610345035236534446855967744287431950156190789571091011854278700670531536912583922257645541317940119683111443923751620097011653189398599735703771999227032202963009069882926539423644450214016849434013829538599255036114761442172565277135223452624054477098036115982499671808162028050955668311207489457471010358794390103880425866128957522089961396308079232621894437169401162215285543789377719164063329046592626125976477479709124174318014574525250156016654997445159564178612366124714025569006884547117369368843212678931012687323779005827189754176310749455258878214164398218410163448740275793790113640555375589552530143644409903650344879129909378258261046399655584779042320658036298011378163736663869520949776271215514718102599236666372363567947974597269076589991846941327440252517269575438041639963143249745243796698950602352896520319455865717885980269548846149368902316645841537870674040234260941295377801835362656637366134214004824734706415754513555226769625405638314662659282918991789098323957007561825608356119964603 + +# "ProFTPD" +31299473534312262776425585492872330648898007475573747686511734533328843377054251000045337408640658643264777560550523652263716601967176021713029220618273321087807676031915223187879494755339030407780244487639956841690467129259284576162376239566152314068303021299461898619317640459488786021015123334339921211897846553287404450314470911079848329350347046577029639345466054095814382010516205267740099541235363694198715777796169544664810154881122665461185273937211724586450592366925966393024278919419574283529710926728803238795528416569360987351800921729831369276960005974548939066127119765083306460492060736118246566151755503561706165861572368561978504076098847660139156840111982846401560123448591728973128192259759580278807734868856595412056429035280718359847430311787278134413193695716868295672987371620068042879459593130554382131322339411378217673319273009027571639567626114985119515200759689903758838061767312610782792700237194736839164466309921101135672054215046819635912790752355357249804715909081903201733166554922770438583955901743268012067299672347629249982918408962970797147947027855406862179415455385306004066906739523024233008933511709923873662404228654082360291780827241784990030817026055762510356711196368838367264247823150023167545981544406834091224811427570626426272131990685874614188233431450822290214430703253555583186494613174252440684800577816154030657730208536882045974575095463981743799188804168788441642058964538514209775797824451158993176322530092928544443396922088920205925062091318673906840961166987519290583959067005736044543309783511553338707364181695819720702592991495668337910517783701695066142396936980930636856963977831213837145011721411970160808448991469329389678849355939240258600705492169500867910979393652221370465448972399953433155089590971657181833473583765013644815832101086309219349468785600901303847019864807765787 + +# "ProFTPD" +842583000993045072637278642109901152103261923931236175788452043395835931872848482669580216429166310471893963002813982523507744183298035638380633699708788872007339195053363676210543188458982814648244285781891977789350854145845098767617917105439116573111107035713188720795327868690656824703579200074379067793808150376553099987803804062916278558688049193255223197184566162760070112846375799470594721161807479862158946955386596628536212815471482014247214513855881948470070791860002882588595556426782479616904272003587260891105308747001427205143410668530481850441975443068998762424989279375170481022004413516522026179757627369105917089325647184882951700083963497493525907573983062565422732475779643483560757033174230275171854369260515982564284558350426664891192930108154986087328112229293571621203441594349831442705426364202644536996077010112617051367371064084652438935604841234964912659138743739041431129200444928047130102954349346924659898296062267241077089892252283481159087533143061715075886314960787135245606388142954893159629656874505520343164833970456391996719250239756800849389727710302745421395697831477996940551839957110177892706519603094970138252930404570091890868494473034640779001880720250621626160122361360957600205875229974984765052104576962073906145469829806988741037404682346915918868247985475386777043652184076056075266432579619819843583483912192964862050178460166612303892771730993644094803736153930194451391094174838154400870059520143467898002852746911676266052857342128737513327388606257353970560411505075314710468391209342555665824899345489319400327140237283631183721278412481250255675770072765717605270444344602304767192635834999918745562496880294620898158754640701488018939456852939480684562565907219397080802741584232790265448896765357000388625159482028737161115217778260089059925769844896898457401102148237004351214279658006655945162471509279769621477001618734509392661225025427494080610698768725431986210060156537977812536098473372555128858118524663410057866784971094191896608754164811842347647862656062193237071472596009345104467720936174369502112957735120605230796536550526073320107058503539363665491662843858007004414547619637692127649556924570381450258194999012433531463917738796372800143851458398329058266603497557872154278268111650749903192875364273234576142545565560132387939493677439588722552015918122167805855557322418557066911853301356571738165573273023707816337475166068640316082202616532954193827365634369494484973753516615125445659 + +# "LibTomCrypt" +101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039 + +# "LibTomCrypt" +736335108039604595805923406147184530889923370574768772191969612422073040099331944991573923112581267542507986451953227192970402893063850485730703075899286013451337291468249027691733891486704001513279827771740183629161065194874727962517148100775228363421083691764065477590823919364012917984605619526140821798437127 + +# "LibTomCrypt" +5328861283668172329945723047610411795771014270600552860323385523406647326552760472582266594166949982639319866344591875989188385919141614032967632182106788230617154308807280817035869875026730777842155223320417183340387162699544821179884800708832389269366962629279314344211669291534466869589107113928150426545698929768007946765669598970231274510785562045304927693165937003804520022122096407 + +# "LibTomCrypt" +38564998830736521417281865696453025806593491967131023221754800625044118265468851210705360385717536794615180260494208076605798671660719333199513807806252394423283413430106003596332513246682903994829528690198205120921557533726473585751382193953592127439965050261476810842071573684505878854588706623484573925925903505747545471088867712185004135201289273405614415899438276535626346098904241020877974002916168099951885406379295536200413493190419727789712076165162175783 + +# "LibTomCrypt" +279095111627852376407822673918065072905887935345660252615989519488029661278604994789701101367875859521849524793382568057369148405837577299984720398976429790087982805274893437406788716103454867635208144157749912668657006085226160261808841484862703257771979713923863820038729637520989894984676774385364934677289947762340313157123529922421738738162392233756507666339799675257002539356619747080176786496732679854783185583233878234270370065954615221443190595445898747930123678952192875629172092437548194134594886873249778512829119416327678197159 + +# "LibTomCrypt" +542189391331696172661670440619180536749994166415993334151601745392193484590296600979602378676624808129613777993466242203025054573692562689251250471628358318743978285860720148446448885701001277560572526947619392551574490839286458454994488665744991822837769918095117129546414124448777033941223565831420390846864429504774477949153794689948747680362212954278693335653935890352619041936727463717926744868338358149568368643403037768649616778526013610493696186055899318268339432671541328195724261329606699831016666359440874843103020666106568222401047720269951530296879490444224546654729111504346660859907296364097126834834235287147 + +# "LibTomCrypt" +1487259134814709264092032648525971038895865645148901180585340454985524155135260217788758027400478312256339496385275012465661575576202252063145698732079880294664220579764848767704076761853197216563262660046602703973050798218246170835962005598561669706844469447435461092542265792444947706769615695252256130901271870341005768912974433684521436211263358097522726462083917939091760026658925757076733484173202927141441492573799914240222628795405623953109131594523623353044898339481494120112723445689647986475279242446083151413667587008191682564376412347964146113898565886683139407005941383669325997475076910488086663256335689181157957571445067490187939553165903773554290260531009121879044170766615232300936675369451260747671432073394867530820527479172464106442450727640226503746586340279816318821395210726268291535648506190714616083163403189943334431056876038286530365757187367147446004855912033137386225053275419626102417236133948503 + +# "LibTomCrypt" +1095121115716677802856811290392395128588168592409109494900178008967955253005183831872715423151551999734857184538199864469605657805519106717529655044054833197687459782636297255219742994736751541815269727940751860670268774903340296040006114013971309257028332849679096824800250742691718610670812374272414086863715763724622797509437062518082383056050144624962776302147890521249477060215148275163688301275847155316042279405557632639366066847442861422164832655874655824221577849928863023018366835675399949740429332468186340518172487073360822220449055340582568461568645259954873303616953776393853174845132081121976327462740354930744487429617202585015510744298530101547706821590188733515880733527449780963163909830077616357506845523215289297624086914545378511082534229620116563260168494523906566709418166011112754529766183554579321224940951177394088465596712620076240067370589036924024728375076210477267488679008016579588696191194060127319035195370137160936882402244399699172017835144537488486396906144217720028992863941288217185353914991583400421682751000603596655790990815525126154394344641336397793791497068253936771017031980867706707490224041075826337383538651825493679503771934836094655802776331664261631740148281763487765852746577808019633679 + +# "Socat" +27788893276069724796504555675597658900595616769773727063231875314156885361379100133264804184710789407128574011804155595735704837674243828066040543912171576627544718762752948158991754559261759162739343094515270757451837630913502740443023902769553802723685440839891240497710460941757089246131322686180648463540974702859210630184042730717698427486397505787974799692901205514386555272667298045803284972074823213104807295638814082142694729938965663710648170010420323923305528998108799706139846097432481556448740855888110797022123731105964852194684036975049177742094726795060211226322344210328442014189175085444396370522979 + +# "Socat" +143319364394905942617148968085785991039146683740268996579566827015580969124702493833109074343879894586653465192222251909074832038151585448034731101690454685781999248641772509287801359980318348021809541131200479989220793925941518568143721972993251823166164933334796625008174851430377966394594186901123322297453 + +# "HAProxy" +176239444111649184001807886764937833964048435503795244999892081768789022375735129915740662180068334018339161388592958930526963170519019882900807402416607478066376591136260438873107131022267101489325892860968978786211058103300402499464852578205304343633112813894051715807017599329349818891389130497782833296267 + +# "HAProxy" +29858796390615156579005888939269198307245905232681039735701203577782476926154873335426127695897301754922870128756842593030151414119709262645229012441727298368711743410459247864230844928652844066470778453407016731127877523140218134153576484186182950525935914709244296481672185142305068112555406408976796124878635827772120777258550853683439376087177772896228263369772738298975007811505514162302230875939649849577860441810207979136789694197146933683702582561144371423098825724758001276881551281910063375037847674958425455182508146273563179524764981626911867808039229817688516441992282273960105156684293367156005318653939 + +# "HAProxy" +906040840570581628380102443042533861539556557517936170926193455423730027837035343802588461339798237837475447988178812029134850861021153585005063335617996553768213337860774575502160795277533287464627066487807717589999181053196180624799186875227432140901857022126832808904656375633414194414552334492747951247501836622316403471110676048569777319299601171704677234861055585859735781271577798830532249564558234177966202320578834072694239353656761041903937825662368907675656932130031869732503793672833030422034909702170861654194326037695796389172599276354651108744948500830717852813901958647978225693799997790190075499683046859044427630083214486625672563853418910161815638591520186500612691900810077498517067960122593264771259949610494243682989807680057883660184291039606834485529416614329435402077543694418214174659819337306416572722289656707277110121619222229511207971018486819624504829653498154535139686575250457271762799716977128710497523899453049153699793530242644384117668637391534890493031631537822163431401923603177775997568711241483941019767613162887962063507644816337503418727944508950664649444861084128865053119474215353946462261884758016198125443516882791862273977681960435739151437484804278673499862950433100913752693192967979 + +# "HAProxy" +102700630561259395087032918003696203215413680966205093401719261420927348617434421199810037690244910311348546427618773468138363558097981635746622031353236427233047123501573548251948502109660464742170278233192733579208742792462937581596612734833735829907594549504874993126473577377037753456164875577780679800659 diff --git a/testssl.sh b/testssl.sh index 648b38a..f70c699 100755 --- a/testssl.sh +++ b/testssl.sh @@ -148,7 +148,7 @@ BUGS=${BUGS:-""} # -bugs option from openssl, needed for DEBUG=${DEBUG:-0} # 1: normal putput the files in /tmp/ are kept for further debugging purposes # 2: list more what's going on , also lists some errors of connections # 3: slight hexdumps + other info, - # 4: display bytes sent via sockets + # 4: display bytes sent via sockets # 5: display bytes received via sockets # 6: whole 9 yards FAST=${FAST:-false} # preference: show only first cipher, run_allciphers with openssl instead of sockets @@ -159,7 +159,7 @@ CSVFILE=${CSVFILE:-""} # csvfile if used APPEND=${APPEND:-false} # append to csv/json file instead of overwriting it GIVE_HINTS=false # give an addtional info to findings HAS_IPv6=${HAS_IPv6:-false} # if you have OpenSSL with IPv6 support AND IPv6 networking set it to yes -UNBRACKTD_IPV6=${UNBRACKTD_IPV6:-false} # some versions of OpenSSL (like Gentoo) don't support [bracketed] IPv6 addresses +UNBRACKTD_IPV6=${UNBRACKTD_IPV6:-false} # some versions of OpenSSL (like Gentoo) don't support [bracketed] IPv6 addresses SERVER_SIZE_LIMIT_BUG=false # Some servers have either a ClientHello total size limit or cipher limit of ~128 ciphers (e.g. old ASAs) # tuning vars, can not be set by a cmd line switch @@ -556,7 +556,7 @@ declare TLS_CIPHER_OSSL_SUPPORTED=() ###### output functions ###### # a little bit of sanitzing with bash internal search&replace -- otherwise printf will hiccup at '%' and '--' does the rest. -out(){ +out(){ # if [[ "$BASH_VERSINFO" -eq 4 ]]; then printf -- "%b" "${1//%/%%}" # else @@ -573,7 +573,7 @@ pr_blue() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && out "\033[1;32m$1" pr_blueln() { pr_blue "$1"; outln; } pr_warning() { [[ "$COLOR" -eq 2 ]] && out "\033[0;35m$1" || pr_underline "$1"; pr_off; } # some local problem: one test cannot be done -pr_warningln() { pr_warning "$1"; outln; } # litemagenya +pr_warningln() { pr_warning "$1"; outln; } # litemagenta pr_magenta() { [[ "$COLOR" -eq 2 ]] && out "\033[1;35m$1" || pr_underline "$1"; pr_off; } # fatal error: quitting because of this! pr_magentaln() { pr_magenta "$1"; outln; } @@ -590,10 +590,10 @@ pr_greyln() { pr_grey "$1"; outln; } pr_done_good() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && out "\033[0;34m$1" || out "\033[0;32m$1" ) || out "$1"; pr_off; } # litegreen (liteblue), This is good pr_done_goodln() { pr_done_good "$1"; outln; } -pr_done_best() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && out "\033[1;34m$1" || out "\033[1;32m$1" ) || out "$1"; pr_off; } # green (blue), This is the best +pr_done_best() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && out "\033[1;34m$1" || out "\033[1;32m$1" ) || out "$1"; pr_off; } # green (blue), This is the best pr_done_bestln() { pr_done_best "$1"; outln; } -pr_svrty_minor() { [[ "$COLOR" -eq 2 ]] && out "\033[1;33m$1" || out "$1"; pr_off; } # yellow brown | academic or minor problem +pr_svrty_minor() { [[ "$COLOR" -eq 2 ]] && out "\033[1;33m$1" || out "$1"; pr_off; } # yellow brown | academic or minor problem pr_svrty_minorln() { pr_svrty_minor "$1"; outln; } pr_svrty_medium() { [[ "$COLOR" -eq 2 ]] && out "\033[0;33m$1" || out "$1"; pr_off; } # brown | it is not a bad problem but you shouldn't do this pr_svrty_mediumln() { pr_svrty_medium "$1"; outln; } @@ -892,6 +892,13 @@ hex2dec() { echo $((16#$1)) } +# convert 414243 into ABC +hex2ascii() { + for (( i=0; i<${#1}; i+=2 )); do + printf "\x${1:$i:2}" + done +} + # trim spaces for BSD and old sed count_lines() { #echo "${$(wc -l <<< "$1")// /}" @@ -1082,7 +1089,7 @@ string_to_asciihex() { [[ -n "$string" ]] && output+="$(printf "%02x" "'${string:eos:1}")" out "$output" return 0 - + } ###### check code starts here ###### @@ -2008,23 +2015,50 @@ listciphers() { } -# argv[1]: cipher list to test +# argv[1]: cipher list to test in OpenSSL syntax # argv[2]: string on console # argv[3]: ok to offer? 0: yes, 1: no # argv[4]: string for fileout +# argv[5]: non-SSLv2 cipher list to test (hexcodes), if using sockets +# argv[6]: SSLv2 cipher list to test (hexcodes), if using sockets std_cipherlists() { - local -i sclient_success + local -i i len sclient_success + local sslv2_cipherlist detected_ssl2_ciphers local singlespaces proto="" addcmd="" local debugname="$(sed -e s'/\!/not/g' -e 's/\:/_/g' <<< "$1")" - [[ "$OPTIMAL_PROTO" == "-ssl2" ]] && addcmd="$OPTIMAL_PROTO" && proto="$OPTIMAL_PROTO" - [[ ! "$OPTIMAL_PROTO" =~ ssl ]] && addcmd="$SNI" + [[ "$OPTIMAL_PROTO" == "-ssl2" ]] && proto="$OPTIMAL_PROTO" pr_bold "$2 " # indenting to be in the same row as server preferences - if listciphers "$1" $proto; then # is that locally available?? - $OPENSSL s_client -cipher "$1" $BUGS $STARTTLS -connect $NODEIP:$PORT $PROXY $addcmd 2>$ERRFILE >$TMPFILE $ERRFILE >$TMPFILE $ERRFILE >$TMPFILE $ERRFILE | while read hexcode dash ciph sslvers kx auth enc mac export ; do - # FIXME: e.g. OpenSSL < 1.0 doesn't understand "-V" --> we can't do anything about it! - normalize_ciphercode $hexcode - # is argument a number? - if [[ $arg =~ $re ]]; then - neat_list $HEXC $ciph $kx $enc | grep -qai "$arg" - else - neat_list $HEXC $ciph $kx $enc | grep -qwai "$arg" - fi - if [[ $? -eq 0 ]]; then # string matches, so we can ssl to it: - if [[ "$sslvers" == "SSLv2" ]]; then - $OPENSSL s_client -ssl2 -cipher $ciph $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY 2>$ERRFILE >$TMPFILE $ERRFILE >$TMPFILE >$ERRFILE) + fi + + # Test the SSLv2 ciphers, if any. + if "$using_sockets"; then + ciphers_to_test="" + for (( i=0; i < nr_ciphers; i++ )); do + if [[ "${sslvers[i]}" == "SSLv2" ]]; then + ciphers_to_test+=", ${hexcode[i]}" + fi + done + if [[ -n "$ciphers_to_test" ]]; then + sslv2_sockets "${ciphers_to_test:2}" "true" + if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then + supported_sslv2_ciphers="$(grep "Supported cipher: " "$TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt")" + "$SHOW_SIGALGO" && s="$($OPENSSL x509 -noout -text -in "$HOSTCERT" | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1)" + for (( i=0 ; i$TMPFILE 2>$ERRFILE = 128 ciphers. So, + # test cipher suites in bundles of 128 or less. + num_bundles=$nr_ossl_ciphers/128 + mod_check=$nr_ossl_ciphers%128 + [[ $mod_check -ne 0 ]] && num_bundles=$num_bundles+1 + + bundle_size=$nr_ossl_ciphers/$num_bundles + mod_check=$nr_ossl_ciphers%$num_bundles + [[ $mod_check -ne 0 ]] && bundle_size+=1 + fi + + "$HAS_NO_SSL2" && addcmd="-no_ssl2" || addcmd="" + for (( bundle=0; bundle < num_bundles; bundle++ )); do + end_of_bundle=$bundle*$bundle_size+$bundle_size + [[ $end_of_bundle -gt $nr_ossl_ciphers ]] && end_of_bundle=$nr_ossl_ciphers + while true; do + ciphers_to_test="" + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + ! "${ciphers_found2[i]}" && ciphers_to_test+=":${ciph2[i]}" + done + [[ -z "$ciphers_to_test" ]] && break + $OPENSSL s_client $addcmd -cipher "${ciphers_to_test:1}" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE = 128 ciphers. So, + # test cipher suites in bundles of 128 or less. + num_bundles=$nr_nonossl_ciphers/128 + mod_check=$nr_nonossl_ciphers%128 + [[ $mod_check -ne 0 ]] && num_bundles=$num_bundles+1 + + bundle_size=$nr_nonossl_ciphers/$num_bundles + mod_check=$nr_nonossl_ciphers%$num_bundles + [[ $mod_check -ne 0 ]] && bundle_size+=1 + fi + + for (( bundle=0; bundle < num_bundles; bundle++ )); do + end_of_bundle=$bundle*$bundle_size+$bundle_size + [[ $end_of_bundle -gt $nr_nonossl_ciphers ]] && end_of_bundle=$nr_nonossl_ciphers + while true; do + ciphers_to_test="" + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode2[i]}" + done + [[ -z "$ciphers_to_test" ]] && break + if "$SHOW_SIGALGO"; then + tls_sockets "03" "${ciphers_to_test:2}, 00,ff" "all" + else + tls_sockets "03" "${ciphers_to_test:2}, 00,ff" "ephemeralkey" + fi + sclient_success=$? + [[ $sclient_success -ne 0 ]] && [[ $sclient_success -ne 2 ]] && break + cipher=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + [[ "$cipher" == "${rfc_ciph2[i]}" ]] && ciphers_found2[i]=true && break + done + [[ $i -eq $end_of_bundle ]] && break + i=${index[i]} + ciphers_found[i]=true + if [[ ${kx[i]} == "Kx=ECDH" ]] || [[ ${kx[i]} == "Kx=DH" ]] || [[ ${kx[i]} == "Kx=EDH" ]]; then + dhlen=$(read_dhbits_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" quiet) + kx[i]="${kx[i]} $dhlen" + fi + "$SHOW_SIGALGO" && [[ -r "$HOSTCERT" ]] && \ + sigalg[i]="$($OPENSSL x509 -noout -text -in "$HOSTCERT" | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1)" + done + done + + for (( i=0; i < nr_ciphers; i++ )); do + export="${export2[i]}" + neat_list "${normalized_hexcode[i]}" "${ciph[i]}" "${kx[i]}" "${enc[i]}" + if "${ciphers_found[i]}"; then + pr_cyan " available" + fileout "cipher_${normalized_hexcode[i]}" "INFO" "$(neat_list "${normalized_hexcode[i]}" "${ciph[i]}" "${kx[i]}" "${enc[i]}") available" + else + out " not a/v" + fileout "cipher_${normalized_hexcode[i]}" "INFO" "$(neat_list "${normalized_hexcode[i]}" "${ciph[i]}" "${kx[i]}" "${enc[i]}") not a/v" + fi + outln + done + "$using_sockets" && HAS_DH_BITS="$has_dh_bits" exit done outln @@ -2352,8 +2588,8 @@ run_allciphers() { pr_headlineln " Testing $nr_ciphers_tested via OpenSSL and sockets against the server, ordered by encryption strength " else pr_headlineln " Testing all $nr_ciphers_tested locally available ciphers against the server, ordered by encryption strength " - outln [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && pr_warning " Cipher mapping not available, doing a fallback to openssl" + outln if ! "$HAS_DH_BITS"; then [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && out "." pr_warningln " Your $OPENSSL cannot show DH/ECDH bits" @@ -2507,124 +2743,291 @@ run_allciphers() { # test for all ciphers per protocol locally configured (w/o distinguishing whether they are good or bad) run_cipher_per_proto() { - local proto proto_text ossl_ciphers_proto - local -i nr_ciphers - local n sslvers auth mac export - local -a hexcode ciph kx enc export2 - local -i i j parent child end_of_bundle round_num bundle_size num_bundles mod_check - local -a ciphers_found - local dhlen + local proto proto_hex proto_text ossl_ciphers_proto + local -i nr_ciphers nr_ossl_ciphers nr_nonossl_ciphers success + local n sslvers auth mac export hexc sslv2_ciphers="" cipher + local -a hexcode normalized_hexcode ciph rfc_ciph kx enc export2 + local -a hexcode2 ciph2 rfc_ciph2 + local -i i bundle end_of_bundle bundle_size num_bundles mod_check + local -a ciphers_found ciphers_found2 sigalg ossl_supported index + local dhlen supported_sslv2_ciphers ciphers_to_test addcmd sni temp local available local id + local has_dh_bits="$HAS_DH_BITS" + local using_sockets=true - pr_headlineln " Testing all locally available ciphers per protocol against the server, ordered by encryption strength " - ! "$HAS_DH_BITS" && pr_warningln " (Your $OPENSSL cannot show DH/ECDH bits)" + "$SSL_NATIVE" && using_sockets=false + "$FAST" && using_sockets=false + [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false + + outln + if "$using_sockets"; then + pr_headlineln " Testing per protocol via OpenSSL and sockets against the server, ordered by encryption strength " + else + pr_headlineln " Testing all locally available ciphers per protocol against the server, ordered by encryption strength " + [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && pr_warning " Cipher mapping not available, doing a fallback to openssl" + outln + if ! "$HAS_DH_BITS"; then + [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && out "." + pr_warningln " (Your $OPENSSL cannot show DH/ECDH bits)" + fi + fi outln neat_header - outln " -ssl2 SSLv2\n -ssl3 SSLv3\n -tls1 TLS 1\n -tls1_1 TLS 1.1\n -tls1_2 TLS 1.2"| while read proto proto_text; do - locally_supported "$proto" "$proto_text" || continue + outln " -ssl2 22 SSLv2\n -ssl3 00 SSLv3\n -tls1 01 TLS 1\n -tls1_1 02 TLS 1.1\n -tls1_2 03 TLS 1.2"| while read proto proto_hex proto_text; do + "$using_sockets" || locally_supported "$proto" "$proto_text" || continue + "$using_sockets" && out "$proto_text " outln has_server_protocol "${proto:1}" || continue - # The OpenSSL ciphers function, prior to version 1.1.0, could only understand -ssl2, -ssl3, and -tls1. - if [[ "$proto" == "-ssl2" ]] || [[ "$proto" == "-ssl3" ]] || \ - [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == "1.1.0"* ]] || [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == "1.1.1"* ]]; then - ossl_ciphers_proto="$proto" - else - ossl_ciphers_proto="-tls1" - fi - # get a list of all the cipher suites to test (only need the hexcode, ciph, kx, enc, and export values) + # get a list of all the cipher suites to test nr_ciphers=0 - while read hexcode[nr_ciphers] n ciph[nr_ciphers] sslvers kx[nr_ciphers] auth enc[nr_ciphers] mac export2[nr_ciphers]; do - nr_ciphers=$nr_ciphers+1 - done < <($OPENSSL ciphers $ossl_ciphers_proto -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>$ERRFILE) - - # Split ciphers into bundles of size 4**n, starting with the smallest - # "n" that leaves the ciphers in one bundle, and then reducing "n" by - # one in each round. Only test a bundle of 4**n ciphers against the - # server if it was part of a bundle of 4**(n+1) ciphers that included - # a cipher supported by the server. Continue until n=0. - - # Determine the smallest bundle size that will result in their being one bundle. - for(( bundle_size=1; bundle_size < nr_ciphers; bundle_size*=4 )); do - : - done - - # set ciphers_found[1] so that the complete bundle will be tested in round 0. - ciphers_found[1]=true - # Some servers can't handle a handshake with >= 128 ciphers. - for (( round_num=0; bundle_size>=128; bundle_size/=4 )); do - round_num=$round_num+1 - for (( i=4**$round_num; i<2*4**$round_num; i++ )); do - ciphers_found[i]=true + if "$using_sockets" || [[ $OSSL_VER_MAJOR -lt 1 ]]; then + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + hexc="${TLS_CIPHER_HEXCODE[i]}" + ciph[nr_ciphers]="${TLS_CIPHER_OSSL_NAME[i]}" + rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" + kx[nr_ciphers]="${TLS_CIPHER_KX[i]}" + enc[nr_ciphers]="${TLS_CIPHER_ENC[i]}" + export2[nr_ciphers]="${TLS_CIPHER_EXPORT[i]}" + ciphers_found[nr_ciphers]=false + sigalg[nr_ciphers]="" + ossl_supported[nr_ciphers]=${TLS_CIPHER_OSSL_SUPPORTED[i]} + if "$using_sockets" && ! "$has_dh_bits" && ( [[ ${kx[nr_ciphers]} == "Kx=ECDH" ]] || [[ ${kx[nr_ciphers]} == "Kx=DH" ]] || [[ ${kx[nr_ciphers]} == "Kx=EDH" ]] ); then + ossl_supported[nr_ciphers]=false + fi + if [[ ${#hexc} -eq 9 ]]; then + hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2}" + if [[ "${hexc:2:2}" == "00" ]]; then + normalized_hexcode[nr_ciphers]="x${hexc:7:2}" + else + normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}" + fi + else + hexc="$(tolower "$hexc")" + hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2},${hexc:12:2}" + normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}${hexc:12:2}" + fi + if ( "$using_sockets" || "${TLS_CIPHER_OSSL_SUPPORTED[i]}" ); then + if [[ ${#hexc} -eq 9 ]] && [[ "$proto_text" != "SSLv2" ]]; then + if [[ "$proto_text" == "TLS 1.3" ]]; then + [[ "${hexc:2:2}" == "13" ]] && nr_ciphers+=1 + elif [[ "$proto_text" == "TLS 1.2" ]]; then + [[ "${hexc:2:2}" != "13" ]] && nr_ciphers+=1 + elif [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA256" ]] && [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA384" ]] && \ + [[ "${TLS_CIPHER_RFC_NAME[i]}" != *"_CCM" ]] && [[ "${TLS_CIPHER_RFC_NAME[i]}" != *"_CCM_8" ]]; then + nr_ciphers+=1 + fi + elif [[ ${#hexc} -eq 14 ]] && [[ "$proto_text" == "SSLv2" ]]; then + sslv2_ciphers+=", ${hexcode[nr_ciphers]}" + nr_ciphers+=1 + fi + fi done - done - for (( 1; bundle_size>=1; bundle_size/=4 )); do - # Note that since the number of ciphers isn't a power of 4, the number - # of bundles may be may be less than 4**(round_num+1), and the final - # bundle may have fewer than bundle_size ciphers. - num_bundles=$nr_ciphers/$bundle_size - mod_check=$nr_ciphers%$bundle_size - [[ $mod_check -ne 0 ]] && num_bundles=$num_bundles+1 - for (( i=0; i$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE >$ERRFILE) + fi - # If this is a "leaf" of the test tree, then print out the results. - if [[ $bundle_size -eq 1 ]] && ( ${ciphers_found[child]} || "$SHOW_EACH_C"); then - export=${export2[i]} - normalize_ciphercode "${hexcode[i]}" - if [[ ${kx[i]} == "Kx=ECDH" ]] || [[ ${kx[i]} == "Kx=DH" ]] || [[ ${kx[i]} == "Kx=EDH" ]]; then - if ${ciphers_found[child]}; then - dhlen=$(read_dhbits_from_file "$TMPFILE" quiet) - kx[i]="${kx[i]} $dhlen" - fi - fi - neat_list "$HEXC" "${ciph[i]}" "${kx[i]}" "${enc[i]}" - if "$SHOW_EACH_C"; then - if ${ciphers_found[child]}; then + if [[ "$proto" == "-ssl2" ]] && "$using_sockets"; then + sslv2_sockets "${sslv2_ciphers:2}" "true" + if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then + supported_sslv2_ciphers="$(grep "Supported cipher: " "$TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt")" + "$SHOW_SIGALGO" && s="$($OPENSSL x509 -noout -text -in "$HOSTCERT" | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1)" + for (( i=0 ; i$TMPFILE 2>$ERRFILE = 128 ciphers. So, + # test cipher suites in bundles of 128 or less. + num_bundles=$nr_ossl_ciphers/128 + mod_check=$nr_ossl_ciphers%128 + [[ $mod_check -ne 0 ]] && num_bundles=$num_bundles+1 + + bundle_size=$nr_ossl_ciphers/$num_bundles + mod_check=$nr_ossl_ciphers%$num_bundles + [[ $mod_check -ne 0 ]] && bundle_size+=1 + fi + + sni="" + [[ ! "$proto" =~ ssl ]] && sni="$SNI" + for (( bundle=0; bundle < num_bundles; bundle++ )); do + end_of_bundle=$bundle*$bundle_size+$bundle_size + [[ $end_of_bundle -gt $nr_ossl_ciphers ]] && end_of_bundle=$nr_ossl_ciphers + for (( success=0; success==0 ; 1 )); do + ciphers_to_test="" + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + ! "${ciphers_found2[i]}" && ciphers_to_test+=":${ciph2[i]}" + done + success=1 + if [[ -n "$ciphers_to_test" ]]; then + $OPENSSL s_client -cipher "${ciphers_to_test:1}" $proto $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $sni >$TMPFILE 2>$ERRFILE = 128 ciphers. So, + # test cipher suites in bundles of 128 or less. + num_bundles=$nr_nonossl_ciphers/128 + mod_check=$nr_nonossl_ciphers%128 + [[ $mod_check -ne 0 ]] && num_bundles=$num_bundles+1 + + bundle_size=$nr_nonossl_ciphers/$num_bundles + mod_check=$nr_nonossl_ciphers%$num_bundles + [[ $mod_check -ne 0 ]] && bundle_size+=1 + fi + + for (( bundle=0; bundle < num_bundles; bundle++ )); do + end_of_bundle=$bundle*$bundle_size+$bundle_size + [[ $end_of_bundle -gt $nr_nonossl_ciphers ]] && end_of_bundle=$nr_nonossl_ciphers + for (( success=0; success==0 ; 1 )); do + ciphers_to_test="" + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode2[i]}" + done + success=1 + if [[ -n "$ciphers_to_test" ]]; then + if "$SHOW_SIGALGO"; then + tls_sockets "$proto_hex" "${ciphers_to_test:2}, 00,ff" "all" + else + tls_sockets "$proto_hex" "${ciphers_to_test:2}, 00,ff" "ephemeralkey" + fi + if [[ $? -eq 0 ]]; then + success=0 + cipher=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + [[ "$cipher" == "${rfc_ciph2[i]}" ]] && ciphers_found2[i]=true && break + done + i=${index[i]} + ciphers_found[i]=true + if [[ "$proto_text" == "TLS 1.3" ]]; then + temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") # extract line + kx[i]="Kx=$(awk -F',' '{ print $1 }' <<< $temp)" + fi + if [[ ${kx[i]} == "Kx=ECDH" ]] || [[ ${kx[i]} == "Kx=DH" ]] || [[ ${kx[i]} == "Kx=EDH" ]]; then + dhlen=$(read_dhbits_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" quiet) + kx[i]="${kx[i]} $dhlen" + fi + "$SHOW_SIGALGO" && [[ -r "$HOSTCERT" ]] && \ + sigalg[i]="$($OPENSSL x509 -noout -text -in "$HOSTCERT" | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1)" + fi + fi + done + done + fi + + for (( i=0 ; i$TMPFILE 2>$ERRFILE debugme echo "$OPENSSL s_client -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} $TMPFILE 2>$ERRFILE sclient_connect_successful $? $TMPFILE sclient_success=$? fi @@ -3650,8 +4053,8 @@ run_client_simulation() { if [[ "$proto" == TLSv1.2 ]] && ( ! "$using_sockets" || [[ -z "${handshakebytes[i]}" ]] ); then # OpenSSL reports TLS1.2 even if the connection is TLS1.1 or TLS1.0. Need to figure out which one it is... for tls in ${tlsvers[i]}; do - $OPENSSL s_client $tls -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} $TMPFILE 2>$ERRFILE debugme echo "$OPENSSL s_client $tls -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} $TMPFILE 2>$ERRFILE sclient_connect_successful $? $TMPFILE sclient_success=$? if [[ $sclient_success -eq 0 ]]; then @@ -3697,7 +4100,7 @@ run_client_simulation() { # generic function whether $1 is supported by s_client ($2: string to display) locally_supported() { [[ -n "$2" ]] && out "$2 " - if $OPENSSL s_client "$1" 2>&1 | grep -aq "unknown option"; then + if $OPENSSL s_client "$1" -connect x 2>&1 | grep -aq "unknown option"; then local_problem_ln "$OPENSSL doesn't support \"s_client $1\"" return 7 fi @@ -3971,7 +4374,7 @@ run_protocols() { fileout "tls1_1" "CRITICAL" "TLSv1.1 is not offered, server responded with higher version number ($detected_version_string) than requested by client" else pr_svrty_criticalln " -- server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" - fileout "tls1" "CRITICAL" "TLSv1.1: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" + fileout "tls1_1" "CRITICAL" "TLSv1.1: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" fi ;; 5) @@ -4004,7 +4407,7 @@ run_protocols() { fileout "tls1_2" "MEDIUM" "TLSv1.2 is not offered" # no GCM, penalty else pr_svrty_criticalln " -- connection failed rather than downgrading to $latest_supported_string" - fileout "tls1_1" "CRITICAL" "TLSv1.2: connection failed rather than downgrading to $latest_supported_string" + fileout "tls1_2" "CRITICAL" "TLSv1.2: connection failed rather than downgrading to $latest_supported_string" fi ;; 2) @@ -4026,7 +4429,7 @@ run_protocols() { fileout "tls1_2" "CRITICAL" "TLSv1.2 is not offered, server responded with higher version number ($detected_version_string) than requested by client" else pr_svrty_criticalln " -- server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" - fileout "tls1" "CRITICAL" "TLSv1.2: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" + fileout "tls1_2" "CRITICAL" "TLSv1.2: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" fi ;; 5) @@ -4043,21 +4446,58 @@ run_protocols() { #TODO: work with fixed lists here run_std_cipherlists() { + local hexc hexcode strength + local -i i + local null_ciphers="c0,10, c0,06, c0,15, c0,0b, c0,01, c0,3b, c0,3a, c0,39, 00,b9, 00,b8, 00,b5, 00,b4, 00,2e, 00,2d, 00,b1, 00,b0, 00,2c, 00,3b, 00,02, 00,01, 00,82, 00,83, ff,87, 00,ff" + local sslv2_null_ciphers="" + local anon_ciphers="c0,19, 00,a7, 00,6d, 00,3a, 00,c5, 00,89, c0,47, c0,5b, c0,85, c0,18, 00,a6, 00,6c, 00,34, 00,bf, 00,9b, 00,46, c0,46, c0,5a, c0,84, c0,16, 00,18, c0,17, 00,1b, 00,1a, 00,19, 00,17, c0,15, 00,ff" + local sslv2_anon_ciphers="" + local adh_ciphers="00,a7, 00,6d, 00,3a, 00,c5, 00,89, c0,47, c0,5b, c0,85, 00,a6, 00,6c, 00,34, 00,bf, 00,9b, 00,46, c0,46, c0,5a, c0,84, 00,18, 00,1b, 00,1a, 00,19, 00,17, 00,ff" + local sslv2_adh_ciphers="" + local exp40_ciphers="00,14, 00,11, 00,19, 00,08, 00,06, 00,27, 00,26, 00,2a, 00,29, 00,0b, 00,0e, 00,17, 00,03, 00,28, 00,2b, 00,ff" + local sslv2_exp40_ciphers="04,00,80, 02,00,80" + local exp56_ciphers="00,63, 00,62, 00,61, 00,65, 00,64, 00,60, 00,ff" + local sslv2_exp56_ciphers="" + local exp_ciphers="00,63, 00,62, 00,61, 00,65, 00,64, 00,60, 00,14, 00,11, 00,19, 00,08, 00,06, 00,27, 00,26, 00,2a, 00,29, 00,0b, 00,0e, 00,17, 00,03, 00,28, 00,2b, 00,ff" + local sslv2_exp_ciphers="04,00,80, 02,00,80" + local low_ciphers="00,15, 00,12, 00,0f, 00,0c, 00,09, 00,1e, 00,22, fe,fe, ff,e1, 00,ff" + local sslv2_low_ciphers="08,00,80, 06,00,40" + local des_ciphers="00,15, 00,12, 00,0f, 00,0c, 00,09, 00,1e, 00,22, fe,fe, ff,e1, 00,ff" + local sslv2_des_ciphers="06,00,40" + local medium_ciphers="00,9a, 00,99, 00,98, 00,97, 00,96, 00,07, 00,21, 00,25, c0,11, c0,07, 00,66, c0,0c, c0,02, 00,05, 00,04, 00,92, 00,8a, 00,20, 00,24, c0,33, 00,8e, 00,ff" + local sslv2_medium_ciphers="" + local tdes_ciphers="c0,12, c0,08, c0,1c, c0,1b, c0,1a, 00,16, 00,13, 00,10, 00,0d, c0,0d, c0,03, 00,0a, 00,93, 00,8b, 00,1f, 00,23, c0,34, 00,8f, fe,ff, ff,e0, 00,ff" + local sslv2_tdes_ciphers="07,00,c0" + local high_ciphers="13,02, 13,03, cc,14, cc,13, cc,15, c0,30, c0,2c, c0,28, c0,24, c0,14, c0,0a, c0,22, c0,21, c0,20, 00,b7, 00,b3, 00,91, c0,9b, c0,99, c0,97, 00,af, c0,95, 00,a5, 00,a3, 00,a1, 00,9f, cc,a9, cc,a8, cc,aa, c0,af, c0,ad, c0,a3, c0,9f, 00,6b, 00,6a, 00,69, 00,68, 00,39, 00,38, 00,37, 00,36, c0,77, c0,73, 00,c4, 00,c3, 00,c2, 00,c1, 00,88, 00,87, 00,86, 00,85, 00,ad, 00,ab, cc,ae, cc,ad, cc,ac, c0,ab, c0,a7, c0,32, c0,2e, c0,2a, c0,26, c0,0f, c0,05, c0,79, c0,75, 00,9d, c0,a1, c0,9d, 00,a9, cc,ab, c0,a9, c0,a5, 00,3d, 00,35, 00,c0, c0,38, c0,36, 00,84, 00,95, 00,8d, c0,3d, c0,3f, c0,41, c0,43, c0,45, c0,49, c0,4b, c0,4d, c0,4f, c0,51, c0,53, c0,55, c0,57, c0,59, c0,5d, c0,5f, c0,61, c0,63, c0,65, c0,67, c0,69, c0,6b, c0,6d, c0,6f, c0,71, c0,7b, c0,7d, c0,7f, c0,81, c0,83, c0,87, c0,89, c0,8b, c0,8d, c0,8f, c0,91, c0,93, 00,80, 00,81, ff,00, ff,01, ff,02, ff,03, ff,85, 16,b7, 16,b8, 16,b9, 16,ba, 13,01, 13,04, 13,05, c0,2f, c0,2b, c0,27, c0,23, c0,13, c0,09, c0,1f, c0,1e, c0,1d, 00,a4, 00,a2, 00,a0, 00,9e, c0,ae, c0,ac, c0,a2, c0,9e, 00,ac, 00,aa, c0,aa, c0,a6, c0,a0, c0,9c, 00,a8, c0,a8, c0,a4, 00,67, 00,40, 00,3f, 00,3e, 00,33, 00,32, 00,31, 00,30, c0,76, c0,72, 00,be, 00,bd, 00,bc, 00,bb, 00,45, 00,44, 00,43, 00,42, c0,31, c0,2d, c0,29, c0,25, c0,0e, c0,04, c0,78, c0,74, 00,9c, 00,3c, 00,2f, 00,ba, c0,37, c0,35, 00,b6, 00,b2, 00,90, 00,41, c0,9a, c0,98, c0,96, 00,ae, c0,94, 00,94, 00,8c, c0,3c, c0,3e, c0,40, c0,42, c0,44, c0,48, c0,4a, c0,4c, c0,4e, c0,50, c0,52, c0,54, c0,56, c0,58, c0,5c, c0,5e, c0,60, c0,62, c0,64, c0,66, c0,68, c0,6a, c0,6c, c0,6e, c0,70, c0,7a, c0,7c, c0,7e, c0,80, c0,82, c0,86, c0,88, c0,8a, c0,8c, c0,8e, c0,90, c0,92, 00,ff" + local sslv2_high_ciphers="" + local using_sockets=true + + "$SSL_NATIVE" && using_sockets=false + + if ! "$using_sockets"; then + null_ciphers=""; anon_ciphers=""; adh_ciphers=""; exp40_ciphers="" + exp56_ciphers=""; exp_ciphers=""; low_ciphers=""; des_ciphers="" + medium_ciphers=""; tdes_ciphers=""; high_ciphers="" + sslv2_null_ciphers=""; sslv2_anon_ciphers=""; sslv2_adh_ciphers=""; sslv2_exp40_ciphers="" + sslv2_exp56_ciphers=""; sslv2_exp_ciphers=""; sslv2_low_ciphers=""; sslv2_des_ciphers="" + sslv2_medium_ciphers=""; sslv2_tdes_ciphers=""; sslv2_high_ciphers="" + fi + outln pr_headlineln " Testing ~standard cipher lists " outln # see ciphers(1ssl) or run 'openssl ciphers -v' - std_cipherlists 'NULL:eNULL' " Null Ciphers " 1 "NULL" - std_cipherlists 'aNULL' " Anonymous NULL Ciphers " 1 "aNULL" - std_cipherlists 'ADH' " Anonymous DH Ciphers " 1 "ADH" - std_cipherlists 'EXPORT40' " 40 Bit encryption " 1 "EXPORT40" - std_cipherlists 'EXPORT56' " 56 Bit encryption " 1 "EXPORT56" - std_cipherlists 'EXPORT' " Export Ciphers (general) " 1 "EXPORT" - std_cipherlists 'LOW:!ADH' " Low (<=64 Bit) " 1 "LOW" - std_cipherlists 'DES:!ADH:!EXPORT:!aNULL' " DES Ciphers " 1 "DES" - std_cipherlists 'MEDIUM:!NULL:!aNULL:!SSLv2:!3DES' " \"Medium\" grade encryption" 2 "MEDIUM" - std_cipherlists '3DES:!ADH:!aNULL' " Triple DES Ciphers " 3 "3DES" - std_cipherlists 'HIGH:!NULL:!aNULL:!DES:!3DES' " High grade encryption " 0 "HIGH" + std_cipherlists 'NULL:eNULL' " Null Ciphers " 1 "NULL" "$null_ciphers" "$sslv2_null_ciphers" + std_cipherlists 'aNULL' " Anonymous NULL Ciphers " 1 "aNULL" "$anon_ciphers" "$sslv2_anon_ciphers" + std_cipherlists 'ADH' " Anonymous DH Ciphers " 1 "ADH" "$adh_ciphers" "$sslv2_adh_ciphers" + std_cipherlists 'EXPORT40' " 40 Bit encryption " 1 "EXPORT40" "$exp40_ciphers" "$sslv2_exp40_ciphers" + std_cipherlists 'EXPORT56' " 56 Bit encryption " 1 "EXPORT56" "$exp56_ciphers" "$sslv2_exp56_ciphers" + std_cipherlists 'EXPORT' " Export Ciphers (general) " 1 "EXPORT" "$exp_ciphers" "$sslv2_exp_ciphers" + std_cipherlists 'LOW:!ADH' " Low (<=64 Bit) " 1 "LOW" "$low_ciphers" "$sslv2_low_ciphers" + std_cipherlists 'DES:!ADH:!EXPORT:!aNULL' " DES Ciphers " 1 "DES" "$des_ciphers" "$sslv2_des_ciphers" + std_cipherlists 'MEDIUM:!NULL:!aNULL:!SSLv2:!3DES' " \"Medium\" grade encryption" 2 "MEDIUM" "$medium_ciphers" "$sslv2_medium_ciphers" + std_cipherlists '3DES:!ADH:!aNULL' " Triple DES Ciphers " 3 "3DES" "$tdes_ciphers" "$sslv2_tdes_ciphers" + std_cipherlists 'HIGH:!NULL:!aNULL:!DES:!3DES' " High grade encryption " 0 "HIGH" "$high_ciphers" "$sslv2_high_ciphers" outln return 0 } @@ -4066,7 +4506,7 @@ run_std_cipherlists() { # arg1: file with input for grepping the bit length for ECDH/DHE # arg2: whether to print warning "old fart" or not (empty: no) read_dhbits_from_file() { - local bits what_dh temp + local bits what_dh temp curve="" local add="" local old_fart=" (openssl cannot show DH bits)" @@ -4074,14 +4514,23 @@ read_dhbits_from_file() { what_dh=$(awk -F',' '{ print $1 }' <<< $temp) bits=$(awk -F',' '{ print $3 }' <<< $temp) # RH's backport has the DH bits in second arg after comma - grep -q bits <<< $bits || bits=$(awk -F',' '{ print $2 }' <<< $temp) + if grep -q bits <<< $bits; then + curve="$(strip_spaces "$(awk -F',' '{ print $2 }' <<< $temp)")" + else + bits=$(awk -F',' '{ print $2 }' <<< $temp) + fi bits=$(tr -d ' bits' <<< $bits) if [[ "$what_dh" == "X25519" ]] || [[ "$what_dh" == "X448" ]]; then + curve="$what_dh" what_dh="ECDH" fi - debugme echo ">$HAS_DH_BITS|$what_dh|$bits<" + if [[ -n "$curve" ]]; then + debugme echo ">$HAS_DH_BITS|$what_dh($curve)|$bits<" + else + debugme echo ">$HAS_DH_BITS|$what_dh|$bits<" + fi [[ -n "$what_dh" ]] && HAS_DH_BITS=true # FIX 190 if [[ -z "$what_dh" ]] && ! "$HAS_DH_BITS"; then @@ -4093,7 +4542,10 @@ read_dhbits_from_file() { [[ -n "$bits" ]] && [[ -z "$2" ]] && out ", " if [[ $what_dh == "DH" ]] || [[ $what_dh == "EDH" ]]; then - [[ -z "$2" ]] && add="bit DH" + if [[ -z "$2" ]]; then + add="bit DH" + [[ -n "$curve" ]] && add+=" ($curve)" + fi if [[ "$bits" -le 600 ]]; then pr_svrty_critical "$bits $add" elif [[ "$bits" -le 800 ]]; then @@ -4107,7 +4559,10 @@ read_dhbits_from_file() { fi # https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography, http://www.keylength.com/en/compare/ elif [[ $what_dh == "ECDH" ]]; then - [[ -z "$2" ]] && add="bit ECDH" + if [[ -z "$2" ]]; then + add="bit ECDH" + [[ -n "$curve" ]] && add+=" ($curve)" + fi if [[ "$bits" -le 80 ]]; then # has that ever existed? pr_svrty_critical "$bits $add" elif [[ "$bits" -le 108 ]]; then # has that ever existed? @@ -4132,15 +4587,18 @@ read_dhbits_from_file() { run_server_preference() { local cipher1 cipher2 local default_cipher default_proto - local remark4default_cipher + local remark4default_cipher supported_sslv2_ciphers local -a cipher proto local p i - local -i ret=0 + local -i ret=0 j local list_fwd="DES-CBC3-SHA:RC4-MD5:DES-CBC-SHA:RC4-SHA:AES128-SHA:AES128-SHA256:AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-AES256-SHA:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-DSS-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:AES256-SHA256" # now reversed offline via tac, see https://github.com/thomassa/testssl.sh/commit/7a4106e839b8c3033259d66697893765fc468393 : local list_reverse="AES256-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-DES-CBC3-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:AES256-SHA:AES128-SHA256:AES128-SHA:RC4-SHA:DES-CBC-SHA:RC4-MD5:DES-CBC3-SHA" local has_cipher_order=true local isok addcmd="" addcmd2="" sni="" + local using_sockets=true + + "$SSL_NATIVE" && using_sockets=false outln pr_headlineln " Testing server preferences " @@ -4299,26 +4757,61 @@ run_server_preference() { i=1 for p in ssl2 ssl3 tls1 tls1_1 tls1_2; do if [[ $p == ssl2 ]] && ! "$HAS_SSL2"; then - out " (SSLv2: "; local_problem "$OPENSSL doesn't support \"s_client -ssl2\""; outln ")"; - continue - fi - if [[ $p == ssl3 ]] && ! "$HAS_SSL3"; then - out " (SSLv3: "; local_problem "$OPENSSL doesn't support \"s_client -ssl3\"" ; outln ")"; - continue - fi - if [[ "$p" =~ ssl ]]; then - $OPENSSL s_client $STARTTLS -"$p" $BUGS -connect $NODEIP:$PORT $PROXY >$ERRFILE >$TMPFILE + if ! "$using_sockets" || [[ $TLS_NR_CIPHERS -eq 0 ]]; then + out " (SSLv2: "; local_problem "$OPENSSL doesn't support \"s_client -ssl2\""; outln ")"; + continue + else + sslv2_sockets "" "true" + if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then + # Just arbitrarily pick the first cipher in the cipher-mapping.txt list. + proto[i]="SSLv2" + supported_sslv2_ciphers="$(grep "Supported cipher: " "$TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt")" + for (( j=0; j < TLS_NR_CIPHERS; j++ )); do + if [[ "${TLS_CIPHER_SSLVERS[j]}" == "SSLv2" ]]; then + cipher1="${TLS_CIPHER_HEXCODE[j]}" + cipher1="$(tolower "x${cipher1:2:2}${cipher1:7:2}${cipher1:12:2}")" + if [[ "$supported_sslv2_ciphers" =~ "$cipher1" ]]; then + cipher[i]="${TLS_CIPHER_OSSL_NAME[j]}" + break + fi + fi + done + [[ $DEBUG -ge 2 ]] && outln "Default cipher for ${proto[i]}: ${cipher[i]}" + else + proto[i]="" + cipher[i]="" + fi + fi + elif [[ $p == ssl3 ]] && ! "$HAS_SSL3"; then + if ! "$using_sockets"; then + out " (SSLv3: "; local_problem "$OPENSSL doesn't support \"s_client -ssl3\"" ; outln ")"; + continue + else + tls_sockets "00" "$TLS_CIPHER" + if [[ $? -eq 0 ]]; then + proto[i]="SSLv3" + cipher[i]="" + cipher1=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") + [[ $TLS_NR_CIPHERS -ne 0 ]] && cipher[i]="$(rfc2openssl "$cipher1")" + [[ -z "${cipher[i]}" ]] && cipher[i]="$cipher1" + [[ $DEBUG -ge 2 ]] && outln "Default cipher for ${proto[i]}: ${cipher[i]}" + else + proto[i]="" + cipher[i]="" + fi + fi else - $OPENSSL s_client $STARTTLS -"$p" $BUGS -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE - fi - if sclient_connect_successful $? $TMPFILE; then - proto[i]=$(grep -aw "Protocol" $TMPFILE | sed -e 's/^.*Protocol.*://' -e 's/ //g') - cipher[i]=$(grep -aw "Cipher" $TMPFILE | egrep -avw "New|is" | sed -e 's/^.*Cipher.*://' -e 's/ //g') - [[ ${cipher[i]} == "0000" ]] && cipher[i]="" # Hack! - [[ $DEBUG -ge 2 ]] && outln "Default cipher for ${proto[i]}: ${cipher[i]}" - else - proto[i]="" - cipher[i]="" + [[ "$p" =~ ssl ]] && sni="" || sni="$SNI" + $OPENSSL s_client $STARTTLS -"$p" $BUGS -connect $NODEIP:$PORT $PROXY $sni >$ERRFILE >$TMPFILE + if sclient_connect_successful $? $TMPFILE; then + proto[i]=$(grep -aw "Protocol" $TMPFILE | sed -e 's/^.*Protocol.*://' -e 's/ //g') + cipher[i]=$(grep -aw "Cipher" $TMPFILE | egrep -avw "New|is" | sed -e 's/^.*Cipher.*://' -e 's/ //g') + [[ ${cipher[i]} == "0000" ]] && cipher[i]="" # Hack! + [[ $DEBUG -ge 2 ]] && outln "Default cipher for ${proto[i]}: ${cipher[i]}" + else + proto[i]="" + cipher[i]="" + fi fi i=$(($i + 1)) done @@ -4373,15 +4866,18 @@ run_server_preference() { check_tls12_pref() { local batchremoved="-CAMELLIA:-IDEA:-KRB5:-PSK:-SRP:-aNULL:-eNULL" local batchremoved_success=false - local tested_cipher="-$1" - local order="$1" + local tested_cipher="" + local order="" + local -i nr_ciphers_found_r1=0 nr_ciphers_found_r2=0 while true; do - $OPENSSL s_client $STARTTLS -tls1_2 $BUGS -cipher "ALL:$tested_cipher:$batchremoved" -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE + $OPENSSL s_client $STARTTLS -tls1_2 $BUGS -cipher "ALL$tested_cipher:$batchremoved" -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE if sclient_connect_successful $? $TMPFILE ; then cipher=$(awk '/Cipher.*:/ { print $3 }' $TMPFILE) order+=" $cipher" tested_cipher="$tested_cipher:-$cipher" + nr_ciphers_found_r1+=1 + "$FAST" && break else debugme outln "A: $tested_cipher" break @@ -4389,7 +4885,7 @@ check_tls12_pref() { done batchremoved="${batchremoved//-/}" while true; do - # no ciphers from "ALL:$tested_cipher:$batchremoved" left + # no ciphers from "ALL$tested_cipher:$batchremoved" left # now we check $batchremoved, and remove the minus signs first: $OPENSSL s_client $STARTTLS -tls1_2 $BUGS -cipher "$batchremoved" -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE if sclient_connect_successful $? $TMPFILE ; then @@ -4397,7 +4893,9 @@ check_tls12_pref() { cipher=$(awk '/Cipher.*:/ { print $3 }' $TMPFILE) order+=" $cipher" batchremoved="$batchremoved:-$cipher" + nr_ciphers_found_r1+=1 debugme outln "B1: $batchremoved" + "$FAST" && break else debugme outln "B2: $batchremoved" break @@ -4407,34 +4905,31 @@ check_tls12_pref() { if "$batchremoved_success"; then # now we combine the two cipher sets from both while loops + [[ "${order:0:1}" == " " ]] && order="${order:1}" combined_ciphers="${order// /:}" - $OPENSSL s_client $STARTTLS -tls1_2 $BUGS -cipher "$combined_ciphers" -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE - if sclient_connect_successful $? $TMPFILE ; then - # first cipher - cipher=$(awk '/Cipher.*:/ { print $3 }' $TMPFILE) - order="$cipher" - tested_cipher="-$cipher" - else - fixmeln "something weird happened around line $((LINENO - 6))" - return 1 - fi + order="" ; tested_cipher="" while true; do - $OPENSSL s_client $STARTTLS -tls1_2 $BUGS -cipher "$combined_ciphers:$tested_cipher" -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE + $OPENSSL s_client $STARTTLS -tls1_2 $BUGS -cipher "$combined_ciphers$tested_cipher" -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE if sclient_connect_successful $? $TMPFILE ; then cipher=$(awk '/Cipher.*:/ { print $3 }' $TMPFILE) order+=" $cipher" tested_cipher="$tested_cipher:-$cipher" + nr_ciphers_found_r2+=1 + "$FAST" && break else # nothing left, we're done - out " $order" break fi done - - else - # second cipher set didn't succeed: we can just output everything - out " $order" + if "$FAST" && [[ $nr_ciphers_found_r2 -ne 1 ]]; then + fixmeln "something weird happened around line $((LINENO - 14))" + return 1 + elif ! "$FAST" && [[ $nr_ciphers_found_r2 -ne $nr_ciphers_found_r1 ]]; then + fixmeln "something weird happened around line $((LINENO - 16))" + return 1 + fi fi + out "$order" tmpfile_handle $FUNCNAME.txt return 0 @@ -4442,35 +4937,34 @@ check_tls12_pref() { cipher_pref_check() { - local p proto protos npn_protos sni + local p proto proto_hex npn_protos sni local tested_cipher cipher order local overflow_probe_cipherlist="ALL:-ECDHE-RSA-AES256-GCM-SHA384:-AES128-SHA:-DES-CBC3-SHA" + local -i i nr_ciphers nr_nonossl_ciphers num_bundles mod_check bundle_size bundle end_of_bundle success + local hexc ciphers_to_test + local -a rfc_ciph hexcode ciphers_found ciphers_found2 + local -a -i index + local using_sockets=true ciphers_found_with_sockets + + "$SSL_NATIVE" && using_sockets=false + "$FAST" && using_sockets=false + [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false pr_bold " Cipher order" - for p in ssl2 ssl3 tls1 tls1_1 tls1_2; do - order="" - if [[ $p == ssl2 ]] && ! "$HAS_SSL2"; then - out "\n SSLv2: "; local_problem "$OPENSSL doesn't support \"s_client -ssl2\""; - continue - fi - if [[ $p == ssl3 ]] && ! "$HAS_SSL3"; then + outln " ssl3 00 SSLv3\n tls1 01 TLSv1\n tls1_1 02 TLSv1.1\n tls1_2 03 TLSv1.2"| while read p proto_hex proto; do + order=""; ciphers_found_with_sockets=false + if [[ $p == ssl3 ]] && ! "$HAS_SSL3" && ! "$using_sockets"; then out "\n SSLv3: "; local_problem "$OPENSSL doesn't support \"s_client -ssl3\""; continue fi - # with the supplied binaries SNI works also for SSLv2 (+ SSLv3) - [[ "$p" =~ ssl ]] && sni="" || sni=$SNI - $OPENSSL s_client $STARTTLS -"$p" $BUGS -connect $NODEIP:$PORT $PROXY $sni $ERRFILE >$TMPFILE - if sclient_connect_successful $? $TMPFILE; then - tested_cipher="" - proto=$(awk '/Protocol/ { print $3 }' $TMPFILE) - cipher=$(awk '/Cipher *:/ { print $3 }' $TMPFILE) - [[ -z "$proto" ]] && continue # for early openssl versions sometimes needed - outln - printf " %-10s" "$proto: " - tested_cipher="-"$cipher - order="$cipher" - if [[ $p == tls1_2 ]]; then + has_server_protocol "$p" || continue + + if [[ $p != ssl3 ]] || "$HAS_SSL3"; then + # with the supplied binaries SNI works also for SSLv3 + [[ "$p" =~ ssl ]] && sni="" || sni=$SNI + + if [[ $p == tls1_2 ]] && ! "$SERVER_SIZE_LIMIT_BUG"; then # for some servers the ClientHello is limited to 128 ciphers or the ClientHello itself has a length restriction. # So far, this was only observed in TLS 1.2, affected are e.g. old Cisco LBs or ASAs, see issue #189 # To check whether a workaround is needed we send a laaarge list of ciphers/big client hello. If connect fails, @@ -4482,23 +4976,144 @@ cipher_pref_check() { fi fi if [[ $p == tls1_2 ]] && "$SERVER_SIZE_LIMIT_BUG"; then - order=$(check_tls12_pref "$cipher") - out "$order" + order="$(check_tls12_pref)" else - out " $cipher" # this is the first cipher for protocol - if ! "$FAST"; then - while true; do - $OPENSSL s_client $STARTTLS -"$p" $BUGS -cipher "ALL:$tested_cipher" -connect $NODEIP:$PORT $PROXY $sni >$ERRFILE >$TMPFILE - sclient_connect_successful $? $TMPFILE || break - cipher=$(awk '/Cipher *:/ { print $3 }' $TMPFILE) - out " $cipher" - order+=" $cipher" - tested_cipher="$tested_cipher:-$cipher" - done - fi + tested_cipher="" + while true; do + $OPENSSL s_client $STARTTLS -"$p" $BUGS -cipher "ALL:COMPLEMENTOFALL$tested_cipher" -connect $NODEIP:$PORT $PROXY $sni >$ERRFILE >$TMPFILE + sclient_connect_successful $? $TMPFILE || break + cipher=$(awk '/Cipher *:/ { print $3 }' $TMPFILE) + [[ -z "$cipher" ]] && break + order+=" $cipher" + tested_cipher+=":-"$cipher + "$FAST" && break + done fi fi - [[ -z "$order" ]] || fileout "order_$p" "INFO" "Default cipher order for protocol $p: $order" + + nr_nonossl_ciphers=0 + if "$using_sockets"; then + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + ciphers_found[i]=false + hexc="${TLS_CIPHER_HEXCODE[i]}" + if [[ ${#hexc} -eq 9 ]]; then + if [[ " $order " =~ " ${TLS_CIPHER_OSSL_NAME[i]} " ]]; then + ciphers_found[i]=true + else + ciphers_found2[nr_nonossl_ciphers]=false + hexcode[nr_nonossl_ciphers]="${hexc:2:2},${hexc:7:2}" + rfc_ciph[nr_nonossl_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" + index[nr_nonossl_ciphers]=$i + # Only test ciphers that are relevant to the protocol. + if [[ "$p" == "tls1_3" ]]; then + [[ "${hexc:2:2}" == "13" ]] && nr_nonossl_ciphers+=1 + elif [[ "$p" == "tls1_2" ]]; then + [[ "${hexc:2:2}" != "13" ]] && nr_nonossl_ciphers+=1 + elif [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA256" ]] && \ + [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA384" ]] && \ + [[ "${TLS_CIPHER_RFC_NAME[i]}" != *"_CCM" ]] && \ + [[ "${TLS_CIPHER_RFC_NAME[i]}" != *"_CCM_8" ]]; then + nr_nonossl_ciphers+=1 + fi + fi + fi + done + fi + + if [[ $nr_nonossl_ciphers -eq 0 ]]; then + num_bundles=0 + elif [[ $p != tls1_2 ]] || ! "$SERVER_SIZE_LIMIT_BUG"; then + num_bundles=1 + bundle_size=$nr_nonossl_ciphers + else + num_bundles=$nr_nonossl_ciphers/128 + mod_check=$nr_nonossl_ciphers%128 + [[ $mod_check -ne 0 ]] && num_bundles=$num_bundles+1 + + bundle_size=$nr_nonossl_ciphers/$num_bundles + mod_check=$nr_nonossl_ciphers%$num_bundles + [[ $mod_check -ne 0 ]] && bundle_size+=1 + fi + + for (( bundle=0; bundle < num_bundles; bundle++ )); do + end_of_bundle=$bundle*$bundle_size+$bundle_size + [[ $end_of_bundle -gt $nr_nonossl_ciphers ]] && end_of_bundle=$nr_nonossl_ciphers + while true; do + ciphers_to_test="" + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode[i]}" + done + [[ -z "$ciphers_to_test" ]] && break + tls_sockets "$proto_hex" "${ciphers_to_test:2}, 00,ff" "ephemeralkey" + [[ $? -ne 0 ]] && break + cipher=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + [[ "$cipher" == "${rfc_ciph[i]}" ]] && ciphers_found2[i]=true && break + done + i=${index[i]} + ciphers_found[i]=true + ciphers_found_with_sockets=true + if [[ $p != tls1_2 ]] || ! "$SERVER_SIZE_LIMIT_BUG"; then + # Throw out the results found so far and start over using just sockets + bundle=$num_bundles + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + ciphers_found[i]=true + done + break + fi + done + done + + # If additional ciphers were found using sockets and there is no + # SERVER_SIZE_LIMIT_BUG, then just use sockets to find the cipher order. + # If there is a SERVER_SIZE_LIMIT_BUG, then use sockets to find the cipher + # order, but starting with the list of ciphers supported by the server. + if "$ciphers_found_with_sockets"; then + order="" + nr_ciphers=0 + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + hexc="${TLS_CIPHER_HEXCODE[i]}" + if "${ciphers_found[i]}" && [[ ${#hexc} -eq 9 ]]; then + ciphers_found2[nr_ciphers]=false + hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2}" + rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" + if [[ "$p" == "tls1_3" ]]; then + [[ "${hexc:2:2}" == "13" ]] && nr_ciphers+=1 + elif [[ "$p" == "tls1_2" ]]; then + [[ "${hexc:2:2}" != "13" ]] && nr_ciphers+=1 + elif [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA256" ]] && \ + [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA384" ]] && \ + [[ "${TLS_CIPHER_RFC_NAME[i]}" != *"_CCM" ]] && \ + [[ "${TLS_CIPHER_RFC_NAME[i]}" != *"_CCM_8" ]]; then + nr_ciphers+=1 + fi + fi + done + while true; do + ciphers_to_test="" + for (( i=0; i < nr_ciphers; i++ )); do + ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode[i]}" + done + [[ -z "$ciphers_to_test" ]] && break + tls_sockets "$proto_hex" "${ciphers_to_test:2}, 00,ff" "ephemeralkey" + [[ $? -ne 0 ]] && break + cipher=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") + for (( i=0; i < nr_ciphers; i++ )); do + [[ "$cipher" == "${rfc_ciph[i]}" ]] && ciphers_found2[i]=true && break + done + cipher="$(rfc2openssl "$cipher")" + # If there is no OpenSSL name for the cipher, then use the RFC name + [[ -z "$cipher" ]] && cipher=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") + order+=" $cipher" + done + fi + + if [[ -n "$order" ]]; then + outln + printf " %-10s" "$proto: " + out "$order" + fileout "order_$p" "INFO" "Default cipher order for protocol $p: $order" + fi done outln @@ -4733,16 +5348,19 @@ sclient_connect_successful() { # ALPN extensions in the same ServerHello. determine_tls_extensions() { local addcmd - local -i success + local -i success=1 local line params="" tls_extensions="" local alpn_proto alpn="" alpn_list_len_hex alpn_extn_len_hex local -i alpn_list_len alpn_extn_len + local cbc_cipher_list="ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DH-RSA-AES256-SHA256:DH-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:ECDHE-RSA-CAMELLIA256-SHA384:ECDHE-ECDSA-CAMELLIA256-SHA384:DHE-RSA-CAMELLIA256-SHA256:DHE-DSS-CAMELLIA256-SHA256:DH-RSA-CAMELLIA256-SHA256:DH-DSS-CAMELLIA256-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:ECDH-RSA-CAMELLIA256-SHA384:ECDH-ECDSA-CAMELLIA256-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA256:CAMELLIA256-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DH-RSA-AES128-SHA256:DH-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:ECDHE-RSA-CAMELLIA128-SHA256:ECDHE-ECDSA-CAMELLIA128-SHA256:DHE-RSA-CAMELLIA128-SHA256:DHE-DSS-CAMELLIA128-SHA256:DH-RSA-CAMELLIA128-SHA256:DH-DSS-CAMELLIA128-SHA256:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:ECDH-RSA-CAMELLIA128-SHA256:ECDH-ECDSA-CAMELLIA128-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA256:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:EXP1024-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-DH-DSS-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA" + local cbc_cipher_list_hex="c0,28, c0,24, c0,14, c0,0a, 00,6b, 00,6a, 00,69, 00,68, 00,39, 00,38, 00,37, 00,36, c0,77, c0,73, 00,c4, 00,c3, 00,c2, 00,c1, 00,88, 00,87, 00,86, 00,85, c0,2a, c0,26, c0,0f, c0,05, c0,79, c0,75, 00,3d, 00,35, 00,c0, 00,84, c0,3d, c0,3f, c0,41, c0,43, c0,45, c0,49, c0,4b, c0,4d, c0,4f, c0,27, c0,23, c0,13, c0,09, 00,67, 00,40, 00,3f, 00,3e, 00,33, 00,32, 00,31, 00,30, c0,76, c0,72, 00,be, 00,bd, 00,bc, 00,bb, 00,9a, 00,99, 00,98, 00,97, 00,45, 00,44, 00,43, 00,42, c0,29, c0,25, c0,0e, c0,04, c0,78, c0,74, 00,3c, 00,2f, 00,ba, 00,96, 00,41, 00,07, c0,3c, c0,3e, c0,40, c0,42, c0,44, c0,48, c0,4a, c0,4c, c0,4e, c0,12, c0,08, 00,16, 00,13, 00,10, 00,0d, c0,0d, c0,03, 00,0a, fe,ff, ff,e0, 00,63, 00,15, 00,12, 00,0f, 00,0c, 00,62, 00,09, fe,fe, ff,e1, 00,14, 00,11, 00,08, 00,06, 00,0b, 00,0e" local using_sockets=true [[ "$OPTIMAL_PROTO" == "-ssl2" ]] && return 0 "$SSL_NATIVE" && using_sockets=false if "$using_sockets"; then + tls_extensions="00,01,00,01,02, 00,02,00,00, 00,04,00,00, 00,12,00,00, 00,16,00,00, 00,17,00,00" if [[ -z $STARTTLS ]]; then for alpn_proto in $ALPN_PROTOs; do alpn+=",$(printf "%02x" ${#alpn_proto}),$(string_to_asciihex "$alpn_proto")" @@ -4751,11 +5369,16 @@ determine_tls_extensions() { alpn_list_len_hex=$(printf "%04x" $alpn_list_len) alpn_extn_len=$alpn_list_len+2 alpn_extn_len_hex=$(printf "%04x" $alpn_extn_len) - tls_sockets "03" "$TLS12_CIPHER" "all" "00,01,00,01,02, 00,02,00,00, 00,04,00,00, 00,12,00,00, 00,16,00,00, 00,17,00,00, 00,10,${alpn_extn_len_hex:0:2},${alpn_extn_len_hex:2:2},${alpn_list_len_hex:0:2},${alpn_list_len_hex:2:2}$alpn" - else - tls_sockets "03" "$TLS12_CIPHER" "all" "00,01,00,01,02, 00,02,00,00, 00,04,00,00, 00,12,00,00, 00,16,00,00, 00,17,00,00" + tls_extensions+=", 00,10,${alpn_extn_len_hex:0:2},${alpn_extn_len_hex:2:2},${alpn_list_len_hex:0:2},${alpn_list_len_hex:2:2}$alpn" + fi + if [[ ! "$TLS_EXTENSIONS" =~ "encrypt-then-mac" ]]; then + tls_sockets "03" "$cbc_cipher_list_hex, 00,ff" "all" "$tls_extensions" + success=$? + fi + if [[ $success -ne 0 ]] && [[ $success -ne 2 ]]; then + tls_sockets "03" "$TLS12_CIPHER" "all" "$tls_extensions" + success=$? fi - success=$? [[ $success -eq 2 ]] && success=0 [[ $success -eq 0 ]] && tls_extensions="$(grep -a 'TLS Extensions: ' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" | sed 's/TLS Extensions: //' )" if [[ -r "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" ]]; then @@ -4768,17 +5391,23 @@ determine_tls_extensions() { elif "$HAS_SPDY" && [[ -z $STARTTLS ]]; then params="-nextprotoneg \"$NPN_PROTOs\"" fi - success=1 addcmd="" if [[ -z "$OPTIMAL_PROTO" ]] && [[ -z "$SNI" ]] && "$HAS_NO_SSL2"; then addcmd="-no_ssl2" elif [[ ! "$OPTIMAL_PROTO" =~ ssl ]]; then addcmd="$SNI" fi - $OPENSSL s_client $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd $OPTIMAL_PROTO -tlsextdebug $params $ERRFILE >$TMPFILE - sclient_connect_successful $? $TMPFILE - if [[ $? -eq 0 ]]; then - success=0 + if [[ ! "$TLS_EXTENSIONS" =~ "encrypt-then-mac" ]]; then + $OPENSSL s_client $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd $OPTIMAL_PROTO -tlsextdebug $params -cipher $cbc_cipher_list $ERRFILE >$TMPFILE + sclient_connect_successful $? $TMPFILE + success=$? + fi + if [[ $success -ne 0 ]]; then + $OPENSSL s_client $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd $OPTIMAL_PROTO -tlsextdebug $params $ERRFILE >$TMPFILE + sclient_connect_successful $? $TMPFILE + success=$? + fi + if [[ $success -eq 0 ]]; then tls_extensions=$(grep -a 'TLS server extension ' $TMPFILE | sed -e 's/TLS server extension //g' -e 's/\" (id=/\/#/g' -e 's/,.*$/,/g' -e 's/),$/\"/g') tls_extensions=$(echo $tls_extensions) # into one line fi @@ -5286,7 +5915,7 @@ certificate_info() { cnfinding="Common Name (CN) : " cn="$(get_cn_from_cert $HOSTCERT)" if [[ -n "$cn" ]]; then - pr_dquoted "$cn" + pr_italic "$cn" cnfinding="$cn" else cn="no CN field in subject" @@ -5324,7 +5953,7 @@ certificate_info() { outln ", (request w/o SNI: $cn_nosni)" cnfinding+=", (request w/o SNI: $cn_nosni)" else - out " (CN in response to request w/o SNI: "; pr_dquoted "$cn_nosni"; outln ")" + out " (CN in response to request w/o SNI: "; pr_italic "$cn_nosni"; outln ")" cnfinding+=" (CN in response to request w/o SNI: \"$cn_nosni\")" fi fileout "${json_prefix}cn" "$cnok" "$cnfinding" @@ -5338,7 +5967,7 @@ certificate_info() { out "$indent"; pr_bold " subjectAltName (SAN) " if [[ -n "$sans" ]]; then while read san; do - [[ -n "$san" ]] && pr_dquoted "$san" + [[ -n "$san" ]] && pr_italic "$san" out " " done <<< "$sans" fileout "${json_prefix}san" "INFO" "subjectAltName (SAN) : $sans" @@ -5359,7 +5988,7 @@ certificate_info() { pr_svrty_criticalln "self-signed (NOT ok)" fileout "${json_prefix}issuer" "CRITICAL" "Issuer: selfsigned" else - issuerfinding="$(pr_dquoted "$issuer_CN")" + issuerfinding="$(pr_italic "$issuer_CN")" if [[ -z "$issuer_O" ]] && [[ -n "$issuer_DC" ]]; then for san in $issuer_DC; do if [[ -z "$issuer_O" ]]; then @@ -5371,10 +6000,10 @@ certificate_info() { fi if [[ -n "$issuer_O" ]]; then issuerfinding+=" (" - issuerfinding+="$(pr_dquoted "$issuer_O")" + issuerfinding+="$(pr_italic "$issuer_O")" if [[ -n "$issuer_C" ]]; then issuerfinding+=" from " - issuerfinding+="$(pr_dquoted "$issuer_C")" + issuerfinding+="$(pr_italic "$issuer_C")" fi issuerfinding+=")" fi @@ -5539,11 +6168,19 @@ certificate_info() { out "$indent"; pr_bold " # of certificates provided"; outln " $certificates_provided" fileout "${json_prefix}certcount" "INFO" "# of certificates provided : $certificates_provided" + # Get both CRL and OCSP URL upfront. If there's none, this is not good. And we need to penalize this in the output + crl="$($OPENSSL x509 -in $HOSTCERT -noout -text 2>>$ERRFILE | awk '/CRL Distribution/,/URI/ { print $0 }' | awk -F'URI:' '/URI/ { print $2 }')" + ocsp_uri=$($OPENSSL x509 -in $HOSTCERT -noout -ocsp_uri 2>>$ERRFILE) + out "$indent"; pr_bold " Certificate Revocation List " - crl="$($OPENSSL x509 -in $HOSTCERT -noout -text 2>>$ERRFILE | grep -A 4 "CRL Distribution" | grep URI | sed 's/^.*URI://')" - if [[ -z "$crl" ]]; then - pr_svrty_highln "--" - fileout "${json_prefix}crl" "HIGH" "No CRL provided" + if [[ -z "$crl" ]] ; then + if [[ -n "$ocsp_uri" ]]; then + outln "--" + fileout "${json_prefix}crl" "INFO" "No CRL provided" + else + pr_svrty_highln "-- (NOT ok)" + fileout "${json_prefix}crl" "HIGH" "Neither CRL nor OCSP URL provided" + fi elif grep -q http <<< "$crl"; then if [[ $(count_lines "$crl") -eq 1 ]]; then outln "$crl" @@ -5558,10 +6195,9 @@ certificate_info() { fi out "$indent"; pr_bold " OCSP URI " - ocsp_uri=$($OPENSSL x509 -in $HOSTCERT -noout -ocsp_uri 2>>$ERRFILE) - if [[ -z "$ocsp_uri" ]]; then - pr_svrty_highln "--" - fileout "${json_prefix}ocsp_uri" "HIGH" "OCSP URI : --" + if [[ -z "$ocsp_uri" ]] && [[ -n "$crl" ]]; then + outln "--" + fileout "${json_prefix}ocsp_uri" "INFO" "OCSP URI : --" else outln "$ocsp_uri" fileout "${json_prefix}ocsp_uri" "INFO" "OCSP URI : $ocsp_uri" @@ -5588,8 +6224,19 @@ certificate_info() { fi fi fi - outln "\n" + outln + out "$indent"; pr_bold " DNS CAA RR"; out " (experimental) " + caa="$(get_caa_rr_record $NODE)" + if [[ -n "$caa" ]]; then + pr_done_good "OK"; out " (" ; pr_italic "$caa"; out ")" + fileout "${json_prefix}CAA_record" "OK" "DNS Certification Authority Authorization (CAA) Resource Record / RFC6844 : offered" + else + pr_svrty_minor "--" + fileout "${json_prefix}CAA_record" "LOW" "DNS Certification Authority Authorization (CAA) Resource Record / RFC6844 : not offered" + fi + + outln "\n" return $ret } # FIXME: revoked, see checkcert.sh @@ -5729,11 +6376,12 @@ run_server_defaults() { done determine_tls_extensions + if [[ $? -eq 0 ]] && [[ "$OPTIMAL_PROTO" != "-ssl2" ]]; then + cp "$TEMPDIR/$NODEIP.determine_tls_extensions.txt" $TMPFILE + >$ERRFILE - cp "$TEMPDIR/$NODEIP.determine_tls_extensions.txt" $TMPFILE - >$ERRFILE - - [[ -z "$sessticket_str" ]] && sessticket_str=$(grep -aw "session ticket" $TMPFILE | grep -a lifetime) + [[ -z "$sessticket_str" ]] && sessticket_str=$(grep -aw "session ticket" $TMPFILE | grep -a lifetime) + fi outln pr_headlineln " Testing server defaults (Server Hello) " @@ -5782,38 +6430,98 @@ run_server_defaults() { run_pfs() { local -i sclient_success - local pfs_offered=false ecdhe_offered=false - local tmpfile - local dhlen - local hexcode dash pfs_cipher sslvers kx auth enc mac curve - local pfs_cipher_list="$ROBUST_PFS_CIPHERS" - local ecdhe_cipher_list="" + local pfs_offered=false ecdhe_offered=false ffdhe_offered=false + local hexc dash pfs_cipher sslvers auth mac export curve dhlen + local -a hexcode normalized_hexcode ciph rfc_ciph kx enc ciphers_found sigalg ossl_supported + local pfs_cipher_list="$ROBUST_PFS_CIPHERS" pfs_hex_cipher_list="" ciphers_to_test + local ecdhe_cipher_list="" ecdhe_cipher_list_hex="" ffdhe_cipher_list_hex="" + local curves_hex=("00,01" "00,02" "00,03" "00,04" "00,05" "00,06" "00,07" "00,08" "00,09" "00,0a" "00,0b" "00,0c" "00,0d" "00,0e" "00,0f" "00,10" "00,11" "00,12" "00,13" "00,14" "00,15" "00,16" "00,17" "00,18" "00,19" "00,1a" "00,1b" "00,1c" "00,1d" "00,1e") local -a curves_ossl=("sect163k1" "sect163r1" "sect163r2" "sect193r1" "sect193r2" "sect233k1" "sect233r1" "sect239k1" "sect283k1" "sect283r1" "sect409k1" "sect409r1" "sect571k1" "sect571r1" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "prime192v1" "secp224k1" "secp224r1" "secp256k1" "prime256v1" "secp384r1" "secp521r1" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448") local -a curves_ossl_output=("K-163" "sect163r1" "B-163" "sect193r1" "sect193r2" "K-233" "B-233" "sect239k1" "K-283" "B-283" "K-409" "B-409" "K-571" "B-571" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "P-192" "secp224k1" "P-224" "secp256k1" "P-256" "P-384" "P-521" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448") - local -a supported_curves=() - local -i nr_supported_ciphers=0 nr_curves=0 i j low high - local pfs_ciphers curves_offered curves_to_test temp - local curve_found curve_used + local -a ffdhe_groups_hex=("01,00" "01,01" "01,02" "01,03" "01,04") + local -a ffdhe_groups_output=("ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192") + local -a supported_curve bits + local -i nr_supported_ciphers=0 nr_curves=0 nr_ossl_curves=0 i j low high + local pfs_ciphers curves_offered="" curves_offered_text="" curves_to_test temp + local len1 len2 curve_found + local has_dh_bits="$HAS_DH_BITS" + local using_sockets=true + + "$SSL_NATIVE" && using_sockets=false + "$FAST" && using_sockets=false + [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false outln pr_headlineln " Testing robust (perfect) forward secrecy, (P)FS -- omitting Null Authentication/Encryption, 3DES, RC4 " - if ! "$HAS_DH_BITS" && "$WIDE"; then - pr_warningln " (Your $OPENSSL cannot show DH/ECDH bits)" - fi - - nr_supported_ciphers=$(count_ciphers $(actually_supported_ciphers $pfs_cipher_list)) - debugme echo $nr_supported_ciphers - debugme echo $(actually_supported_ciphers $pfs_cipher_list) - if [[ "$nr_supported_ciphers" -le "$CLIENT_MIN_PFS" ]]; then + if ! "$using_sockets"; then + [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && pr_warning " Cipher mapping not available, doing a fallback to openssl" + if ! "$HAS_DH_BITS" && "$WIDE"; then + [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && out "." + pr_warning " (Your $OPENSSL cannot show DH/ECDH bits)" + fi outln - local_problem_ln "You only have $nr_supported_ciphers PFS ciphers on the client side " - fileout "pfs" "WARN" "(Perfect) Forward Secrecy tests: Skipped. You only have $nr_supported_ciphers PFS ciphers on the client site. ($CLIENT_MIN_PFS are required)" - return 1 fi - $OPENSSL s_client -cipher $pfs_cipher_list $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE $ERRFILE) + fi + export="" + + if "$using_sockets"; then + tls_sockets "03" "${pfs_hex_cipher_list:2}" + sclient_success=$? + [[ $sclient_success -eq 2 ]] && sclient_success=0 + else + debugme echo $nr_supported_ciphers + debugme echo $(actually_supported_ciphers $pfs_cipher_list) + if [[ "$nr_supported_ciphers" -le "$CLIENT_MIN_PFS" ]]; then + outln + local_problem_ln "You only have $nr_supported_ciphers PFS ciphers on the client side " + fileout "pfs" "WARN" "(Perfect) Forward Secrecy tests: Skipped. You only have $nr_supported_ciphers PFS ciphers on the client site. ($CLIENT_MIN_PFS are required)" + return 1 + fi + $OPENSSL s_client -cipher $pfs_cipher_list $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE $tmpfile $TMPFILE $ERRFILE) # -V doesn't work with openssl < 1.0 + done + debugme echo $pfs_offered "$WIDE" || outln - if ! "$pfs_offered"; then - pr_svrty_medium "WARN: no PFS ciphers found" - fileout "pfs_ciphers" "MEDIUM" "(Perfect) Forward Secrecy Ciphers: no PFS ciphers found" - else - fileout "pfs_ciphers" "INFO" "(Perfect) Forward Secrecy Ciphers: $pfs_ciphers" - fi + fileout "pfs_ciphers" "INFO" "(Perfect) Forward Secrecy Ciphers: $pfs_ciphers" fi + # find out what elliptic curves are supported. if "$ecdhe_offered"; then - # find out what elliptic curves are supported. - curves_offered="" for curve in "${curves_ossl[@]}"; do - $OPENSSL s_client -curves $curve 2>&1 | egrep -iaq "Error with command|unknown option" - [[ $? -ne 0 ]] && nr_curves+=1 && supported_curves+=("$curve") + ossl_supported[nr_curves]=false + supported_curve[nr_curves]=false + $OPENSSL s_client -curves $curve -connect x 2>&1 | egrep -iaq "Error with command|unknown option" + [[ $? -ne 0 ]] && ossl_supported[nr_curves]=true && nr_ossl_curves+=1 + nr_curves+=1 done # OpenSSL limits the number of curves that can be specified in the - # "-curves" option to 28. So, the list is broken in two since there - # are currently 30 curves defined. - for i in 1 2; do - case $i in - 1) low=0; high=$nr_curves/2 ;; - 2) low=$nr_curves/2; high=$nr_curves ;; - esac - sclient_success=0 - while [[ "$sclient_success" -eq 0 ]]; do - curves_to_test="" - for (( j=low; j < high; j++ )); do - [[ ! " $curves_offered " =~ " ${supported_curves[j]} " ]] && curves_to_test+=":${supported_curves[j]}" - done - if [[ -n "$curves_to_test" ]]; then - $OPENSSL s_client -cipher "${ecdhe_cipher_list:1}" -curves "${curves_to_test:1}" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI &>$tmpfile $TMPFILE $ERRFILE >$TMPFILE + if "$HAS_ALPN"; then + $OPENSSL s_client -connect $NODEIP:$PORT $BUGS $SNI -alpn $proto $ERRFILE >$TMPFILE + else + alpn_extn="$(printf "%02x" ${#proto}),$(string_to_asciihex "$proto")" + len="$(printf "%04x" $((${#proto}+1)))" + alpn_extn="${len:0:2},${len:2:2},$alpn_extn" + len="$(printf "%04x" $((${#proto}+3)))" + alpn_extn="00,10,${len:0:2},${len:2:2},$alpn_extn" + tls_sockets "03" "$TLS12_CIPHER" "all" "$alpn_extn" + if [[ -r "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" ]]; then + cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE + else + echo "" > $TMPFILE + fi + fi #tmpstr=$(grep -a '^ALPN protocol' $TMPFILE | sed 's/ALPN protocol.*: //') #tmpstr=$(awk '/^ALPN protocol*:/ { print $2 }' $TMPFILE) tmpstr=$(awk -F':' '/^ALPN protocol*:/ { print $2 }' $TMPFILE) @@ -6469,6 +7314,159 @@ get_pub_key_size() { return 0 } +# Extract the DH ephemeral key from the ServerKeyExchange message +get_dh_ephemeralkey() { + local tls_serverkeyexchange_ascii="$1" + local -i tls_serverkeyexchange_ascii_len offset + local dh_p dh_g dh_y dh_param len1 key_bitstring tmp_der_key_file + local -i i dh_p_len dh_g_len dh_y_len dh_param_len + + tls_serverkeyexchange_ascii_len=${#tls_serverkeyexchange_ascii} + dh_p_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:0:4}") + offset=4+$dh_p_len + if [[ $tls_serverkeyexchange_ascii_len -lt $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + + # Subtract any leading 0 bytes + for (( i=4; i < offset; i=i+2 )); do + [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break + dh_p_len=$dh_p_len-2 + done + if [[ $i -ge $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + dh_p="${tls_serverkeyexchange_ascii:i:dh_p_len}" + + dh_g_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:offset:4}") + i=4+$offset + offset+=4+$dh_g_len + if [[ $tls_serverkeyexchange_ascii_len -lt $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + # Subtract any leading 0 bytes + for (( 1; i < offset; i=i+2 )); do + [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break + dh_g_len=$dh_g_len-2 + done + if [[ $i -ge $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + dh_g="${tls_serverkeyexchange_ascii:i:dh_g_len}" + + dh_y_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:offset:4}") + i=4+$offset + offset+=4+$dh_y_len + if [[ $tls_serverkeyexchange_ascii_len -lt $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + # Subtract any leading 0 bytes + for (( 1; i < offset; i=i+2 )); do + [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break + dh_y_len=$dh_y_len-2 + done + if [[ $i -ge $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + dh_y="${tls_serverkeyexchange_ascii:i:dh_y_len}" + + # The following code assumes that all lengths can be encoded using at most 2 bytes, + # which just means that the encoded length of the public key must be less than + # 65,536 bytes. If the length is anywhere close to that, it is almost certainly an + # encoding error. + if [[ $dh_p_len+$dh_g_len+$dh_y_len -ge 131000 ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + # make ASN.1 INTEGER of p, g, and Y + [[ "0x${dh_p:0:1}" -ge 8 ]] && dh_p_len+=2 && dh_p="00$dh_p" + if [[ $dh_p_len -lt 256 ]]; then + len1="$(printf "%02x" $((dh_p_len/2)))" + elif [[ $dh_p_len -lt 512 ]]; then + len1="81$(printf "%02x" $((dh_p_len/2)))" + else + len1="82$(printf "%04x" $((dh_p_len/2)))" + fi + dh_p="02${len1}$dh_p" + + [[ "0x${dh_g:0:1}" -ge 8 ]] && dh_g_len+=2 && dh_g="00$dh_g" + if [[ $dh_g_len -lt 256 ]]; then + len1="$(printf "%02x" $((dh_g_len/2)))" + elif [[ $dh_g_len -lt 512 ]]; then + len1="81$(printf "%02x" $((dh_g_len/2)))" + else + len1="82$(printf "%04x" $((dh_g_len/2)))" + fi + dh_g="02${len1}$dh_g" + + [[ "0x${dh_y:0:1}" -ge 8 ]] && dh_y_len+=2 && dh_y="00$dh_y" + if [[ $dh_y_len -lt 256 ]]; then + len1="$(printf "%02x" $((dh_y_len/2)))" + elif [[ $dh_y_len -lt 512 ]]; then + len1="81$(printf "%02x" $((dh_y_len/2)))" + else + len1="82$(printf "%04x" $((dh_y_len/2)))" + fi + dh_y="02${len1}$dh_y" + + # Make a SEQUENCE of p and g + dh_param_len=${#dh_p}+${#dh_g} + if [[ $dh_param_len -lt 256 ]]; then + len1="$(printf "%02x" $((dh_param_len/2)))" + elif [[ $dh_param_len -lt 512 ]]; then + len1="81$(printf "%02x" $((dh_param_len/2)))" + else + len1="82$(printf "%04x" $((dh_param_len/2)))" + fi + dh_param="30${len1}${dh_p}${dh_g}" + + # Make a SEQUENCE of the paramters SEQUENCE and the OID + dh_param_len=22+${#dh_param} + if [[ $dh_param_len -lt 256 ]]; then + len1="$(printf "%02x" $((dh_param_len/2)))" + elif [[ $dh_param_len -lt 512 ]]; then + len1="81$(printf "%02x" $((dh_param_len/2)))" + else + len1="82$(printf "%04x" $((dh_param_len/2)))" + fi + dh_param="30${len1}06092A864886F70D010301${dh_param}" + + # Encapsulate public key, y, in a BIT STRING + dh_y_len=${#dh_y}+2 + if [[ $dh_y_len -lt 256 ]]; then + len1="$(printf "%02x" $((dh_y_len/2)))" + elif [[ $dh_y_len -lt 512 ]]; then + len1="81$(printf "%02x" $((dh_y_len/2)))" + else + len1="82$(printf "%04x" $((dh_y_len/2)))" + fi + dh_y="03${len1}00$dh_y" + + # Create the public key SEQUENCE + i=${#dh_param}+${#dh_y} + if [[ $i -lt 256 ]]; then + len1="$(printf "%02x" $((i/2)))" + elif [[ $i -lt 512 ]]; then + len1="81$(printf "%02x" $((i/2)))" + else + len1="82$(printf "%04x" $((i/2)))" + fi + key_bitstring="30${len1}${dh_param}${dh_y}" + tmp_der_key_file=$(mktemp $TEMPDIR/pub_key_der.XXXXXX) || return 1 + asciihex_to_binary_file "$key_bitstring" "$tmp_der_key_file" + key_bitstring="$($OPENSSL pkey -pubin -in $tmp_der_key_file -inform DER 2> $ERRFILE)" + rm $tmp_der_key_file + [[ -z "$key_bitstring" ]] && return 1 + out "$key_bitstring" + return 0 +} + # arg1: name of file with socket reply # arg2: true if entire server hello should be parsed parse_sslv2_serverhello() { @@ -6498,6 +7496,7 @@ parse_sslv2_serverhello() { "$parse_complete" && echo "======================================" > $TMPFILE v2_hello_ascii=$(hexdump -v -e '16/1 "%02X"' $1) + v2_hello_ascii="${v2_hello_ascii%%[!0-9A-F]*}" [[ "$DEBUG" -ge 5 ]] && echo "$v2_hello_ascii" if [[ -z "$v2_hello_ascii" ]]; then ret=0 # 1 line without any blanks: no server hello received @@ -6529,6 +7528,10 @@ parse_sslv2_serverhello() { echo "SSLv2 certificate length: 0x$v2_hello_cert_length" echo "SSLv2 cipher spec length: 0x$v2_hello_cipherspec_length" fi + + if "$parse_complete" && [[ 2*$(hex2dec "$v2_hello_length") -ne ${#v2_hello_ascii}-4 ]]; then + ret=7 + fi fi "$parse_complete" || return $ret @@ -6536,11 +7539,15 @@ parse_sslv2_serverhello() { rm -f $HOSTCERT $TEMPDIR/intermediatecerts.pem if [[ $ret -eq 3 ]]; then certificate_len=2*$(hex2dec "$v2_hello_cert_length") - + if [[ "$v2_cert_type" == "01" ]] && [[ "$v2_hello_cert_length" != "00" ]]; then tmp_der_certfile=$(mktemp $TEMPDIR/der_cert.XXXXXX) || return $ret asciihex_to_binary_file "${v2_hello_ascii:26:certificate_len}" "$tmp_der_certfile" - $OPENSSL x509 -inform DER -in $tmp_der_certfile -outform PEM -out $HOSTCERT + $OPENSSL x509 -inform DER -in $tmp_der_certfile -outform PEM -out $HOSTCERT 2>$ERRFILE + if [[ $? -ne 0 ]]; then + debugme echo "Malformed certificate in ServerHello." + return 1 + fi rm $tmp_der_certfile get_pub_key_size echo "======================================" >> $TMPFILE @@ -6657,7 +7664,7 @@ parse_tls_serverhello() { local process_full="$2" local tls_handshake_ascii="" tls_alert_ascii="" local -i tls_hello_ascii_len tls_handshake_ascii_len tls_alert_ascii_len msg_len - local tls_serverhello_ascii="" tls_certificate_ascii="" + local tls_serverhello_ascii="" tls_certificate_ascii="" local tls_serverkeyexchange_ascii="" tls_certificate_status_ascii="" local -i tls_serverhello_ascii_len=0 tls_certificate_ascii_len=0 local -i tls_serverkeyexchange_ascii_len=0 tls_certificate_status_ascii_len=0 @@ -6671,9 +7678,9 @@ parse_tls_serverhello() { local -i curve_type named_curve local -i dh_bits=0 msb mask local tmp_der_certfile tmp_pem_certfile hostcert_issuer="" ocsp_response="" - local len1 key_bitstring="" tmp_der_key_file - local dh_p dh_g dh_y dh_param ephemeral_param rfc7919_param - local -i dh_p_len dh_g_len dh_y_len dh_param_len + local key_bitstring="" + local dh_p ephemeral_param rfc7919_param + local -i dh_p_len TLS_TIME="" DETECTED_TLS_VERSION="" @@ -7374,137 +8381,11 @@ parse_tls_serverhello() { dh_bits=$dh_bits-1 done - dh_g_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:offset:4}") - i=4+$offset - offset+=4+$dh_g_len - if [[ $tls_serverkeyexchange_ascii_len -lt $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle $FUNCNAME.txt - return 1 - fi - # Subtract any leading 0 bytes - for (( 1; i < offset; i=i+2 )); do - [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break - dh_g_len=$dh_g_len-2 - done - if [[ $i -ge $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle $FUNCNAME.txt - return 1 - fi - dh_g="${tls_serverkeyexchange_ascii:i:dh_g_len}" - - dh_y_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:offset:4}") - i=4+$offset - offset+=4+$dh_y_len - if [[ $tls_serverkeyexchange_ascii_len -lt $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle $FUNCNAME.txt - return 1 - fi - # Subtract any leading 0 bytes - for (( 1; i < offset; i=i+2 )); do - [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break - dh_y_len=$dh_y_len-2 - done - if [[ $i -ge $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle $FUNCNAME.txt - return 1 - fi - dh_y="${tls_serverkeyexchange_ascii:i:dh_y_len}" - - # The following code assumes that all lengths can be encoded using at most 2 bytes, - # which just means that the encoded length of the public key must be less than - # 65,536 bytes. If the length is anywhere close to that, it is almost certainly an - # encoding error. - if [[ $dh_p_len+$dh_g_len+$dh_y_len -ge 131000 ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle $FUNCNAME.txt - return 1 - fi - # make ASN.1 INTEGER of p, g, and Y - [[ "0x${dh_p:0:1}" -ge 8 ]] && dh_p_len+=2 && dh_p="00$dh_p" - if [[ $dh_p_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_p_len/2)))" - elif [[ $dh_p_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_p_len/2)))" - else - len1="82$(printf "%04x" $((dh_p_len/2)))" - fi - dh_p="02${len1}$dh_p" - - [[ "0x${dh_g:0:1}" -ge 8 ]] && dh_g_len+=2 && dh_g="00$dh_g" - if [[ $dh_g_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_g_len/2)))" - elif [[ $dh_g_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_g_len/2)))" - else - len1="82$(printf "%04x" $((dh_g_len/2)))" - fi - dh_g="02${len1}$dh_g" - - [[ "0x${dh_y:0:1}" -ge 8 ]] && dh_y_len+=2 && dh_y="00$dh_y" - if [[ $dh_y_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_y_len/2)))" - elif [[ $dh_y_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_y_len/2)))" - else - len1="82$(printf "%04x" $((dh_y_len/2)))" - fi - dh_y="02${len1}$dh_y" - - # Make a SEQUENCE of p and g - dh_param_len=${#dh_p}+${#dh_g} - if [[ $dh_param_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_param_len/2)))" - elif [[ $dh_param_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_param_len/2)))" - else - len1="82$(printf "%04x" $((dh_param_len/2)))" - fi - dh_param="30${len1}${dh_p}${dh_g}" - - # Make a SEQUENCE of the paramters SEQUENCE and the OID - dh_param_len=22+${#dh_param} - if [[ $dh_param_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_param_len/2)))" - elif [[ $dh_param_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_param_len/2)))" - else - len1="82$(printf "%04x" $((dh_param_len/2)))" - fi - dh_param="30${len1}06092A864886F70D010301${dh_param}" - - # Encapsulate public key, y, in a BIT STRING - dh_y_len=${#dh_y}+2 - if [[ $dh_y_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_y_len/2)))" - elif [[ $dh_y_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_y_len/2)))" - else - len1="82$(printf "%04x" $((dh_y_len/2)))" - fi - dh_y="03${len1}00$dh_y" - - # Create the public key SEQUENCE - i=${#dh_param}+${#dh_y} - if [[ $i -lt 256 ]]; then - len1="$(printf "%02x" $((i/2)))" - elif [[ $i -lt 512 ]]; then - len1="81$(printf "%02x" $((i/2)))" - else - len1="82$(printf "%04x" $((i/2)))" - fi - key_bitstring="30${len1}${dh_param}${dh_y}" - tmp_der_key_file=$(mktemp $TEMPDIR/pub_key_der.XXXXXX) || return 1 - asciihex_to_binary_file "$key_bitstring" "$tmp_der_key_file" - key_bitstring="$($OPENSSL pkey -pubin -in $tmp_der_key_file -inform DER 2> $ERRFILE)" - rm $tmp_der_key_file - [[ -n "$key_bitstring" ]] && echo "$key_bitstring" >> $TMPFILE + key_bitstring="$(get_dh_ephemeralkey "$tls_serverkeyexchange_ascii")" + [[ $? -eq 0 ]] && echo "$key_bitstring" >> $TMPFILE # Check to see whether the ephemeral public key uses one of the groups from - # RFC 7919 for parameters + # RFC 7919 for parameters case $dh_bits in 2048) named_curve=256; named_curve_str=" ffdhe2048," ;; 3072) named_curve=257; named_curve_str=" ffdhe3072," ;; @@ -7535,6 +8416,13 @@ sslv2_sockets() { local ret local client_hello cipher_suites len_client_hello local len_ciph_suites_byte len_ciph_suites + local server_hello sock_reply_file2 + local -i response_len server_hello_len + local parse_complete=false + + if [[ "$2" == "true" ]]; then + parse_complete=true + fi if [[ -n "$1" ]]; then cipher_suites="$1" @@ -7575,13 +8463,31 @@ sslv2_sockets() { socksend_sslv2_clienthello "$client_hello" sockread_serverhello 32768 + if "$parse_complete"; then + server_hello=$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE") + server_hello_len=2+$(hex2dec "${server_hello:1:3}") + response_len=$(wc -c "$SOCK_REPLY_FILE" | awk '{ print $1 }') + for (( 1; response_len < server_hello_len; 1 )); do + sock_reply_file2=$(mktemp $TEMPDIR/ddreply.XXXXXX) || return 7 + mv "$SOCK_REPLY_FILE" "$sock_reply_file2" + + debugme echo "requesting more server hello data..." + socksend "" $USLEEP_SND + sockread_serverhello 32768 + + [[ ! -s "$SOCK_REPLY_FILE" ]] && break + cat "$SOCK_REPLY_FILE" >> "$sock_reply_file2" + mv "$sock_reply_file2" "$SOCK_REPLY_FILE" + response_len=$(wc -c "$SOCK_REPLY_FILE" | awk '{ print $1 }') + done + fi debugme outln "reading server hello... " if [[ "$DEBUG" -ge 4 ]]; then hexdump -C "$SOCK_REPLY_FILE" | head -6 outln fi - parse_sslv2_serverhello "$SOCK_REPLY_FILE" "$2" + parse_sslv2_serverhello "$SOCK_REPLY_FILE" "$parse_complete" ret=$? close_socket @@ -7594,6 +8500,7 @@ sslv2_sockets() { # ARG1: TLS version low byte (00: SSLv3, 01: TLS 1.0, 02: TLS 1.1, 03: TLS 1.2) # ARG2: CIPHER_SUITES string # ARG3: (optional) additional request extensions +# ARG4: (optional): "true" if ClientHello should advertise compression methods other than "NULL" socksend_tls_clienthello() { local tls_low_byte="$1" local tls_word_reclayer="03, 01" # the first TLS version number is the record layer and always 0301 -- except: SSLv3 @@ -7609,6 +8516,10 @@ socksend_tls_clienthello() { local extension_session_ticket extension_next_protocol extension_padding local extension_supported_groups="" extension_supported_point_formats="" local extra_extensions extra_extensions_list="" + local offer_compression=false compression_metods + + # TLSv1.3 ClientHello messages MUST specify only the NULL compression method. + [[ "$4" == "true" ]] && [[ "0x$tls_low_byte" -le "0x03" ]] && offer_compression=true code2network "$(tolower "$2")" # convert CIPHER_SUITES cipher_suites="$NW_STR" # we don't have the leading \x here so string length is two byte less, see next @@ -7698,7 +8609,7 @@ socksend_tls_clienthello() { 00, 01, 00, 02, 00, 03, 00, 0f, 00, 10, 00, 11" # Supported Point Formats Extension extension_supported_point_formats=" - 00, 0b, # Type: Supported Point Formats , see RFC 4492 + 00, 0b, # Type: Supported Point Formats , see RFC 4492 00, 02, # len 01, 00" fi @@ -7772,6 +8683,7 @@ socksend_tls_clienthello() { # If the length of the Client Hello would be between 256 and 511 bytes, # then add a padding extension (see RFC 7685) len_all=$((0x$len_ciph_suites + 0x2b + 0x$len_extension_hex + 0x2)) + "$offer_compression" && len_all+=2 if [[ $len_all -ge 256 ]] && [[ $len_all -le 511 ]] && [[ ! "$extra_extensions_list" =~ " 0015 " ]]; then if [[ $len_all -gt 508 ]]; then len_padding_extension=0 @@ -7796,24 +8708,35 @@ socksend_tls_clienthello() { # RFC 3546 doesn't specify SSLv3 to have SNI, openssl just ignores the switch if supplied if [[ "$tls_low_byte" == "00" ]]; then - len2twobytes $(printf "%02x\n" $((0x$len_ciph_suites + 0x27))) + len_all=$((0x$len_ciph_suites + 0x27)) else - len2twobytes $(printf "%02x\n" $((0x$len_ciph_suites + 0x27 + 0x$len_extension_hex + 0x2))) + len_all=$((0x$len_ciph_suites + 0x27 + 0x$len_extension_hex + 0x2)) fi + "$offer_compression" && len_all+=2 + len2twobytes $(printf "%02x\n" $len_all) len_client_hello_word="$LEN_STR" #[[ $DEBUG -ge 3 ]] && echo $len_client_hello_word if [[ "$tls_low_byte" == "00" ]]; then - len2twobytes $(printf "%02x\n" $((0x$len_ciph_suites + 0x2b))) + len_all=$((0x$len_ciph_suites + 0x2b)) else - len2twobytes $(printf "%02x\n" $((0x$len_ciph_suites + 0x2b + 0x$len_extension_hex + 0x2))) + len_all=$((0x$len_ciph_suites + 0x2b + 0x$len_extension_hex + 0x2)) fi + "$offer_compression" && len_all+=2 + len2twobytes $(printf "%02x\n" $len_all) len_all_word="$LEN_STR" #[[ $DEBUG -ge 3 ]] && echo $len_all_word # if we have SSLv3, the first occurence of TLS protocol -- record layer -- is SSLv3, otherwise TLS 1.0 [[ $tls_low_byte == "00" ]] && tls_word_reclayer="03, 00" + if "$offer_compression"; then + # See http://www.iana.org/assignments/comp-meth-ids/comp-meth-ids.xhtml#comp-meth-ids-2 + compression_metods="03,01,40,00" # Offer NULL, DEFLATE, and LZS compression + else + compression_metods="01,00" # Only offer NULL compression (0x00) + fi + TLS_CLIENT_HELLO=" # TLS header ( 5 bytes) ,16, $tls_word_reclayer # TLS Version: in wireshark this is always 01 for TLS 1.0-1.2 @@ -7830,8 +8753,7 @@ socksend_tls_clienthello() { ,00 # Session ID length ,$len_ciph_suites_word # Cipher suites length ,$cipher_suites - ,01 # Compression methods length - ,00" # Compression method (x00 for NULL) + ,$compression_metods" fd_socket 5 || return 6 @@ -7850,6 +8772,7 @@ socksend_tls_clienthello() { # arg3: (optional): "all" - process full response (including Certificate and certificate_status handshake messages) # "ephemeralkey" - extract the server's ephemeral key (if any) # arg4: (optional) additional request extensions +# arg5: (optional) "true" if ClientHello should advertise compression methods other than "NULL" tls_sockets() { local -i ret=0 local -i save=0 @@ -7858,8 +8781,9 @@ tls_sockets() { local cipher_list_2send local sock_reply_file2 sock_reply_file3 local tls_hello_ascii next_packet hello_done=0 - local process_full="$3" + local process_full="$3" offer_compression=false + [[ "$5" == "true" ]] && offer_compression=true tls_low_byte="$1" if [[ -n "$2" ]]; then # use supplied string in arg2 if there is one cipher_list_2send="$2" @@ -7872,7 +8796,7 @@ tls_sockets() { fi debugme echo "sending client hello..." - socksend_tls_clienthello "$tls_low_byte" "$cipher_list_2send" "$4" + socksend_tls_clienthello "$tls_low_byte" "$cipher_list_2send" "$4" "$offer_compression" ret=$? # 6 means opening socket didn't succeed, e.g. timeout # if sending didn't succeed we don't bother @@ -7958,7 +8882,7 @@ tls_sockets() { fi debugme outln else - debugme "stuck on sending: $ret" + debugme echo "stuck on sending: $ret" fi close_socket @@ -8271,7 +9195,7 @@ run_ccs_injection(){ fi ret=1 fi - [[ $retval -eq 3 ]] && out " (timed out)" + [[ $retval -eq 3 ]] && out ", timed out" outln close_socket @@ -8349,7 +9273,7 @@ run_renego() { echo R | $OPENSSL s_client $OPTIMAL_PROTO $BUGS $legacycmd $STARTTLS -msg -connect $NODEIP:$PORT $addcmd $PROXY >$TMPFILE 2>>$ERRFILE & wait_kill $! $HEADER_MAXSLEEP if [[ $? -eq 3 ]]; then - pr_done_good "likely not vulnerable (OK)"; outln " (timed out)" # it hung + pr_done_good "likely not vulnerable (OK)"; outln ", timed out" # it hung fileout "sec_client_renego" "OK" "Secure Client-Initiated Renegotiation : likely not vulnerable (timed out)" "$cve" "$cwe" sec_client_renego=1 else @@ -8385,7 +9309,7 @@ run_renego() { } run_crime() { - local -i ret=0 + local -i ret=0 sclient_success local addcmd="" local cve="CVE-2012-4929" local cwe="CWE-310" @@ -8403,14 +9327,30 @@ run_crime() { # first we need to test whether OpenSSL binary has zlib support $OPENSSL zlib -e -a -in /dev/stdin &>/dev/stdout $TMPFILE + sclient_connect_successful $? $TMPFILE + sclient_success=$? fi - - [[ "$OSSL_VER" == "0.9.8"* ]] && addcmd="-no_ssl2" - $OPENSSL s_client $OPTIMAL_PROTO $BUGS $addcmd $STARTTLS -connect $NODEIP:$PORT $PROXY $SNI $TMPFILE - if grep -a Compression $TMPFILE | grep -aq NONE >/dev/null; then + if [[ $sclient_success -ne 0 ]]; then + pr_warning "test failed (couldn't connect)" + fileout "crime" "WARN" "CRIME, TLS: Check failed. (couldn't connect)" "$cve" "$cwe" + ret=7 + elif grep -a Compression $TMPFILE | grep -aq NONE >/dev/null; then pr_done_good "not vulnerable (OK)" if [[ $SERVICE != "HTTP" ]] && ! $CLIENT_AUTH; then out " (not using HTTP anyway)" @@ -8538,27 +9478,51 @@ run_breach() { # Padding Oracle On Downgraded Legacy Encryption, in a nutshell: don't use CBC Ciphers in SSLv3 run_ssl_poodle() { local -i sclient_success=0 - local cbc_ciphers="ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:DHE-PSK-AES256-CBC-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:AECDH-AES256-SHA:ADH-AES256-SHA:ADH-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-SHA:ECDHE-PSK-AES256-CBC-SHA:CAMELLIA256-SHA:RSA-PSK-AES256-CBC-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:AECDH-AES128-SHA:ADH-AES128-SHA:ADH-SEED-SHA:ADH-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-SHA:ECDHE-PSK-AES128-CBC-SHA:DHE-PSK-AES128-CBC-SHA:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:IDEA-CBC-MD5:RC2-CBC-MD5:RSA-PSK-AES128-CBC-SHA:PSK-AES128-CBC-SHA:KRB5-IDEA-CBC-SHA:KRB5-IDEA-CBC-MD5:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:AECDH-DES-CBC3-SHA:ADH-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:DES-CBC3-MD5:RSA-PSK-3DES-EDE-CBC-SHA:PSK-3DES-EDE-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-DES-CBC3-MD5:ECDHE-PSK-3DES-EDE-CBC-SHA:DHE-PSK-3DES-EDE-CBC-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:ADH-DES-CBC-SHA:EXP1024-DES-CBC-SHA:DES-CBC-SHA:DES-CBC-MD5:KRB5-DES-CBC-SHA:KRB5-DES-CBC-MD5:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-ADH-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC2-CBC-MD5:EXP-KRB5-RC2-CBC-SHA:EXP-KRB5-DES-CBC-SHA:EXP-KRB5-RC2-CBC-MD5:EXP-KRB5-DES-CBC-MD5" + local cbc_ciphers="ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:DHE-PSK-AES256-CBC-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:AECDH-AES256-SHA:ADH-AES256-SHA:ADH-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-SHA:ECDHE-PSK-AES256-CBC-SHA:CAMELLIA256-SHA:RSA-PSK-AES256-CBC-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:AECDH-AES128-SHA:ADH-AES128-SHA:ADH-SEED-SHA:ADH-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-SHA:ECDHE-PSK-AES128-CBC-SHA:DHE-PSK-AES128-CBC-SHA:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:RSA-PSK-AES128-CBC-SHA:PSK-AES128-CBC-SHA:KRB5-IDEA-CBC-SHA:KRB5-IDEA-CBC-MD5:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:AECDH-DES-CBC3-SHA:ADH-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:RSA-PSK-3DES-EDE-CBC-SHA:PSK-3DES-EDE-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-DES-CBC3-MD5:ECDHE-PSK-3DES-EDE-CBC-SHA:DHE-PSK-3DES-EDE-CBC-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:ADH-DES-CBC-SHA:EXP1024-DES-CBC-SHA:DES-CBC-SHA:KRB5-DES-CBC-SHA:KRB5-DES-CBC-MD5:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-ADH-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-KRB5-RC2-CBC-SHA:EXP-KRB5-DES-CBC-SHA:EXP-KRB5-RC2-CBC-MD5:EXP-KRB5-DES-CBC-MD5:EXP-DH-DSS-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA" + local cbc_ciphers_hex="c0,14, c0,0a, c0,22, c0,21, c0,20, 00,91, 00,39, 00,38, 00,37, 00,36, 00,88, 00,87, 00,86, 00,85, c0,19, 00,3a, 00,89, c0,0f, c0,05, 00,35, c0,36, 00,84, 00,95, 00,8d, c0,13, c0,09, c0,1f, c0,1e, c0,1d, 00,33, 00,32, 00,31, 00,30, 00,9a, 00,99, 00,98, 00,97, 00,45, 00,44, 00,43, 00,42, c0,18, 00,34, 00,9b, 00,46, c0,0e, c0,04, 00,2f, c0,35, 00,90, 00,96, 00,41, 00,07, 00,94, 00,8c, 00,21, 00,25, c0,12, c0,08, c0,1c, c0,1b, c0,1a, 00,16, 00,13, 00,10, 00,0d, c0,17, 00,1b, c0,0d, c0,03, 00,0a, 00,93, 00,8b, 00,1f, 00,23, c0,34, 00,8f, 00,63, 00,15, 00,12, 00,0f, 00,0c, 00,1a, 00,62, 00,09, 00,1e, 00,22, 00,14, 00,11, 00,19, 00,08, 00,06, 00,27, 00,26, 00,2a, 00,29, 00,0b, 00,0e" local cve="CVE-2014-3566" local cwe="CWE-310" local hint="" + local -i nr_cbc_ciphers=0 + local using_sockets=true [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for SSLv3 POODLE (Padding Oracle On Downgraded Legacy Encryption) " && outln pr_bold " POODLE, SSL"; out " ($cve) " - locally_supported "-ssl3" || return 0 - cbc_ciphers=$(actually_supported_ciphers $cbc_ciphers) - debugme echo $cbc_ciphers - $OPENSSL s_client -ssl3 $STARTTLS $BUGS -cipher $cbc_ciphers -connect $NODEIP:$PORT $PROXY >$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TEMPDIR/dh_p.txt + if [[ ! -s "$common_primes_file" ]]; then + local_problem_ln "couldn't read common primes file $common_primes_file" + out "${spaces}" + fileout "LOGJAM_common primes" "WARN" "couldn't read common primes file $common_primes_file" + ret=7 + else + dh_p="$(toupper "$dh_p")" + # In the previous line of the match is bascially the hint we want to echo + # the most elegant thing to get the previous line [ awk '/regex/ { print x }; { x=$0 }' ] doesn't work with GNU grep + lineno_matched=$(grep -n "$dh_p" "$common_primes_file" 2>/dev/null | awk -F':' '{ print $1 }') + if [[ "$lineno_matched" -ne 0 ]]; then + comment="$(awk "NR == $lineno_matched-1" "$common_primes_file" | awk -F'"' '{ print $2 }')" + ret=1 # vulnerable: common prime + else + ret=0 # not vulnerable: no known common prime + fi + fi + else + ret=3 # no DH key detected + fi + + # now the final verdict + # we only use once the color here on the screen, so screen and fileout SEEM to be inconsistent + if "$vuln_exportdh_ciphers"; then + pr_svrty_high "VULNERABLE (NOT ok):"; out " uses DH EXPORT ciphers" + fileout "logjam" "HIGH" "LOGJAM: VULNERABLE, uses DH EXPORT ciphers" "$cve" "$cwe" "$hint" + if [[ $ret -eq 3 ]]; then + out ", no DH key detected" + fileout "LOGJAM_common primes" "OK" "no DH key detected" + elif [[ $ret -eq 1 ]]; then + out "\n${spaces}" + # now size matters -- i.e. the bit size ;-) + if [[ $len_dh_p -le 512 ]]; then + pr_svrty_critical "VULNERABLE (NOT ok):"; out " common prime \"$comment\" detected ($len_dh_p bits)" + fileout "LOGJAM_common primes" "CRITICAL" "common prime \"$comment\" detected" + elif [[ $len_dh_p -le 1024 ]]; then + pr_svrty_high "VULNERABLE (NOT ok):"; out " common prime \"$comment\" detected ($len_dh_p bits)" + fileout "LOGJAM_common primes" "HIGH" "common prime \"$comment\" detected" + elif [[ $len_dh_p -le 1536 ]]; then + pr_svrty_medium "common prime with $len_dh_p bits detected: \"$comment\"" + fileout "LOGJAM_common primes" "MEDIUM" "common prime \"$comment\" detected" + elif [[ $len_dh_p -le 2048 ]]; then + pr_svrty_minor "common prime with $len_dh_p bits detected: \"$comment\"" + fileout "LOGJAM_common primes" "LOW" "common prime \"$comment\" detected" + else + out "common prime with $len_dh_p bits detected: \"$comment\"" + fileout "LOGJAM_common primes" "INFO" "common prime \"$comment\" detected" + fi + elif [[ $ret -eq 0 ]]; then + out " no common primes detected" + fileout "LOGJAM_common primes" "INFO" "no common primes detected" + elif [[ $ret -eq 7 ]]; then + out "FIXME 1" + fi + else + if [[ $ret -eq 1 ]]; then + # now size matters -- i.e. the bit size ;-) + if [[ $len_dh_p -le 512 ]]; then + pr_svrty_critical "VULNERABLE (NOT ok):" ; out " uses common prime \"$comment\" ($len_dh_p bits)" + fileout "LOGJAM_common primes" "CRITICAL" "common prime \"$comment\" detected" + elif [[ $len_dh_p -le 1024 ]]; then + pr_svrty_high "VULNERABLE (NOT ok):"; out " common prime \"$comment\" detected ($len_dh_p bits)" + fileout "LOGJAM_common primes" "HIGH" "common prime \"$comment\" detected" + elif [[ $len_dh_p -le 1536 ]]; then + pr_svrty_medium "Common prime with $len_dh_p bits detected: \"$comment\"" + fileout "LOGJAM_common primes" "MEDIUM" "common prime \"$comment\" detected" + elif [[ $len_dh_p -le 2048 ]]; then + pr_svrty_minor "Common prime with $len_dh_p bits detected: \"$comment\"" + fileout "LOGJAM_common primes" "LOW" "common prime \"$comment\" detected" + else + out "Common prime with $len_dh_p bits detected: \"$comment\"" + fileout "LOGJAM_common primes" "INFO" "common prime \"$comment\" detected" + fi + out ", but no DH EXPORT ciphers${addtl_warning}" + fileout "logjam" "OK" "LOGJAM: not vulnerable, no DH EXPORT ciphers, $addtl_warning" "$cve" "$cwe" + elif [[ $ret -eq 3 ]]; then + pr_done_good "not vulnerable (OK):"; out " no DH EXPORT ciphers${addtl_warning}" + fileout "logjam" "OK" "LOGJAM: not vulnerable, no DH EXPORT ciphers, $addtl_warning" "$cve" "$cwe" + out ", no DH key detected" + fileout "LOGJAM_common primes" "OK" "no DH key detected" + elif [[ $ret -eq 0 ]]; then + pr_done_good "not vulnerable (OK):"; out " no DH EXPORT ciphers${ddtl_warning}" + fileout "logjam" "OK" "LOGJAM: not vulnerable, no DH EXPORT ciphers, $addtl_warning" "$cve" "$cwe" + out ", no common primes detected" + fileout "LOGJAM_common primes" "OK" "no common primes detected" + elif [[ $ret -eq 7 ]]; then + pr_done_good "partly not vulnerable:"; out " no DH EXPORT ciphers${ddtl_warning}" + fileout "logjam" "OK" "LOGJAM: not vulnerable, no DH EXPORT ciphers, $addtl_warning" "$cve" "$cwe" + fi fi outln - - debugme echo $(actually_supported_ciphers $exportdhe_cipher_list) - debugme echo $nr_supported_ciphers - tmpfile_handle $FUNCNAME.txt - return $sclient_success + return 0 } -# TODO: perfect candidate for replacement by sockets, so is freak run_drown() { @@ -8767,7 +9924,7 @@ run_drown() { outln fi # if we want to use OPENSSL: check for < openssl 1.0.2g, openssl 1.0.1s if native openssl - pr_bold " DROWN"; out " ($cve) " + pr_bold " DROWN"; out " ($cve) " sslv2_sockets case $? in @@ -8811,7 +9968,11 @@ run_drown() { # not advertising it as it after 5 tries and account is needed cert_fingerprint_sha2=${cert_fingerprint_sha2/SHA256 /} outln "$spaces https://censys.io/ipv4?q=$cert_fingerprint_sha2 could help you to find out" + fileout "drown" "INFO" "make sure you don't use this certificate elsewhere with SSLv2 enabled services, see https://censys.io/ipv4?q=$cert_fingerprint_sha2" fi + else + outln "$spaces no RSA certificate, thus certificate can't be used with SSLv2 elsewhere" + fileout "drown" "INFO" "no RSA certificate, thus certificate can't be used with SSLv2 elsewhere" fi ret=0 ;; @@ -8824,18 +9985,21 @@ run_drown() { # Browser Exploit Against SSL/TLS: don't use CBC Ciphers in SSLv3 TLSv1.0 run_beast(){ - local hexcode dash cbc_cipher sslvers kx auth enc mac export addcmd - local detected_proto - local -i sclient_success=0 - local detected_cbc_ciphers="" + local hexc dash cbc_cipher sslvers auth mac export sni + local -a ciph hexcode normalized_hexcode kx enc export2 + local proto proto_hex + local -i i nr_ciphers=0 sclient_success=0 + local detected_cbc_ciphers="" ciphers_to_test local higher_proto_supported="" - local -i sclient_success=0 local vuln_beast=false local spaces=" " local cr=$'\n' local first=true local continued=false - local cbc_cipher_list="EXP-RC2-CBC-MD5:IDEA-CBC-SHA:EXP-DES-CBC-SHA:DES-CBC-SHA:DES-CBC3-SHA:EXP-DH-DSS-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:DH-DSS-DES-CBC3-SHA:EXP-DH-RSA-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-RSA-DES-CBC3-SHA:EXP-EDH-DSS-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:EDH-DSS-DES-CBC3-SHA:EXP-EDH-RSA-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EXP-ADH-DES-CBC-SHA:ADH-DES-CBC-SHA:ADH-DES-CBC3-SHA:KRB5-DES-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-IDEA-CBC-SHA:KRB5-DES-CBC-MD5:KRB5-DES-CBC3-MD5:KRB5-IDEA-CBC-MD5:EXP-KRB5-DES-CBC-SHA:EXP-KRB5-RC2-CBC-SHA:EXP-KRB5-DES-CBC-MD5:EXP-KRB5-RC2-CBC-MD5:AES128-SHA:DH-DSS-AES128-SHA:DH-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DHE-RSA-AES128-SHA:ADH-AES128-SHA:AES256-SHA:DH-DSS-AES256-SHA:DH-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ADH-AES256-SHA:AES128-SHA256:AES256-SHA256:DH-DSS-AES128-SHA256:DH-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DHE-RSA-CAMELLIA128-SHA:ADH-CAMELLIA128-SHA:EXP1024-DES-CBC-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:DHE-RSA-AES128-SHA256:DH-DSS-AES256-SHA256:DH-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-SHA256:ADH-AES128-SHA256:ADH-AES256-SHA256:CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DHE-RSA-CAMELLIA256-SHA:ADH-CAMELLIA256-SHA:PSK-3DES-EDE-CBC-SHA:PSK-AES128-CBC-SHA:PSK-AES256-CBC-SHA:SEED-SHA:DH-DSS-SEED-SHA:DH-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DHE-RSA-SEED-SHA:ADH-SEED-SHA:ECDH-ECDSA-DES-CBC3-SHA:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AECDH-DES-CBC3-SHA:AECDH-AES128-SHA:AECDH-AES256-SHA:SRP-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-DSS-AES-256-CBC-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDH-ECDSA-AES128-SHA256:ECDH-ECDSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDH-RSA-AES128-SHA256:ECDH-RSA-AES256-SHA384:RC2-CBC-MD5:EXP-RC2-CBC-MD5:IDEA-CBC-MD5:DES-CBC-MD5:DES-CBC3-MD5" + local cbc_cipher_list="ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:DHE-PSK-AES256-CBC-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:AECDH-AES256-SHA:ADH-AES256-SHA:ADH-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-SHA:ECDHE-PSK-AES256-CBC-SHA:CAMELLIA256-SHA:RSA-PSK-AES256-CBC-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:AECDH-AES128-SHA:ADH-AES128-SHA:ADH-SEED-SHA:ADH-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-SHA:ECDHE-PSK-AES128-CBC-SHA:DHE-PSK-AES128-CBC-SHA:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:RSA-PSK-AES128-CBC-SHA:PSK-AES128-CBC-SHA:KRB5-IDEA-CBC-SHA:KRB5-IDEA-CBC-MD5:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:AECDH-DES-CBC3-SHA:ADH-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:RSA-PSK-3DES-EDE-CBC-SHA:PSK-3DES-EDE-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-DES-CBC3-MD5:ECDHE-PSK-3DES-EDE-CBC-SHA:DHE-PSK-3DES-EDE-CBC-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:ADH-DES-CBC-SHA:EXP1024-DES-CBC-SHA:DES-CBC-SHA:KRB5-DES-CBC-SHA:KRB5-DES-CBC-MD5:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-ADH-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-KRB5-RC2-CBC-SHA:EXP-KRB5-DES-CBC-SHA:EXP-KRB5-RC2-CBC-MD5:EXP-KRB5-DES-CBC-MD5:EXP-DH-DSS-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA" + local cbc_ciphers_hex="c0,14, c0,0a, c0,22, c0,21, c0,20, 00,91, 00,39, 00,38, 00,37, 00,36, 00,88, 00,87, 00,86, 00,85, c0,19, 00,3a, 00,89, c0,0f, c0,05, 00,35, c0,36, 00,84, 00,95, 00,8d, c0,13, c0,09, c0,1f, c0,1e, c0,1d, 00,33, 00,32, 00,31, 00,30, 00,9a, 00,99, 00,98, 00,97, 00,45, 00,44, 00,43, 00,42, c0,18, 00,34, 00,9b, 00,46, c0,0e, c0,04, 00,2f, c0,35, 00,90, 00,96, 00,41, 00,07, 00,94, 00,8c, 00,21, 00,25, c0,12, c0,08, c0,1c, c0,1b, c0,1a, 00,16, 00,13, 00,10, 00,0d, c0,17, 00,1b, c0,0d, c0,03, 00,0a, 00,93, 00,8b, 00,1f, 00,23, c0,34, 00,8f, 00,63, 00,15, 00,12, 00,0f, 00,0c, 00,1a, 00,62, 00,09, 00,1e, 00,22, 00,14, 00,11, 00,19, 00,08, 00,06, 00,27, 00,26, 00,2a, 00,29, 00,0b, 00,0e" + local has_dh_bits="$HAS_DH_BITS" + local using_sockets=true local cve="CVE-2011-3389" local cwe="CWE-20" local hint="" @@ -8848,9 +10012,48 @@ run_beast(){ outln fi pr_bold " BEAST"; out " ($cve) " -# output in wide mode if cipher doesn't exist is not ok - >$ERRFILE + "$SSL_NATIVE" && using_sockets=false + [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false + if "$using_sockets" || [[ $OSSL_VER_MAJOR -lt 1 ]]; then + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + hexc="${TLS_CIPHER_HEXCODE[i]}" + if [[ ${#hexc} -eq 9 ]] && [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ CBC ]] && \ + [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA256" ]] && [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA384" ]]; then + cbc_cipher_list_hex+=", ${hexc:2:2},${hexc:7:2}" + ciph[nr_ciphers]="${TLS_CIPHER_OSSL_NAME[i]}" + hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2}" + rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" + kx[nr_ciphers]="${TLS_CIPHER_KX[i]}" + enc[nr_ciphers]="${TLS_CIPHER_ENC[i]}" + export2[nr_ciphers]="${TLS_CIPHER_EXPORT[i]}" + ossl_supported[nr_ciphers]=${TLS_CIPHER_OSSL_SUPPORTED[i]} + if "$using_sockets" && "$WIDE" && ! "$has_dh_bits" && \ + ( [[ ${kx[nr_ciphers]} == "Kx=ECDH" ]] || [[ ${kx[nr_ciphers]} == "Kx=DH" ]] || [[ ${kx[nr_ciphers]} == "Kx=EDH" ]] ); then + ossl_supported[nr_ciphers]=false + fi + if [[ "${hexc:2:2}" == "00" ]]; then + normalized_hexcode[nr_ciphers]="x${hexc:7:2}" + else + normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}" + fi + nr_ciphers+=1 + fi + done + cbc_cipher_list_hex="${cbc_cipher_list_hex:2}" + else + while read hexc dash ciph[nr_ciphers] sslvers kx[nr_ciphers] auth enc[nr_ciphers] mac export2[nr_ciphers]; do + if [[ ":${cbc_cipher_list}:" =~ ":${ciph[nr_ciphers]}:" ]]; then + ossl_supported[nr_ciphers]=true + if [[ "${hexc:2:2}" == "00" ]]; then + normalized_hexcode[nr_ciphers]="x${hexc:7:2}" + else + normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}" + fi + nr_ciphers+=1 + fi + done < <($OPENSSL ciphers -tls1 -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>>$ERRFILE) + fi # first determine whether it's mitigated by higher protocols for proto in tls1_1 tls1_2; do @@ -8861,17 +10064,21 @@ run_beast(){ done for proto in ssl3 tls1; do - if [[ "$proto" == "ssl3" ]] && ! locally_supported "-$proto"; then + if [[ "$proto" == "ssl3" ]] && ! "$using_sockets" && ! locally_supported "-$proto"; then continued=true out " " continue fi - addcmd="" - [[ ! "$proto" =~ ssl ]] && addcmd="$SNI" - $OPENSSL s_client -"$proto" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd >$TMPFILE 2>>$ERRFILE $TMPFILE 2>>$ERRFILE $TMPFILE 2>>$ERRFILE $TMPFILE 2>>$ERRFILE $TMPFILE 2>>$ERRFILE >$ERRFILE) # -V doesn't work with openssl < 1.0 - # ^^^^^ process substitution as shopt will either segfault or doesn't work with old bash versions - $OPENSSL s_client -cipher "$cbc_cipher" -"$proto" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd >$TMPFILE 2>>$ERRFILE /dev/null ; then + readlink -f ls &>/dev/null && \ + TESTSSL_INSTALL_DIR=$(dirname $(readlink -f ${BASH_SOURCE[0]})) || \ + TESTSSL_INSTALL_DIR=$(dirname $(readlink ${BASH_SOURCE[0]})) + # not sure whether Darwin has -f + CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" + [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" + fi + + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] ; then + unset ADD_RFC_STR + debugme echo "$CIPHERS_BY_STRENGTH_FILE" + pr_warningln "\nATTENTION: No cipher mapping file found!" + outln "Please note from 2.9dev on $PROG_NAME needs files in \"\$TESTSSL_INSTALL_DIR/etc/\" to function correctly." + outln + ignore_no_or_lame "Type \"yes\" to ignore this warning and proceed at your own risk" "yes" + [[ $? -ne 0 ]] && exit -2 + fi } @@ -9380,13 +10655,13 @@ find_openssl_binary() { OPENSSL_NR_CIPHERS=$(count_ciphers "$($OPENSSL ciphers 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>/dev/null)") - $OPENSSL s_client -ssl2 2>&1 | grep -aq "unknown option" || \ + $OPENSSL s_client -ssl2 -connect x 2>&1 | grep -aq "unknown option" || \ HAS_SSL2=true - $OPENSSL s_client -ssl3 2>&1 | grep -aq "unknown option" || \ + $OPENSSL s_client -ssl3 -connect x 2>&1 | grep -aq "unknown option" || \ HAS_SSL3=true - $OPENSSL s_client -no_ssl2 2>&1 | grep -aq "unknown option" || \ + $OPENSSL s_client -no_ssl2 -connect x 2>&1 | grep -aq "unknown option" || \ HAS_NO_SSL2=true $OPENSSL s_client -help 2>$s_client_has @@ -9421,7 +10696,7 @@ find_openssl_binary() { fi else outln - ignore_no_or_lame " neccessary binary \"timeout\" not found. Continue without timeout?" + ignore_no_or_lame " Neccessary binary \"timeout\" not found. Continue without timeout? " "y" [[ $? -ne 0 ]] && exit -2 unset OPENSSL_TIMEOUT fi @@ -9443,13 +10718,15 @@ check4openssl_oldfarts() { ;; esac if [[ $OSSL_VER_MAJOR -lt 1 ]]; then ## mm: Patch for libressl - pr_magentaln " Your \"$OPENSSL\" is way too old (", where is: @@ -9491,7 +10768,7 @@ help() { "$PROG_NAME URI", where is: - -t, --starttls does a default run against a STARTTLS enabled does a default run against a STARTTLS enabled (latter three require supplied openssl) --xmpphost for STARTTLS enabled XMPP it supplies the XML stream to-'' domain -- sometimes needed --mx tests MX records from high to low priority (STARTTLS, port 25) @@ -9516,12 +10793,12 @@ single check as ("$PROG_NAME URI" does everything except -E): -B, --heartbleed tests for heartbleed vulnerability -I, --ccs, --ccs-injection tests for CCS injection vulnerability -R, --renegotiation tests for renegotiation vulnerabilities - -C, --compression, --crime tests for CRIME vulnerability - -T, --breach tests for BREACH vulnerability + -C, --compression, --crime tests for CRIME vulnerability (TLS compression issue) + -A, --beast tests for BEAST vulnerability (HTTP compression issue) -O, --poodle tests for POODLE (SSL) vulnerability -Z, --tls-fallback checks TLS_FALLBACK_SCSV mitigation + -T, --breach tests for BREACH vulnerability -F, --freak tests for FREAK vulnerability - -A, --beast tests for BEAST vulnerability -J, --logjam tests for LOGJAM vulnerability -D, --drown tests for DROWN vulnerability -s, --pfs, --fs, --nsa checks (perfect) forward secrecy settings @@ -9680,7 +10957,7 @@ EOF ossl_ciph="$(grep -w "$hexc" <<< "$ossl_supported_tls" | awk '{ print $3 }')" if [[ -n "$ossl_ciph" ]]; then TLS_CIPHER_OSSL_SUPPORTED[TLS_NR_CIPHERS]=true - [[ "$ossl_ciph" != "${TLS_CIPHER_OSSL_NAME[TLS_NR_CIPHERS]}" ]] && TLS_CIPHER_OSSL_NAME[TLS_NR_CIPHERS]="$ossl_ciph" + [[ "$ossl_ciph" != "${TLS_CIPHER_OSSL_NAME[TLS_NR_CIPHERS]}" ]] && TLS_CIPHER_OSSL_NAME[TLS_NR_CIPHERS]="$ossl_ciph" fi fi elif [[ $OSSL_VER_MAJOR -lt 1 ]]; then @@ -9807,20 +11084,21 @@ EOF return 0 } - +# arg1: text to display before "-->" +# arg2: arg needed to accept to continue ignore_no_or_lame() { local a [[ "$WARNINGS" == off ]] && return 0 [[ "$WARNINGS" == false ]] && return 0 [[ "$WARNINGS" == batch ]] && return 1 - pr_magenta "$1 " + pr_warning "$1 --> " read a - case $a in - Y|y|Yes|YES|yes) return 0;; - default) ;; - esac - return 1 + if [[ "$a" == "$(tolower "$2")" ]]; then + $ok_arg return 0 + else + return 1 + fi } # arg1: URI @@ -10050,13 +11328,91 @@ get_aaaa_record() { echo "$ip6" } +# RFC6844: DNS Certification Authority Authorization (CAA) Resource Record +# arg1: domain to check for +get_caa_rr_record() { + local caa="" + local saved_openssl_conf="$OPENSSL_CONF" -# now get all IP addresses + OPENSSL_CONF="" + if which dig &> /dev/null; then + caa="$(dig $1 type257 +short | awk '{ print $3 }')" + # empty if no CAA record + elif which host &> /dev/null; then + caa="$(host -t type257 $1)" + if grep -wq issue <<< "$caa" && grep -wvq "has no CAA" <<< "$caa"; then + caa="$(awk '/issue/ { print $NF }' <<< "$caa")" + fi + elif which nslookup &> /dev/null; then + caa="$(nslookup -type=type257 $1)" + if grep -wq issue <<< "$caa" && grep -wvq "No answer" <<< "$caa"; then + caa="$(awk '/issue/ { print $NF }' <<< "$caa")" + fi + else + return 1 + # No dig, host, or nslookup --> complaint was elsewhere already and except for one which has drill only we don't get here + fi + OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/drwetter/testssl.sh/issues/134 + + # try to convert old return values + if [[ "$caa" =~ ^[A-F0-9]+$ ]]; then + caa=${caa:4:100} # ignore the first 4 bytes + caa=$(hex2ascii "$caa" | sed 's/^issue//g') + else + caa=${caa//\"/} # strip " + fi + echo "$caa" +# to do: +# 1: check old binaries whether they support this record at all +# done (2: check whether hexstring is returned and deal with it) +# 3: check more than domainname, see https://tools.ietf.org/html/rfc6844#section-3 +# 4: check whether $1 is a CNAME and take this +# 5: query with drill + return 0 +} + +get_mx_record() { + local mx="" + local saved_openssl_conf="$OPENSSL_CONF" + + OPENSSL_CONF="" # see https://github.com/drwetter/testssl.sh/issues/134 + check_resolver_bins + if which host &> /dev/null; then + mxs=$(host -t MX "$1" 2>/dev/null | awk '/is handled by/ { print $(NF-1), $NF }') + elif which dig &> /dev/null; then + mxs=$(dig +short -t MX "$1" 2>/dev/null) + elif which drill &> /dev/null; then + mxs=$(drill mx "$1" 2>/dev/null | awk '/^\;\;\sANSWER\sSECTION\:$/,/\;\;\sAUTHORITY\sSECTION\:$/ { print $5,$6 }' | sed '/^\s$/d') + elif which nslookup &> /dev/null; then + mxs=$(nslookup -type=MX "$1" 2>/dev/null | awk '/mail exchanger/ { print $(NF-1), $NF }') + else + fatal "No dig, host, drill or nslookup" -3 + fi + OPENSSL_CONF="$saved_openssl_conf" + echo "$mxs" +} + + +# set IPADDRs and IP46ADDRs +# determine_ip_addresses() { local ip4="" local ip6="" - if is_ipv4addr "$NODE"; then + if [[ -n "$CMDLINE_IP" ]]; then + # command line has supplied an IP address + [[ "$CMDLINE_IP" == "one" ]] && \ + CMDLINE_IP="$(get_a_record $NODE | head -1)" + # use first IPv4 address + NODEIP="$CMDLINE_IP" + if is_ipv4addr "$NODEIP"; then + ip4="$NODEIP" + elif is_ipv6addr "$NODEIP"; then + ip6="$NODEIP" + else + fatal "couldn't identify supplied \"CMDLINE_IP\"" 2 + fi + elif is_ipv4addr "$NODE"; then ip4="$NODE" # only an IPv4 address was supplied as an argument, no hostname SNI="" # override Server Name Indication as we test the IP only else @@ -10076,6 +11432,7 @@ determine_ip_addresses() { LOCAL_AAAA=true # we have a local ipv6 entry and need to signal this to testssl fi fi + if [[ -z "$ip4" ]]; then # IPv6 only address if "$HAS_IPv6"; then IPADDRs=$(newline_to_spaces "$ip6") @@ -10090,7 +11447,7 @@ determine_ip_addresses() { IP46ADDRs=$(newline_to_spaces "$ip4 $ip6") fi fi - if [[ -z "$IPADDRs" ]] && [[ -z "$CMDLINE_IP" ]]; then + if [[ -z "$IPADDRs" ]]; then fatal "No IPv4 address for \"$NODE\" available" -1 fi return 0 # IPADDR and IP46ADDR is set now @@ -10123,27 +11480,6 @@ determine_rdns() { return 0 } -get_mx_record() { - local mx="" - local saved_openssl_conf="$OPENSSL_CONF" - - OPENSSL_CONF="" # see https://github.com/drwetter/testssl.sh/issues/134 - check_resolver_bins - if which host &> /dev/null; then - mxs=$(host -t MX "$1" 2>/dev/null | grep 'handled by' | sed -e 's/^.*by //g' -e 's/\.$//') - elif which dig &> /dev/null; then - mxs=$(dig +short -t MX "$1" 2>/dev/null) - elif which drill &> /dev/null; then - mxs=$(drill mx "$1" 2>/dev/null | awk '/^\;\;\sANSWER\sSECTION\:$/,/\;\;\sAUTHORITY\sSECTION\:$/ { print $5,$6 }' | sed '/^\s$/d') - elif which nslookup &> /dev/null; then - mxs=$(nslookup -type=MX "$1" 2>/dev/null | grep 'mail exchanger = ' | sed 's/^.*mail exchanger = //g') - else - fatal "No dig, host, drill or nslookup" -3 - fi - OPENSSL_CONF="$saved_openssl_conf" - echo "$mxs" -} - # We need to get the IP address of the proxy so we can use it in fd_socket # check_proxy() { @@ -10232,7 +11568,7 @@ determine_optimal_proto() { debugme echo "OPTIMAL_PROTO: $OPTIMAL_PROTO" if [[ "$OPTIMAL_PROTO" == "-ssl2" ]]; then pr_magentaln "$NODEIP:$PORT appears to only support SSLv2." - ignore_no_or_lame " Type \"yes\" to accept some false negatives or positives " + ignore_no_or_lame " Type \"yes\" to proceed and accept false negatives or positives" "yes" [[ $? -ne 0 ]] && exit -2 fi fi @@ -10247,7 +11583,7 @@ determine_optimal_proto() { fi tmpfile_handle $FUNCNAME.txt pr_boldln "doesn't seem to be a TLS/SSL enabled server"; - ignore_no_or_lame " Note that the results might look ok but they are nonsense. Proceed ? " + ignore_no_or_lame " The results might look ok but they could be nonsense. Really proceed ? (\"yes\" to continue)" "yes" [[ $? -ne 0 ]] && exit -2 fi @@ -11039,10 +12375,10 @@ lets_roll() { ################# main ################# -get_install_dir initialize_globals parse_cmd_line "$@" +get_install_dir set_color_functions maketempf find_openssl_binary @@ -11075,13 +12411,11 @@ if $do_mx_all_ips; then else parse_hn_port "${URI}" # NODE, URL_PATH, PORT, IPADDR and IP46ADDR is set now prepare_logging - if ! determine_ip_addresses && [[ -z "$CMDLINE_IP" ]]; then + if ! determine_ip_addresses; then fatal "No IP address could be determined" 2 fi if [[ -n "$CMDLINE_IP" ]]; then - [[ "$CMDLINE_IP" == "one" ]] && \ - CMDLINE_IP=$(echo -n "$IPADDRs" | awk '{ print $1 }') - NODEIP="$CMDLINE_IP" # specific ip address for NODE was supplied + # we just test the one supplied lets_roll "${STARTTLS_PROTOCOL}" ret=$? else # no --ip was supplied @@ -11106,4 +12440,3 @@ else fi exit $? - diff --git a/utils/generate_static_cipher_lists.sh b/utils/generate_static_cipher_lists.sh new file mode 100644 index 0000000..f2b5fe2 --- /dev/null +++ b/utils/generate_static_cipher_lists.sh @@ -0,0 +1,352 @@ +#!/usr/bin/env bash +# +# vim:ts=5:sw=5:expandtab +# we have a spaces softtab, that ensures readability with other editors too + +[ -z "$BASH_VERSINFO" ] && printf "\n\033[1;35m Please make sure you're using \"bash\"! Bye...\033[m\n\n" >&2 && exit 245 +[ $(kill -l | grep -c SIG) -eq 0 ] && printf "\n\033[1;35m Please make sure you're calling me without leading \"sh\"! Bye...\033[m\n\n" >&2 && exit 245 + +# This shell script generates the various static cipher lists that are used in testssl.sh. +# It should be re-run whenever new ciphers are added to cipher-mapping.txt to determine +# whether any of the variables in testssl.sh containing cipher lists need to be updated. + +# debugging help: +readonly PS4='${LINENO}> ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' + +COLOR=${COLOR:-2} # 2: Full color, 1: b/w+positioning, 0: no ESC at all +readonly RUN_DIR=$(dirname "$0") +TESTSSL_INSTALL_DIR="${TESTSSL_INSTALL_DIR:-""}" # if you run testssl.sh from a different path you can set either TESTSSL_INSTALL_DIR +CIPHERS_BY_STRENGTH_FILE="" + +###### Cipher suite information ##### +declare -i TLS_NR_CIPHERS=0 +declare TLS_CIPHER_HEXCODE=() +declare TLS_CIPHER_OSSL_NAME=() +declare TLS_CIPHER_RFC_NAME=() +declare TLS_CIPHER_SSLVERS=() +declare TLS_CIPHER_KX=() +declare TLS_CIPHER_AUTH=() +declare TLS_CIPHER_ENC=() +declare TLS_CIPHER_EXPORT=() + +###### output functions ###### +# a little bit of sanitzing with bash internal search&replace -- otherwise printf will hiccup at '%' and '--' does the rest. +out(){ +# if [[ "$BASH_VERSINFO" -eq 4 ]]; then + printf -- "%b" "${1//%/%%}" +# else +# /usr/bin/printf -- "${1//%/%%}" +# fi +} +outln() { out "$1\n"; } +pr_off() { [[ "$COLOR" -ne 0 ]] && out "\033[m"; } +pr_underline() { [[ "$COLOR" -ne 0 ]] && out "\033[4m$1" || out "$1"; pr_off; } + +if [[ $(uname) == "Linux" ]] ; then + toupper() { echo -n "${1^^}" ; } + tolower() { echo -n "${1,,}" ; } +else + toupper() { echo -n "$1" | tr 'a-z' 'A-Z'; } + tolower() { echo -n "$1" | tr 'A-Z' 'a-z' ; } +fi + +# try very hard to determine the install path to get ahold of the mapping file. +# TESTSSL_INSTALL_DIR can be supplied via environment so that the cipher mapping and CA bundles can be found +# www.carbonwind.net/TLS_Cipher_Suites_Project/tls_ssl_cipher_suites_simple_table_all.htm +get_mapping_file() { + local mac + + [[ -z "$TESTSSL_INSTALL_DIR" ]] && TESTSSL_INSTALL_DIR="$(dirname ${BASH_SOURCE[0]})" + + [[ -r "$RUN_DIR/etc/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$RUN_DIR/etc/cipher-mapping.txt" + [[ -r "$RUN_DIR/../etc/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$RUN_DIR/../etc/cipher-mapping.txt" + [[ -r "$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]]; then + [[ -r "$RUN_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$RUN_DIR/cipher-mapping.txt" + [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" + fi + + # we haven't found the cipher file yet... + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] && which readlink &>/dev/null ; then + readlink -f ls &>/dev/null && \ + TESTSSL_INSTALL_DIR=$(readlink -f $(basename ${BASH_SOURCE[0]})) || \ + TESTSSL_INSTALL_DIR=$(readlink $(basename ${BASH_SOURCE[0]})) + # not sure whether Darwin has -f + TESTSSL_INSTALL_DIR=$(dirname $TESTSSL_INSTALL_DIR 2>/dev/null) + [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" + [[ -r "$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" + fi + + # still no cipher mapping file: + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] && which realpath &>/dev/null ; then + TESTSSL_INSTALL_DIR=$(dirname $(realpath ${BASH_SOURCE[0]})) + CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" + [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" + fi + + # still no cipher mapping file (and realpath is not present): + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] && which readlink &>/dev/null ; then + readlink -f ls &>/dev/null && \ + TESTSSL_INSTALL_DIR=$(dirname $(readlink -f ${BASH_SOURCE[0]})) || \ + TESTSSL_INSTALL_DIR=$(dirname $(readlink ${BASH_SOURCE[0]})) + # not sure whether Darwin has -f + CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" + [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" + fi + + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] ; then + outln "\nATTENTION: No cipher mapping file found!" + exit -2 + fi + + while read TLS_CIPHER_HEXCODE[TLS_NR_CIPHERS] n TLS_CIPHER_OSSL_NAME[TLS_NR_CIPHERS] TLS_CIPHER_RFC_NAME[TLS_NR_CIPHERS] TLS_CIPHER_SSLVERS[TLS_NR_CIPHERS] TLS_CIPHER_KX[TLS_NR_CIPHERS] TLS_CIPHER_AUTH[TLS_NR_CIPHERS] TLS_CIPHER_ENC[TLS_NR_CIPHERS] mac TLS_CIPHER_EXPORT[TLS_NR_CIPHERS]; do + TLS_NR_CIPHERS+=1 + done < $CIPHERS_BY_STRENGTH_FILE +} + +get_robust_pfs_ciphers() { + local -i i + local pfs_cipher hexc pfs_cipher_list="" pfs_hex_cipher_list="" + + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + pfs_cipher="${TLS_CIPHER_RFC_NAME[i]}" + if ( [[ "$pfs_cipher" == "TLS_DHE_"* ]] || [[ "$pfs_cipher" == "TLS_ECDHE_"* ]] ) && \ + [[ ! "$pfs_cipher" =~ "NULL" ]] && [[ ! "$pfs_cipher" =~ "DES" ]] && [[ ! "$pfs_cipher" =~ "RC4" ]] && \ + [[ ! "$pfs_cipher" =~ "PSK" ]]; then + hexc="${TLS_CIPHER_HEXCODE[i]}" + pfs_hex_cipher_list+=", ${hexc:2:2},${hexc:7:2}" + [[ "${TLS_CIPHER_OSSL_NAME[i]}" != "-" ]] && pfs_cipher_list+=":${TLS_CIPHER_OSSL_NAME[i]}" + fi + done + outln ; pr_underline "Robust PFS Cipher Lists for SSLv3 - TLSv1.2" ; outln + echo "ROBUST_PFS_CIPHERS=\"${pfs_cipher_list:1}\"" + echo "ROBUST_PFS_CIPHERS_HEX=\"$(tolower "${pfs_hex_cipher_list:2}")\"" +} + +get_std_cipherlists() { + local hexc hexcode strength + local -i i + local null_ciphers="" anon_ciphers="" adh_ciphers="" exp40_ciphers="" + local exp56_ciphers="" exp_ciphers="" low_ciphers="" des_ciphers="" + local medium_ciphers="" tdes_ciphers="" high_ciphers="" + local sslv2_null_ciphers="" sslv2_anon_ciphers="" sslv2_adh_ciphers="" sslv2_exp40_ciphers="" + local sslv2_exp56_ciphers="" sslv2_exp_ciphers="" sslv2_low_ciphers="" sslv2_des_ciphers="" + local sslv2_medium_ciphers="" sslv2_tdes_ciphers="" sslv2_high_ciphers="" + local using_sockets=true + + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + hexc="${TLS_CIPHER_HEXCODE[i]}" + strength="${TLS_CIPHER_ENC[i]}" + strength="${strength//\)/}" + strength="${strength#*\(}" + + if [[ ${#hexc} -eq 9 ]]; then + hexcode="${hexc:2:2},${hexc:7:2}" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=None" ]] && \ + null_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_AUTH[i]}" == "Au=None" ]] && \ + anon_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ "TLS_DH_anon_" ]] && \ + adh_ciphers+=", $hexcode" + [[ $strength -eq 40 ]] && exp40_ciphers+=", $hexcode" +# [[ $strength -eq 56 ]] && exp56_ciphers+=", $hexcode" + [[ $strength -eq 56 ]] && \ + [[ "${TLS_CIPHER_EXPORT[i]}" == "export" ]] && \ + exp56_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_EXPORT[i]}" == "export" ]] && \ + exp_ciphers+=", $hexcode" + if [[ "${TLS_CIPHER_AUTH[i]}" != "Au=None" ]]; then +# [[ $strength -le 64 ]] && low_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" != "Enc=None" ]] && \ + [[ $strength -le 64 ]] && \ + [[ "${TLS_CIPHER_EXPORT[i]}" != "export" ]] && \ + low_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=DES(56)" ]] && \ + [[ "${TLS_CIPHER_EXPORT[i]}" != "export" ]] && \ + des_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=SEED(128)" ]] && \ + medium_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=RC4(128)" ]] && \ + medium_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=IDEA(128)" ]] && \ + medium_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=3DES(168)" ]] && \ + tdes_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=AES"* ]] && \ + high_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=Camellia"* ]] && \ + high_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=ChaCha20"* ]] && \ + high_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=GOST"* ]] && \ + high_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=ARIA"* ]] && \ + high_ciphers+=", $hexcode" + fi + else + hexcode="${hexc:2:2},${hexc:7:2},${hexc:12:2}" + [[ $strength -eq 40 ]] && sslv2_exp40_ciphers+=", $hexcode" +# [[ $strength -eq 56 ]] && sslv2_exp56_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_EXPORT[i]}" == "export" ]] && \ + sslv2_exp_ciphers+=", $hexcode" +# [[ $strength -le 64 ]] && sslv2_low_ciphers+=", $hexcode" + [[ $strength -le 64 ]] && \ + [[ "${TLS_CIPHER_EXPORT[i]}" != "export" ]] && \ + sslv2_low_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=DES(56)" ]] && \ + sslv2_des_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=3DES(168)" ]] && \ + sslv2_tdes_ciphers+=", $hexcode" + fi + done + [[ -n "$null_ciphers" ]] && null_ciphers="${null_ciphers:2}, 00,ff" + [[ -n "$anon_ciphers" ]] && anon_ciphers="${anon_ciphers:2}, 00,ff" + [[ -n "$adh_ciphers" ]] && adh_ciphers="${adh_ciphers:2}, 00,ff" + [[ -n "$exp40_ciphers" ]] && exp40_ciphers="${exp40_ciphers:2}, 00,ff" + [[ -n "$exp56_ciphers" ]] && exp56_ciphers="${exp56_ciphers:2}, 00,ff" + [[ -n "$exp_ciphers" ]] && exp_ciphers="${exp_ciphers:2}, 00,ff" + [[ -n "$low_ciphers" ]] && low_ciphers="${low_ciphers:2}, 00,ff" + [[ -n "$des_ciphers" ]] && des_ciphers="${des_ciphers:2}, 00,ff" + [[ -n "$medium_ciphers" ]] && medium_ciphers="${medium_ciphers:2}, 00,ff" + [[ -n "$tdes_ciphers" ]] && tdes_ciphers="${tdes_ciphers:2}, 00,ff" + [[ -n "$high_ciphers" ]] && high_ciphers="${high_ciphers:2}, 00,ff" + [[ -n "$sslv2_null_ciphers" ]] && sslv2_null_ciphers="${sslv2_null_ciphers:2}" + [[ -n "$sslv2_anon_ciphers" ]] && sslv2_anon_ciphers="${sslv2_anon_ciphers:2}" + [[ -n "$sslv2_adh_ciphers" ]] && sslv2_adh_ciphers="${sslv2_adh_ciphers:2}" + [[ -n "$sslv2_exp40_ciphers" ]] && sslv2_exp40_ciphers="${sslv2_exp40_ciphers:2}" + [[ -n "$sslv2_exp56_ciphers" ]] && sslv2_exp56_ciphers="${sslv2_exp56_ciphers:2}" + [[ -n "$sslv2_exp_ciphers" ]] && sslv2_exp_ciphers="${sslv2_exp_ciphers:2}" + [[ -n "$sslv2_low_ciphers" ]] && sslv2_low_ciphers="${sslv2_low_ciphers:2}" + [[ -n "$sslv2_des_ciphers" ]] && sslv2_des_ciphers="${sslv2_des_ciphers:2}" + [[ -n "$sslv2_medium_ciphers" ]] && sslv2_medium_ciphers="${sslv2_medium_ciphers:2}" + [[ -n "$sslv2_tdes_ciphers" ]] && sslv2_tdes_ciphers="${sslv2_tdes_ciphers:2}" + [[ -n "$sslv2_high_ciphers" ]] && sslv2_high_ciphers="${sslv2_high_ciphers:2}" + + outln ; pr_underline "Cipher lists for run_std_cipherlists()"; outln + outln "null_ciphers=\"$(tolower "$null_ciphers")\"" + outln "sslv2_null_ciphers=\"$(tolower "$sslv2_null_ciphers")\"" + outln "anon_ciphers=\"$(tolower "$anon_ciphers")\"" + outln "sslv2_anon_ciphers=\"$(tolower "$sslv2_anon_ciphers")\"" + outln "adh_ciphers=\"$(tolower "$adh_ciphers")\"" + outln "sslv2_adh_ciphers=\"$(tolower "$sslv2_adh_ciphers")\"" + outln exp40_ciphers"=\"$(tolower "$exp40_ciphers")\"" + outln "sslv2_exp40_ciphers=\"$(tolower "$sslv2_exp40_ciphers")\"" + outln "exp56_ciphers=\"$(tolower "$exp56_ciphers")\"" + outln "sslv2_exp56_ciphers=\"$(tolower "$sslv2_exp56_ciphers")\"" + outln "exp_ciphers=\"$(tolower "$exp_ciphers")\"" + outln "sslv2_exp_ciphers=\"$(tolower "$sslv2_exp_ciphers")\"" + outln "low_ciphers=\"$(tolower "$low_ciphers")\"" + outln "sslv2_low_ciphers=\"$(tolower "$sslv2_low_ciphers")\"" + outln "des_ciphers=\"$(tolower "$des_ciphers")\"" + outln "sslv2_des_ciphers=\"$(tolower "$sslv2_des_ciphers")\"" + outln "medium_ciphers=\"$(tolower "$medium_ciphers")\"" + outln "sslv2_medium_ciphers=\"$(tolower "$sslv2_medium_ciphers")\"" + outln "tdes_ciphers=\"$(tolower "$tdes_ciphers")\"" + outln "sslv2_tdes_ciphers=\"$(tolower "$sslv2_tdes_ciphers")\"" + outln "high_ciphers=\"$(tolower "$high_ciphers")\"" + outln "sslv2_high_ciphers=\"$(tolower "$sslv2_high_ciphers")\"" +} + +get_cbc_ciphers() { + local -i + local hexc cbc_cipher_list="" cbc_cipher_list_hex="" + + # Want to keep ciphers lists to under 128 ciphers. Since there are a number of CBC ciphers + # that do not currently have OpenSSL names, the ciphers with Null authentication can be + # included in the OpenSSL list, but need to be excluded from the hex list. + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + if [[ "${TLS_CIPHER_SSLVERS[i]}" != "SSLv2" ]] && [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ CBC ]] && \ + [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ PSK ]] && [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SRP ]] && \ + [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ KRB5 ]]; then + hexc="${TLS_CIPHER_HEXCODE[i]}" + [[ "${TLS_CIPHER_AUTH[i]}" != "Au=None" ]] && cbc_cipher_list_hex+=", ${hexc:2:2},${hexc:7:2}" + [[ "${TLS_CIPHER_OSSL_NAME[i]}" != "-" ]] && cbc_cipher_list+=":${TLS_CIPHER_OSSL_NAME[i]}" + fi + done + + outln ; pr_underline "CBC Ciphers for determine_tls_extensions()"; outln + outln "cbc_cipher_list=\"${cbc_cipher_list:1}\"" + outln "cbc_cipher_list_hex=\"$(tolower "${cbc_cipher_list_hex:2}")\"" +} + +get_sslv3_tls1_cbc_ciphers() { + local -i + local hexc cbc_ciphers="" cbc_ciphers_hex="" + + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + if [[ "${TLS_CIPHER_SSLVERS[i]}" != "SSLv2" ]] && [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ CBC ]] && \ + [[ "${TLS_CIPHER_RFC_NAME[i]}" != *SHA256 ]] && [[ "${TLS_CIPHER_RFC_NAME[i]}" != *SHA384 ]]; then + hexc="${TLS_CIPHER_HEXCODE[i]}" + cbc_ciphers_hex+=", ${hexc:2:2},${hexc:7:2}" + [[ "${TLS_CIPHER_OSSL_NAME[i]}" != "-" ]] && cbc_ciphers+=":${TLS_CIPHER_OSSL_NAME[i]}" + fi + done + + outln ; pr_underline "SSLv3/TLSv1.0 CBC Ciphers for run_ssl_poodle() and run_beast()"; outln + outln "cbc_ciphers=\"${cbc_ciphers:1}\"" + outln "cbc_ciphers_hex=\"$(tolower "${cbc_ciphers_hex:2}")\"" +} + +get_export_rsa_ciphers() { + local -i i + local exportrsa_cipher_list="" exportrsa_tls_cipher_list_hex="" exportrsa_ssl2_cipher_list_hex="" + + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + if [[ "${TLS_CIPHER_EXPORT[i]}" == "export" ]] && \ + ( [[ "${TLS_CIPHER_KX[i]}" =~ RSA ]] || [[ "${TLS_CIPHER_AUTH[i]}" =~ RSA ]] ); then + hexc="${TLS_CIPHER_HEXCODE[i]}" + [[ "${TLS_CIPHER_SSLVERS[i]}" == "SSLv2" ]] && exportrsa_ssl2_cipher_list_hex+=", ${hexc:2:2},${hexc:7:2},${hexc:12:2}" + [[ "${TLS_CIPHER_SSLVERS[i]}" != "SSLv2" ]] && exportrsa_tls_cipher_list_hex+=", ${hexc:2:2},${hexc:7:2}" + [[ ! ":${exportrsa_cipher_list}:" =~ "${TLS_CIPHER_OSSL_NAME[i]}" ]] && exportrsa_cipher_list+=":${TLS_CIPHER_OSSL_NAME[i]}" + fi + done + + outln ; pr_underline "Export RSA ciphers for run_freak()"; outln + outln "exportrsa_cipher_list=\"${exportrsa_cipher_list:1}\"" + outln "exportrsa_tls_cipher_list_hex=\"${exportrsa_tls_cipher_list_hex:2}\"" + outln "exportrsa_ssl2_cipher_list_hex=\"${exportrsa_ssl2_cipher_list_hex:2}\"" +} + +get_weak_dh_ciphers() { + local -i + local hexc exportdhe_cipher_list="" exportdhe_cipher_list_hex="" + + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + if [[ "${TLS_CIPHER_RFC_NAME[i]}" == "TLS_DHE_"* ]] && [[ "${TLS_CIPHER_EXPORT[i]}" == "export" ]]; then + hexc="${TLS_CIPHER_HEXCODE[i]}" + [[ "${TLS_CIPHER_OSSL_NAME[i]}" != "-" ]] && exportdhe_cipher_list+=":${TLS_CIPHER_OSSL_NAME[i]}" + exportdhe_cipher_list_hex+=", ${hexc:2:2},${hexc:7:2}" + fi + done + + outln; pr_underline "Weak DH ciphers for run_logjam()"; outln + outln "exportdhe_cipher_list=\"${exportdhe_cipher_list:1}\"" + outln "exportdhe_cipher_list_hex=\"${exportdhe_cipher_list_hex:2}\"" +} + +get_dhe_ciphers() { + local -i + local hexc all_dhe_ciphers="" + + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + if [[ "${TLS_CIPHER_RFC_NAME[i]}" == "TLS_DHE_"* ]] || [[ "${TLS_CIPHER_RFC_NAME[i]}" == "TLS_DH_anon_"* ]]; then + hexc="${TLS_CIPHER_HEXCODE[i]}" + all_dhe_ciphers+=", ${hexc:2:2},${hexc:7:2}" + fi + done + + outln; pr_underline "All DHE ciphers for run_logjam()"; outln + outln "all_dhe_ciphers=\"$(tolower "${all_dhe_ciphers:2}")\"" +} + +get_mapping_file +get_robust_pfs_ciphers +get_std_cipherlists +get_cbc_ciphers +get_sslv3_tls1_cbc_ciphers +get_export_rsa_ciphers +get_weak_dh_ciphers +get_dhe_ciphers +outln + +exit $?