def test_tls_certificate_x509_pubkey(self): pkt = tls.TLSRecord() / tls.TLSHandshake() / tls.TLSCertificateList( certificates=[ tls.TLSCertificate(data=x509.X509Cert(self.der_cert)) ]) # dissect and extract pubkey pkt = tls.SSL(str(pkt)) pubkey_extract_from_der = tlsc.x509_extract_pubkey_from_der( self.der_cert) pubkey_extract_from_tls_certificate = tlsc.x509_extract_pubkey_from_der( pkt[tls.TLSCertificate].data) self.assertEqual(pubkey_extract_from_der, pubkey_extract_from_tls_certificate) self.assertTrue(pubkey_extract_from_der.can_encrypt()) self.assertTrue(pubkey_extract_from_der.can_sign()) self.assertTrue(pubkey_extract_from_tls_certificate.can_encrypt()) self.assertTrue(pubkey_extract_from_tls_certificate.can_sign()) plaintext = "-!-plaintext-!-" * 11 ciphertext = ''.join( pubkey_extract_from_tls_certificate.encrypt(plaintext, None)) ciphertext_2 = ''.join(pubkey_extract_from_der.encrypt( plaintext, None)) self.assertTrue(len(ciphertext)) self.assertEqual(ciphertext, ciphertext_2)
def test_tls_certificate_x509_pubkey(self): pkt = tls.TLSRecord()/tls.TLSHandshake()/tls.TLSCertificateList(certificates=[tls.TLSCertificate(data=x509.X509Cert(self.der_cert))]) # dissect and extract pubkey pkt = tls.SSL(str(pkt)) pubkey_extract_from_der = tlsc.x509_extract_pubkey_from_der(self.der_cert) pubkey_extract_from_tls_certificate = tlsc.x509_extract_pubkey_from_der(pkt[tls.TLSCertificate].data) self.assertEqual(pubkey_extract_from_der, pubkey_extract_from_tls_certificate) self.assertTrue(pubkey_extract_from_der.can_encrypt()) self.assertTrue(pubkey_extract_from_der.can_sign()) self.assertTrue(pubkey_extract_from_tls_certificate.can_encrypt()) self.assertTrue(pubkey_extract_from_tls_certificate.can_sign()) plaintext = "-!-plaintext-!-"*11 ciphertext = ''.join(pubkey_extract_from_tls_certificate.encrypt(plaintext,None)) ciphertext_2 = ''.join(pubkey_extract_from_der.encrypt(plaintext,None)) self.assertTrue(len(ciphertext)) self.assertEqual(ciphertext,ciphertext_2)
def get_events(self): events=[] events.extend(self.events) for tlsinfo in (self.info.client, self.info.server): # test CRIME - compressions offered? tmp = tlsinfo.compressions.copy() if 0 in tmp: tmp.remove(0) if len(tmp): events.append(("CRIME - %s supports compression"%tlsinfo.__name__,tlsinfo.compressions)) # test RC4 cipher_namelist = [TLS_CIPHER_SUITES.get(c,"SSLv2_%s"%SSLv2_CIPHER_SUITES.get(c,c)) for c in tlsinfo.ciphers] tmp = [c for c in cipher_namelist if isinstance(c,basestring) and "SSLV2" in c.upper() and "EXP" in c.upper()] if tmp: events.append(("DROWN - SSLv2 with EXPORT ciphers enabled",tmp)) tmp = [c for c in cipher_namelist if isinstance(c,basestring) and "EXP" in c.upper()] if tmp: events.append(("CIPHERS - Export ciphers enabled",tmp)) tmp = [c for c in cipher_namelist if isinstance(c,basestring) and "RC4" in c.upper()] if tmp: events.append(("CIPHERS - RC4 ciphers enabled",tmp)) tmp = [c for c in cipher_namelist if isinstance(c,basestring) and "MD2" in c.upper()] if tmp: events.append(("CIPHERS - MD2 ciphers enabled",tmp)) tmp = [c for c in cipher_namelist if isinstance(c,basestring) and "MD4" in c.upper()] if tmp: events.append(("CIPHERS - MD4 ciphers enabled",tmp)) tmp = [c for c in cipher_namelist if isinstance(c,basestring) and "MD5" in c.upper()] if tmp: events.append(("CIPHERS - MD5 ciphers enabled",tmp)) tmp = [c for c in cipher_namelist if isinstance(c,basestring) and "RSA_EXP" in c.upper()] if tmp: # only check DHE EXPORT for now. we might want to add DH1024 here. events.append(("FREAK - server supports RSA_EXPORT cipher suites",tmp)) tmp = [c for c in cipher_namelist if isinstance(c,basestring) and "DHE_" in c.upper() and "EXPORT_" in c.upper()] if tmp: # only check DHE EXPORT for now. we might want to add DH1024 here. events.append(("LOGJAM - server supports weak DH-Group (512) (DHE_*_EXPORT) cipher suites",tmp)) tmp = [ext for ext in tlsinfo.extensions if ext.haslayer(TLSExtSignatureAndHashAlgorithm)] # obvious SLOTH check, does not detect impl. errors that allow md5 even though not announced. # makes only sense for client_hello for sighashext in tmp: for alg in sighashext[TLSExtSignatureAndHashAlgorithm].algorithms: if alg.signature_algorithm==TLSSignatureAlgorithm.RSA \ and alg.hash_algorithm in (TLSHashAlgorithm.MD5, TLSHashAlgorithm.SHA1): events.append(("SLOTH - %s announces capability of signature/hash algorithm: RSA/%s"%(tlsinfo.__name__,TLS_HASH_ALGORITHMS.get(alg.hash_algorithm)),alg)) try: for certlist in tlsinfo.certificates: for cert in certlist.certificates: pubkey = x509_extract_pubkey_from_der(str(cert.data)) pubkey_size = pubkey.size() + 1 if pubkey_size < 2048: events.append(("INSUFFICIENT SERVER CERT PUBKEY SIZE - 2048 >= %d bits"%pubkey_size,cert)) if pubkey_size % 2048 != 0: events.append(("SUSPICIOUS SERVER CERT PUBKEY SIZE - %d not a multiple of 2048 bits"%pubkey_size,cert)) if pubkey.n in self.RSA_MODULI_KNOWN_FACTORED: events.append(("SERVER CERT PUBKEY FACTORED - trivial private_key recovery possible due to known factors n = p x q. See https://en.wikipedia.org/wiki/RSA_numbers | grep %s"%pubkey.n,cert)) except AttributeError: pass # tlsinfo.client has no attribute certificates if TLSVersion.SSL_2_0 in tlsinfo.versions: events.append(("PROTOCOL VERSION - SSLv2 supported ",tlsinfo.versions)) if TLSVersion.SSL_3_0 in tlsinfo.versions: events.append(("PROTOCOL VERSION - SSLv3 supported ",tlsinfo.versions)) if TLSHeartbeatMode.PEER_ALLOWED_TO_SEND == tlsinfo.heartbeat: events.append(("HEARTBEAT - enabled (non conclusive heartbleed) ",tlsinfo.versions)) if self.info.server.fallback_scsv==True: events.append(("DOWNGRADE / POODLE - FALLBACK_SCSV honored (alert.inappropriate_fallback seen)",self.info.server.fallback_scsv)) return events
def get_events(self): events = [] events.extend(self.events) for tlsinfo in (self.info.client, self.info.server): # test CRIME - compressions offered? tmp = tlsinfo.compressions.copy() if 0 in tmp: tmp.remove(0) if len(tmp): events.append( ("CRIME - %s supports compression" % tlsinfo.__name__, tlsinfo.compressions)) # test RC4 cipher_namelist = [ TLS_CIPHER_SUITES.get( c, "SSLv2_%s" % SSLv2_CIPHER_SUITES.get(c, c)) for c in tlsinfo.ciphers ] tmp = [ c for c in cipher_namelist if isinstance(c, basestring) and "SSLV2" in c.upper() and "EXP" in c.upper() ] if tmp: events.append( ("DROWN - SSLv2 with EXPORT ciphers enabled", tmp)) tmp = [ c for c in cipher_namelist if isinstance(c, basestring) and "EXP" in c.upper() ] if tmp: events.append(("CIPHERS - Export ciphers enabled", tmp)) tmp = [ c for c in cipher_namelist if isinstance(c, basestring) and "RC4" in c.upper() ] if tmp: events.append(("CIPHERS - RC4 ciphers enabled", tmp)) tmp = [ c for c in cipher_namelist if isinstance(c, basestring) and "MD2" in c.upper() ] if tmp: events.append(("CIPHERS - MD2 ciphers enabled", tmp)) tmp = [ c for c in cipher_namelist if isinstance(c, basestring) and "MD4" in c.upper() ] if tmp: events.append(("CIPHERS - MD4 ciphers enabled", tmp)) tmp = [ c for c in cipher_namelist if isinstance(c, basestring) and "MD5" in c.upper() ] if tmp: events.append(("CIPHERS - MD5 ciphers enabled", tmp)) tmp = [ c for c in cipher_namelist if isinstance(c, basestring) and "RSA_EXP" in c.upper() ] if tmp: # only check DHE EXPORT for now. we might want to add DH1024 here. events.append( ("FREAK - server supports RSA_EXPORT cipher suites", tmp)) tmp = [ c for c in cipher_namelist if isinstance(c, basestring) and "DHE_" in c.upper() and "EXPORT_" in c.upper() ] if tmp: # only check DHE EXPORT for now. we might want to add DH1024 here. events.append(( "LOGJAM - server supports weak DH-Group (512) (DHE_*_EXPORT) cipher suites", tmp)) tmp = [ ext for ext in tlsinfo.extensions if ext.haslayer(TLSExtSignatureAndHashAlgorithm) ] # obvious SLOTH check, does not detect impl. errors that allow md5 even though not announced. # makes only sense for client_hello for sighashext in tmp: for alg in sighashext[ TLSExtSignatureAndHashAlgorithm].algorithms: if alg.signature_algorithm==TLSSignatureAlgorithm.RSA \ and alg.hash_algorithm in (TLSHashAlgorithm.MD5, TLSHashAlgorithm.SHA1): events.append(( "SLOTH - %s announces capability of signature/hash algorithm: RSA/%s" % (tlsinfo.__name__, TLS_HASH_ALGORITHMS.get(alg.hash_algorithm)), alg)) try: for certlist in tlsinfo.certificates: for cert in certlist.certificates: pubkey = x509_extract_pubkey_from_der(str(cert.data)) pubkey_size = pubkey.size() + 1 if pubkey_size < 2048: events.append(( "INSUFFICIENT SERVER CERT PUBKEY SIZE - 2048 >= %d bits" % pubkey_size, cert)) if pubkey_size % 2048 != 0: events.append(( "SUSPICIOUS SERVER CERT PUBKEY SIZE - %d not a multiple of 2048 bits" % pubkey_size, cert)) if pubkey.n in self.RSA_MODULI_KNOWN_FACTORED: events.append(( "SERVER CERT PUBKEY FACTORED - trivial private_key recovery possible due to known factors n = p x q. See https://en.wikipedia.org/wiki/RSA_numbers | grep %s" % pubkey.n, cert)) except AttributeError: pass # tlsinfo.client has no attribute certificates if TLSVersion.SSL_2_0 in tlsinfo.versions: events.append( ("PROTOCOL VERSION - SSLv2 supported ", tlsinfo.versions)) if TLSVersion.SSL_3_0 in tlsinfo.versions: events.append( ("PROTOCOL VERSION - SSLv3 supported ", tlsinfo.versions)) if TLSHeartbeatMode.PEER_ALLOWED_TO_SEND == tlsinfo.heartbeat: events.append( ("HEARTBEAT - enabled (non conclusive heartbleed) ", tlsinfo.versions)) if self.info.server.fallback_scsv == True: events.append(( "DOWNGRADE / POODLE - FALLBACK_SCSV honored (alert.inappropriate_fallback seen)", self.info.server.fallback_scsv)) return events