diff --git a/scapy/layers/tls/__init__.py b/scapy/layers/tls/__init__.py index 5bc6d76b89e9920c763d7b1959ee9900c1a5df4c..2c6159194a86c9b68690c2a697c9eed1fd214fef 100644 --- a/scapy/layers/tls/__init__.py +++ b/scapy/layers/tls/__init__.py @@ -106,8 +106,6 @@ TODO list (may it be carved away by good souls): - Go through the kx_algs and see what may be commented out. - - Define the OCSPStatus packet. - - Define several Certificate Transparency objects. - Enhance PSK and session ticket support. diff --git a/scapy/layers/tls/cert.py b/scapy/layers/tls/cert.py index a3eed47e4d57d8fadabd75197dafe9b9c9a6498c..8f816267a8d938e4612f3cafdde842d600f4d2e5 100644 --- a/scapy/layers/tls/cert.py +++ b/scapy/layers/tls/cert.py @@ -31,23 +31,23 @@ import time from scapy.config import conf, crypto_validator if conf.crypto_valid: from cryptography.hazmat.backends import default_backend + from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa else: - default_backend = rsa = None + default_backend = rsa = serialization = None -from scapy.config import conf -from scapy.asn1.asn1 import ASN1_BIT_STRING -from scapy.asn1.mib import hash_by_oid from scapy.error import warning -from scapy.layers.x509 import X509_SubjectPublicKeyInfo -from scapy.layers.x509 import RSAPublicKey, RSAPrivateKey -from scapy.layers.x509 import ECDSAPublicKey, ECDSAPrivateKey -from scapy.layers.x509 import RSAPrivateKey_OpenSSL, ECDSAPrivateKey_OpenSSL -from scapy.layers.x509 import X509_Cert, X509_CRL from scapy.utils import binrepr -from scapy.layers.tls.crypto.pkcs1 import pkcs_os2ip, pkcs_i2osp, mapHashFunc -from scapy.layers.tls.crypto.pkcs1 import _EncryptAndVerifyRSA -from scapy.layers.tls.crypto.pkcs1 import _DecryptAndSignRSA +from scapy.asn1.asn1 import ASN1_BIT_STRING +from scapy.asn1.mib import hash_by_oid +from scapy.layers.x509 import (X509_SubjectPublicKeyInfo, + RSAPublicKey, RSAPrivateKey, + ECDSAPublicKey, ECDSAPrivateKey, + RSAPrivateKey_OpenSSL, ECDSAPrivateKey_OpenSSL, + X509_Cert, X509_CRL) +from scapy.layers.tls.crypto.pkcs1 import (pkcs_os2ip, pkcs_i2osp, mapHashFunc, + _EncryptAndVerifyRSA, + _DecryptAndSignRSA) # Maximum allowed size in bytes for a certificate file, to avoid # loading huge file when importing a cert @@ -175,9 +175,18 @@ class _PubKeyFactory(_PKIObjMaker): It casts the appropriate class on the fly, then fills in the appropriate attributes with import_from_asn1pkt() submethod. """ - def __call__(cls, key_path): + def __call__(cls, key_path=None): - # First, we deal with the exceptional RSA 'kx export' call. + if key_path is None: + obj = type.__call__(cls) + if cls is PubKey: + cls = PubKeyRSA + obj.__class__ = cls + obj.frmt = "original" + obj.fill_and_store() + return obj + + # This deals with the rare RSA 'kx export' call. if type(key_path) is tuple: obj = type.__call__(cls) obj.__class__ = PubKeyRSA @@ -199,7 +208,7 @@ class _PubKeyFactory(_PKIObjMaker): elif isinstance(pubkey, ECDSAPublicKey): obj.__class__ = PubKeyECDSA try: - obj.import_from_asn1pkt(obj.der) + obj.import_from_der(obj.der) except ImportError: pass else: @@ -236,61 +245,84 @@ class PubKey(object): return self.verify(str(tbsCert), sigVal, h=h, t='pkcs') -class PubKeyRSA(_PKIObj, PubKey, _EncryptAndVerifyRSA): +class PubKeyRSA(PubKey, _EncryptAndVerifyRSA): """ Wrapper for RSA keys based on _EncryptAndVerifyRSA from crypto/pkcs1.py Use the 'key' attribute to access original object. """ + @crypto_validator + def fill_and_store(self, modulus=None, modulusLen=None, pubExp=None): + pubExp = pubExp or 65537 + if modulus is None: + real_modulusLen = modulusLen or 2048 + private_key = rsa.generate_private_key(public_exponent=pubExp, + key_size=real_modulusLen, + backend=default_backend()) + self.pubkey = private_key.public_key() + else: + real_modulusLen = len(binrepr(modulus)) + if real_modulusLen != modulusLen: + warning("modulus and modulusLen do not match!") + pubNum = rsa.RSAPublicNumbers(n=modulus, e=pubExp) + self.pubkey = pubNum.public_key(default_backend()) + #XXX lines below should be removed once pkcs1.py is cleaned of legacy + pubNum = self.pubkey.public_numbers() + self._modulusLen = real_modulusLen + self._modulus = pubNum.n + self._pubExp = pubNum.e + @crypto_validator def import_from_tuple(self, tup): # this is rarely used e, m, mLen = tup if isinstance(m, str): - self.modulus = pkcs_os2ip(m) - else: - self.modulus = m - self.modulusLen = mLen + m = pkcs_os2ip(m) if isinstance(e, str): - self.pubExp = pkcs_os2ip(e) - else: - self.pubExp = e - pubNum = rsa.RSAPublicNumbers(n=self.modulus, e=self.pubExp) - self.pubkey = pubNum.public_key(default_backend()) + e = pkcs_os2ip(e) + self.fill_and_store(modulus=m, pubExp=e) self.pem = self.pubkey.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo) self.der = pem2der(self.pem) - @crypto_validator def import_from_asn1pkt(self, pubkey): - self.modulus = pubkey.modulus.val - self.modulusLen = len(binrepr(pubkey.modulus.val)) - self.pubExp = pubkey.publicExponent.val - pubNum = rsa.RSAPublicNumbers(n=self.modulus, e=self.pubExp) - self.pubkey = pubNum.public_key(default_backend()) + modulus = pubkey.modulus.val + pubExp = pubkey.publicExponent.val + self.fill_and_store(modulus=modulus, pubExp=pubExp) + def encrypt(self, msg, t=None, h=None, mgf=None, L=None): # no ECDSA encryption support, hence no ECDSA specific keywords here return _EncryptAndVerifyRSA.encrypt(self, msg, t=t, h=h, mgf=mgf, L=L) + def verify(self, msg, sig, h=None, t=None, mgf=None, sLen=None): return _EncryptAndVerifyRSA.verify(self, msg, sig, h=h, t=t, mgf=mgf, sLen=sLen) -class PubKeyECDSA(_PKIObj, PubKey): +class PubKeyECDSA(PubKey): """ Wrapper for ECDSA keys based on the cryptography library. Use the 'key' attribute to access original object. """ - def import_from_asn1pkt(self, pubkey): + @crypto_validator + def fill_and_store(self, curve=None): + curve = curve or ec.SECP256R1 + private_key = ec.generate_private_key(curve(), default_backend()) + self.pubkey = private_key.public_key() + + @crypto_validator + def import_from_der(self, pubkey): # XXX does the cryptography lib support explicit curves? # check also for compressed points self.pubkey = serialization.load_der_public_key(pubkey, backend=default_backend()) - def encrypt(self, msg, t=None, h=None, mgf=None, L=None): + + def encrypt(self, msg, h=None, **kwargs): # cryptography lib does not support ECDSA encryption raise Exception("No ECDSA encryption support") - def verify(self, msg, sig, h=None, - t=None, mgf=None, sLen=None): + + @crypto_validator + def verify(self, msg, sig, h=None, **kwargs): # 'sig' should be a DER-encoded signature, as per RFC 3279 verifier = self.pubkey.verifier(sig, ec.ECDSA(mapHashFunc(h))) verifier.update(msg) @@ -307,7 +339,7 @@ class _PrivKeyFactory(_PKIObjMaker): It casts the appropriate class on the fly, then fills in the appropriate attributes with import_from_asn1pkt() submethod. """ - def __call__(cls, key_path): + def __call__(cls, key_path=None): """ key_path may be the path to either: _an RSAPrivateKey_OpenSSL (as generated by openssl); @@ -315,6 +347,15 @@ class _PrivKeyFactory(_PKIObjMaker): _an RSAPrivateKey; _an ECDSAPrivateKey. """ + if key_path is None: + obj = type.__call__(cls) + if cls is PrivKey: + cls = PrivKeyECDSA + obj.__class__ = cls + obj.frmt = "original" + obj.fill_and_store() + return obj + obj = _PKIObjMaker.__call__(cls, key_path, MAX_KEY_SIZE) multiPEM = False try: @@ -398,54 +439,94 @@ class PrivKey(object): return self.verify(str(tbsCert), sigVal, h=h, t='pkcs') -class PrivKeyRSA(_PKIObj, PrivKey, _EncryptAndVerifyRSA, _DecryptAndSignRSA): +class PrivKeyRSA(PrivKey, _EncryptAndVerifyRSA, _DecryptAndSignRSA): """ Wrapper for RSA keys based on _DecryptAndSignRSA from crypto/pkcs1.py Use the 'key' attribute to access original object. """ @crypto_validator + def fill_and_store(self, modulus=None, modulusLen=None, pubExp=None, + prime1=None, prime2=None, coefficient=None, + exponent1=None, exponent2=None, privExp=None): + pubExp = pubExp or 65537 + if None in [modulus, prime1, prime2, coefficient, privExp, + exponent1, exponent2]: + # note that the library requires every parameter + # in order to call RSAPrivateNumbers(...) + # if one of these is missing, we generate a whole new key + real_modulusLen = modulusLen or 2048 + self.key = rsa.generate_private_key(public_exponent=pubExp, + key_size=real_modulusLen, + backend=default_backend()) + self.pubkey = self.key.public_key() + else: + real_modulusLen = len(binrepr(modulus)) + if real_modulusLen != modulusLen: + warning("modulus and modulusLen do not match!") + pubNum = rsa.RSAPublicNumbers(n=modulus, e=pubExp) + privNum = rsa.RSAPrivateNumbers(p=prime1, q=prime2, + dmp1=exponent1, dmq1=exponent2, + iqmp=coefficient, d=privExp, + public_numbers=pubNum) + self.key = privNum.private_key(default_backend()) + self.pubkey = self.key.public_key() + #XXX lines below should be removed once pkcs1.py is cleaned of legacy + pubNum = self.pubkey.public_numbers() + self._modulusLen = real_modulusLen + self._modulus = pubNum.n + self._pubExp = pubNum.e + def import_from_asn1pkt(self, privkey): - self.modulus = privkey.modulus.val - self.modulusLen = len(binrepr(privkey.modulus.val)) - self.pubExp = privkey.publicExponent.val - self.privExp = privkey.privateExponent.val - self.prime1 = privkey.prime1.val - self.prime2 = privkey.prime2.val - self.exponent1 = privkey.exponent1.val - self.exponent2 = privkey.exponent2.val - self.coefficient = privkey.coefficient.val - self.key = rsa.RSAPrivateNumbers( - p=self.prime1, q=self.prime2, d=self.privExp, dmp1=self.exponent1, - dmq1=self.exponent2, iqmp=self.coefficient, - public_numbers=rsa.RSAPublicNumbers(n=self.modulus, e=self.pubExp), - ).private_key(default_backend()) - self.pubkey = self.key.public_key() + modulus = privkey.modulus.val + pubExp = privkey.publicExponent.val + privExp = privkey.privateExponent.val + prime1 = privkey.prime1.val + prime2 = privkey.prime2.val + exponent1 = privkey.exponent1.val + exponent2 = privkey.exponent2.val + coefficient = privkey.coefficient.val + self.fill_and_store(modulus=modulus, pubExp=pubExp, + privExp=privExp, prime1=prime1, prime2=prime2, + exponent1=exponent1, exponent2=exponent2, + coefficient=coefficient) + def verify(self, msg, sig, h=None, t=None, mgf=None, sLen=None): # Let's copy this from PubKeyRSA instead of adding another baseclass :) return _EncryptAndVerifyRSA.verify(self, msg, sig, h=h, t=t, mgf=mgf, sLen=sLen) + def sign(self, data, h=None, t=None, mgf=None, sLen=None): return _DecryptAndSignRSA.sign(self, data, h=h, t=t, mgf=mgf, sLen=sLen) -class PrivKeyECDSA(_PKIObj, PrivKey): +class PrivKeyECDSA(PrivKey): """ Wrapper for ECDSA keys based on SigningKey from ecdsa library. Use the 'key' attribute to access original object. """ + @crypto_validator + def fill_and_store(self, curve=None): + curve = curve or ec.SECP256R1 + self.key = ec.generate_private_key(curve(), default_backend()) + self.pubkey = self.key.public_key() + + @crypto_validator def import_from_asn1pkt(self, privkey): - self.key = serialization.load_der_private_key(str(privkey), - None, - backend=default_backend()) + self.key = serialization.load_der_private_key(str(privkey), None, + backend=default_backend()) self.pubkey = self.key.public_key() + + @crypto_validator def verify(self, msg, sig, h=None, **kwargs): # 'sig' should be a DER-encoded signature, as per RFC 3279 verifier = self.pubkey.verifier(sig, ec.ECDSA(mapHashFunc(h))) verifier.update(msg) return verifier.verify() + + @crypto_validator def sign(self, data, h=None, **kwargs): signer = self.key.signer(ec.ECDSA(mapHashFunc(h))) signer.update(data) @@ -473,7 +554,7 @@ class _CertMaker(_PKIObjMaker): return obj -class Cert(_PKIObj): +class Cert(object): """ Wrapper for the X509_Cert from layers/x509.py. Use the 'x509Cert' attribute to access original object. @@ -673,7 +754,7 @@ class _CRLMaker(_PKIObjMaker): return obj -class CRL(_PKIObj): +class CRL(object): """ Wrapper for the X509_CRL from layers/x509.py. Use the 'x509CRL' attribute to access original object. diff --git a/scapy/layers/tls/crypto/pkcs1.py b/scapy/layers/tls/crypto/pkcs1.py index 7da7182d30ca4a20c282f25f20b103791470eef7..e4b49c4104730f21f05acebae714e50699ac6986 100644 --- a/scapy/layers/tls/crypto/pkcs1.py +++ b/scapy/layers/tls/crypto/pkcs1.py @@ -95,7 +95,8 @@ _hashFuncParams = {} if conf.crypto_valid: def _hashWrapper(hash_algo, message, backend=default_backend()): - digest = hashes.Hash(hash_algo, backend).update(message) + digest = hashes.Hash(hash_algo(), backend) + digest.update(message) return digest.finalize() _hashFuncParams = { @@ -345,14 +346,14 @@ class _EncryptAndVerifyRSA(object): Not intended to be used directly. Please, see encrypt() method. """ - n = self.modulus + n = self._modulus if isinstance(m, int): m = long(m) if (not isinstance(m, long)) or m > n-1: warning("Key._rsaep() expects a long between 0 and n-1") return None - return pow(m, self.pubExp, n) + return pow(m, self._pubExp, n) @crypto_validator @@ -425,7 +426,7 @@ class _EncryptAndVerifyRSA(object): sLen = hLen # 1) Length checking - modBits = self.modulusLen + modBits = self._modulusLen k = modBits / 8 if len(S) != k: return False @@ -459,7 +460,7 @@ class _EncryptAndVerifyRSA(object): """ # 1) Length checking - k = self.modulusLen / 8 + k = self._modulusLen / 8 if len(S) != k: warning("invalid signature (len(S) != k)") return False @@ -518,7 +519,7 @@ class _EncryptAndVerifyRSA(object): """ if t is None: # RSAVP1 S = pkcs_os2ip(S) - n = self.modulus + n = self._modulus if S > n-1: warning("Signature to be verified is too long for key modulus") return False @@ -584,14 +585,15 @@ class _DecryptAndSignRSA(object): Not intended to be used directly. Please, see decrypt() method. """ - n = self.modulus + n = self._modulus if isinstance(c, int): c = long(c) if (not isinstance(c, long)) or c > n-1: warning("Key._rsaep() expects a long between 0 and n-1") return None - return pow(c, self.privExp, n) + privExp = self.key.private_numbers().d + return pow(c, privExp, n) def decrypt(self, C, t="pkcs", h=None, mgf=None, L=None): @@ -666,7 +668,7 @@ class _DecryptAndSignRSA(object): sLen = hLen # 1) EMSA-PSS encoding - modBits = self.modulusLen + modBits = self._modulusLen k = modBits / 8 EM = pkcs_emsa_pss_encode(M, modBits - 1, h, mgf, sLen) if EM is None: @@ -696,7 +698,7 @@ class _DecryptAndSignRSA(object): """ # 1) EMSA-PKCS1-v1_5 encoding - k = self.modulusLen / 8 + k = self._modulusLen / 8 EM = pkcs_emsa_pkcs1_v1_5_encode(M, k, h) if EM is None: warning("Key._rsassa_pkcs1_v1_5_sign(): unable to encode") @@ -745,14 +747,14 @@ class _DecryptAndSignRSA(object): """ if t is None: # RSASP1 M = pkcs_os2ip(M) - n = self.modulus + n = self._modulus if M > n-1: warning("Message to be signed is too long for key modulus") return None s = self._rsasp1(M) if s is None: return None - return pkcs_i2osp(s, self.modulusLen/8) + return pkcs_i2osp(s, self._modulusLen/8) elif t == "pkcs": # RSASSA-PKCS1-v1_5-SIGN if h is None: h = "sha1" diff --git a/scapy/layers/tls/keyexchange.py b/scapy/layers/tls/keyexchange.py index faf69bfa80ff54a2fe06b451ffbf114743173306..cfff57b6408c1df21de7c1119196a5edd8dcebc0 100644 --- a/scapy/layers/tls/keyexchange.py +++ b/scapy/layers/tls/keyexchange.py @@ -17,7 +17,7 @@ from scapy.config import conf from scapy.error import warning from scapy.fields import * from scapy.packet import Packet, Raw, Padding -from scapy.layers.tls.cert import PubKey, PrivKey +from scapy.layers.tls.cert import PubKeyRSA, PrivKeyRSA from scapy.layers.tls.session import _GenericTLSSessionInheritance from scapy.layers.tls.basefields import _tls_version, _TLSClientVersionField from scapy.layers.tls.crypto.pkcs1 import pkcs_i2osp, pkcs_os2ip @@ -610,18 +610,18 @@ class ServerRSAParams(_GenericTLSSessionInheritance): encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption()) - k = PrivKey(pem_k) + k = PrivKeyRSA(pem_k) self.tls_session.server_tmp_rsa_key = k + pubNum = k.pubkey.public_numbers() - modlen = k.modulusLen / 8 if self.rsamod is "": - self.rsamod = pkcs_i2osp(k.modulus, modlen) + self.rsamod = pkcs_i2osp(pubNum.n, k.pubkey.key_size/8) if self.rsamodlen is None: self.rsamodlen = len(self.rsamod) - rsaexplen = math.ceil(math.log(k.pubExp)/math.log(2)/8.) + rsaexplen = math.ceil(math.log(pubNum.e)/math.log(2)/8.) if self.rsaexp is "": - self.rsaexp = pkcs_i2osp(k.pubExp, rsaexplen) + self.rsaexp = pkcs_i2osp(pubNum.e, rsaexplen) if self.rsaexplen is None: self.rsaexplen = len(self.rsaexp) @@ -629,7 +629,7 @@ class ServerRSAParams(_GenericTLSSessionInheritance): mLen = self.rsamodlen m = self.rsamod e = self.rsaexp - self.tls_session.server_tmp_rsa_key = PubKey((e, m, mLen)) + self.tls_session.server_tmp_rsa_key = PubKeyRSA((e, m, mLen)) def guess_payload_class(self, p): return Padding diff --git a/test/cert.uts b/test/cert.uts index 69b981b5deff396dad3f7b69de8c1d31cb2db952..c43652cd7ae12251078acb7f0264584189f8df7c 100644 --- a/test/cert.uts +++ b/test/cert.uts @@ -32,6 +32,7 @@ TL1SGhzwfinME1e6p3Hm//pDjuJvFaY22k05LgLuyqc59vFiB3Toldz8+AbMNjvz AwIDAQAB -----END PUBLIC KEY----- """) +x_pubNum = x.pubkey.public_numbers() type(x) is PubKeyRSA = PubKey class : key format is PEM @@ -39,16 +40,17 @@ x.frmt == "PEM" = PubKey class : Importing DER-encoded RSA Key y = PubKey('0\x82\x01"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\x98Wj?\xe9\xd3\x11\x9b\xa4KIK?\xec\xa3\xd6\x03H\x9a\xc1\x08\x7f\xb3\xf6\xc9$\xee\x9d\xc7\x98\xc7\t&\xe1Q9A\x17\x83m\xbd\x8b\xe7\xf1\xcb\x03\xdaO\x98\x87\x90-*\xbf\x06\x03\xb5\x99\xe3\x9cl\xe4\x89\xd9\x85GCo\x0cC\x9e\xbe\xf0*\xdb\xea}\xbc\x8b\'\x17\xe2\x1at\x1fp1D\x08\xe1\xd1\xe7W\xfa\xad\xf2\x8a[\xd8\'\x85\xbd\xfc\xd9\xc8o\xfc\x00g\x04\xb4\xa0\x98\x9f\xfe\xd4\xe4T^\xfb\x1f&\xc0|\x97^\xe4J\x9b\xa7\xe6\xc2(\x8b\xccZv\xa6n\x1fCEL\xa3\xac\x10Y\xa3\x97@\xd6\x8d\xf6\xce\x9b\x85\x06\xb2]#\xc7fR\x9c=\x82\xd7\xf4\x17@Z\xf2Q\x99\x9b\xc5*sA\xb2]\xe5\xce%A6\xbb\xb0\xa22\xed\xcc\xef\xb0L\xe9\x92\xcbM\xca0\xe7\xe6\xd0"i&L\xbdR\x1a\x1c\xf0~)\xcc\x13W\xba\xa7q\xe6\xff\xfaC\x8e\xe2o\x15\xa66\xdaM9.\x02\xee\xca\xa79\xf6\xf1b\x07t\xe8\x95\xdc\xfc\xf8\x06\xcc6;\xf3\x03\x02\x03\x01\x00\x01') +y_pubNum = y.pubkey.public_numbers() type(y) is PubKeyRSA = PubKey class : key format is DER y.frmt == "DER" = PubKey class : checking modulus value -x.modulus == y.modulus and x.modulus == 19231328316532061413420367242571475005688288081144416166988378525696075445024135424022026378563116068168327239354659928492979285632474448448624869172454076124150405352043642781483254546569202103296262513098482624188672299255268092629150366527784294463900039290024710152521604731213565912934889752122898104556895316819303096201441834849255370122572613047779766933573375974464479123135292080801384304131606933504677232323037116557327478512106367095125103346134248056463878553619525193565824925835325216545121044922690971718737998420984924512388011040969150550056783451476150234324593710633552558175109683813482739004163L +x_pubNum.n == y_pubNum.n and x_pubNum.n == 19231328316532061413420367242571475005688288081144416166988378525696075445024135424022026378563116068168327239354659928492979285632474448448624869172454076124150405352043642781483254546569202103296262513098482624188672299255268092629150366527784294463900039290024710152521604731213565912934889752122898104556895316819303096201441834849255370122572613047779766933573375974464479123135292080801384304131606933504677232323037116557327478512106367095125103346134248056463878553619525193565824925835325216545121044922690971718737998420984924512388011040969150550056783451476150234324593710633552558175109683813482739004163L = PubKey class : checking public exponent value -x.pubExp == y.pubExp and x.pubExp == 65537L +x_pubNum.e == y_pubNum.e and x_pubNum.e == 65537L = PubKey class : Importing PEM-encoded ECDSA public key z = PubKey(""" @@ -100,18 +102,20 @@ i5+Mqk9ZCGdoReVbAovJFoRqe7Fj9yWM+b1awGjL0bOTtnqx0iljob6uFyhpl1xg W3a3ICJ/ZYLvkgb4IBEteOwWpp37fX57vzhW8EmUV2UX7ve1uNRI -----END RSA PRIVATE KEY----- """) +x_privNum = x.key.private_numbers() +x_pubNum = x.pubkey.public_numbers() type(x) is PrivKeyRSA = PrivKey class : checking public attributes -assert(x.modulus == 19231328316532061413420367242571475005688288081144416166988378525696075445024135424022026378563116068168327239354659928492979285632474448448624869172454076124150405352043642781483254546569202103296262513098482624188672299255268092629150366527784294463900039290024710152521604731213565912934889752122898104556895316819303096201441834849255370122572613047779766933573375974464479123135292080801384304131606933504677232323037116557327478512106367095125103346134248056463878553619525193565824925835325216545121044922690971718737998420984924512388011040969150550056783451476150234324593710633552558175109683813482739004163L) -x.pubExp == 65537L +assert(x_pubNum.n == 19231328316532061413420367242571475005688288081144416166988378525696075445024135424022026378563116068168327239354659928492979285632474448448624869172454076124150405352043642781483254546569202103296262513098482624188672299255268092629150366527784294463900039290024710152521604731213565912934889752122898104556895316819303096201441834849255370122572613047779766933573375974464479123135292080801384304131606933504677232323037116557327478512106367095125103346134248056463878553619525193565824925835325216545121044922690971718737998420984924512388011040969150550056783451476150234324593710633552558175109683813482739004163L) +x_pubNum.e == 65537L = PrivKey class : checking private attributes -assert(x.prime1 == 140977881300857803928857666115326329496639762170623218602431133528876162476487960230341078724702018316260690172014674492782486113504117653531825010840338251572887403113276393351318549036549656895326851872473595350667293402676143426484331639796163189182788306480699144107905869179435145810212051656274284113969L) -assert(x.prime2 == 136413798668820291889092636919077529673097927884427227010121877374504825870002258140616512268521246045642663981036167305976907058413796938050224182519965099316625879807962173794483933183111515251808827349718943344770056106787713032506379905031673992574818291891535689493330517205396872699985860522390496583027L) -assert(x.exponent1 == 46171616708754015342920807261537213121074749458020000367465429453038710215532257783908950878847126373502288079285334594398328912526548076894076506899568491565992572446455658740752572386903609191774044411412991906964352741123956581870694330173563737928488765282233340389888026245745090096745219902501964298369L) -assert(x.exponent2 == 58077388505079936284685944662039782610415160654764308528562806086690474868010482729442634318267235411531220690585030443434512729356878742778542733733189895801341155353491318998637269079682889033003797865508917973141494201620317820971253064836562060222814287812344611566640341960495346782352037479526674026269L) -x.privExp == 15879630313397508329451198152673380989865598204237760057319927734227125481903063742175442230739018051313441697936698689753842471306305671266572085925009572141819112648211571007521954312641597446020984266846581125287547514750428503480880603089110687015181510081018160579576523796170439894692640171752302225125980423560965987469457505107324833137678663960560798216976668670722016960863268272661588745006387723814962668678285659376534048525020951633874488845649968990679414325096323920666486328886913648207836459784281744709948801682209478580185160477801656666089536527545026197569990716720623647770979759861119273292833L +assert(x_privNum.p == 140977881300857803928857666115326329496639762170623218602431133528876162476487960230341078724702018316260690172014674492782486113504117653531825010840338251572887403113276393351318549036549656895326851872473595350667293402676143426484331639796163189182788306480699144107905869179435145810212051656274284113969L) +assert(x_privNum.q == 136413798668820291889092636919077529673097927884427227010121877374504825870002258140616512268521246045642663981036167305976907058413796938050224182519965099316625879807962173794483933183111515251808827349718943344770056106787713032506379905031673992574818291891535689493330517205396872699985860522390496583027L) +assert(x_privNum.dmp1 == 46171616708754015342920807261537213121074749458020000367465429453038710215532257783908950878847126373502288079285334594398328912526548076894076506899568491565992572446455658740752572386903609191774044411412991906964352741123956581870694330173563737928488765282233340389888026245745090096745219902501964298369L) +assert(x_privNum.dmq1 == 58077388505079936284685944662039782610415160654764308528562806086690474868010482729442634318267235411531220690585030443434512729356878742778542733733189895801341155353491318998637269079682889033003797865508917973141494201620317820971253064836562060222814287812344611566640341960495346782352037479526674026269L) +x_privNum.d == 15879630313397508329451198152673380989865598204237760057319927734227125481903063742175442230739018051313441697936698689753842471306305671266572085925009572141819112648211571007521954312641597446020984266846581125287547514750428503480880603089110687015181510081018160579576523796170439894692640171752302225125980423560965987469457505107324833137678663960560798216976668670722016960863268272661588745006387723814962668678285659376534048525020951633874488845649968990679414325096323920666486328886913648207836459784281744709948801682209478580185160477801656666089536527545026197569990716720623647770979759861119273292833L = PrivKey class : Importing PEM-encoded ECDSA private key y = PrivKey(""" @@ -134,13 +138,13 @@ y.key.private_numbers().private_value == 907197864312630821346709366701808397820 ########### PKCS crypto ############################################# # these are legacy tests which should be removed eventually (see our pkcs1.py) -+ PKCS legacy tests ++ PKCS 1 legacy tests -= PKCS legacy : RSA signature & verification -m = "Testing our PKCS legacy methods" += PKCS 1 legacy : RSA signature & verification +m = "Testing our PKCS #1 legacy methods" s = x.sign_legacy(m, t="pkcs", h="tls") -assert(s == "Zp\xd7`\x80\x97\x18\xc5t\xf1\xc2ZZ\x1e'\xee\xf1\x8d\xc2\xfat#Z\xde\xa5gnZ\xb5\xad\xc0?\xe0\xb5\xef\xe4\xc3Z\xe1>\x04@'<\xda\x8dtd\xd1Y\xdfm\x93\x88Sg\x9d\xc42\x87\x01\xd1\xfd\x03$C\x07A\x89\x86\xf4\x87*\x96\xd7\xf0\x0c\x19\x12\xf5\xa5\xa6\x07\x8b\xe6\x04c\x1a8\x18B\xfb\\t\xdf\x9f:\xdc\xa8\x0eg],I\xdc\xcc\x99\xa8\x93rl\xb3\xad\x91Kd\x92H\xf4\xfc\xc2\xf9\xf0\xe0`7\xb0\xf7E\x97\\k\xec\xfb\xff\xcff\xb3\xbf\xf6\xdf(\xae]\x01\x85\x06\xdd\x91\x91(\xf1,\x15c\x8b\x0b,\x1f \xc2\x1aN/\xeeJ$Qz\x9a\xc0\x8c\x99\x80\xe2\xba\xfdpu\x15p\x18;3\xff\x90\xbb$\xf1-VT\xe5'F\xed*0\xadXd9T!\x8au]\xc1\xe8\xf0\xb3\x04\x0f6b\xf2\x7f\xa8\x06}\x97*\xec\x97X\x94g\xd1\xc3a\x11\x1a4\xd0\x01\xb3yp\xdc\xdf5{\xb7\x9d\x97y`\xa6\xde\x03\xe9\xa6\x14s\x0fa") -x_pub = PubKey((x.pubExp, x.modulus, x.modulusLen)) +assert(s == "\x0cm\x8a\x8f\xae`o\xcdC=\xfea\xf4\xff\xf0i\xfe\xa3!\xfd\xa5=*\x99?\x08!\x03A~\xa3-B\xe8\xca\xaf\xb4H|\xa3\x98\xe9\xd5U\xfdL\xb1\x9c\xd8\xb2{\xa1/\xfcr\x8c\xa7\xd3\xa9%\xde\x13\xa8\xf6\xc6<\xc7\xdb\xe3\xa62\xeb\xe9?\xe5by\xc2\x9e\xad\xec\x92:\x14\xd96\xa8\xc0+\xea8'{=\x91$\xdf\xed\xe1+eF8\x9fI\x1f\xa1\xcb4s\xd1#\xdf\xa11\x88o\x050i Hg\x0690\xe6\xe8?\\<:k\x94\x82\x91\x0f\x06\xc7>ZQ\xc2\xcdn\xdb\xf4\x9d\x7f!\xa9>\xe8\xea\xb3\xd83]\x8d\x90\xd4\xa0b\xe6\xe6$d[\xe4\xb4 |W\xb2t\x8c\xb2\xd5>>+\xf1\xa6W'\xaf\xc2CU\x82\x13\xc4\x0b\xc4vD*\xc3\xef\xa6s\nQ\xe6\rS@B\xd2\xa4V\xdc\xd1D\x7f\x00\xaa\xac\xac\x96i\xf1kg*\xe9*\x90a@\xc8uDy\x16\xe2\x03\xd1\x9fa\xe2s\xdb\xees\xa4\x8cna\xba\xdaE\x006&\xa4") +x_pub = PubKey((x._pubExp, x._modulus, x._modulusLen)) x_pub.verify_legacy(m, s, t="pkcs", h="tls") @@ -207,8 +211,9 @@ x.notAfter == (2026, 3, 30, 7, 38, 59, 0, 89, -1) = Cert class : Checking RSA public key assert(type(x.pubKey) is PubKeyRSA) -assert(x.pubKey.modulus == 19231328316532061413420367242571475005688288081144416166988378525696075445024135424022026378563116068168327239354659928492979285632474448448624869172454076124150405352043642781483254546569202103296262513098482624188672299255268092629150366527784294463900039290024710152521604731213565912934889752122898104556895316819303096201441834849255370122572613047779766933573375974464479123135292080801384304131606933504677232323037116557327478512106367095125103346134248056463878553619525193565824925835325216545121044922690971718737998420984924512388011040969150550056783451476150234324593710633552558175109683813482739004163L) -x.pubKey.pubExp == 0x10001 +x_pubNum = x.pubKey.pubkey.public_numbers() +assert(x_pubNum.n == 19231328316532061413420367242571475005688288081144416166988378525696075445024135424022026378563116068168327239354659928492979285632474448448624869172454076124150405352043642781483254546569202103296262513098482624188672299255268092629150366527784294463900039290024710152521604731213565912934889752122898104556895316819303096201441834849255370122572613047779766933573375974464479123135292080801384304131606933504677232323037116557327478512106367095125103346134248056463878553619525193565824925835325216545121044922690971718737998420984924512388011040969150550056783451476150234324593710633552558175109683813482739004163L) +x_pubNum.e == 0x10001 = Cert class : Checking extensions assert(x.cA) diff --git a/test/tls/example_client.py b/test/tls/example_client.py index 3ed4256203a246ef25c6001efca50859ad329f56..3c5f9794c6b5f7183061e150d1e8725f1a3a165f 100755 --- a/test/tls/example_client.py +++ b/test/tls/example_client.py @@ -13,12 +13,12 @@ server at 127.0.0.1:4433, with suite TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA. import os import sys -from scapy.layers.tls.automaton import TLSClientAutomaton -from scapy.layers.tls.handshake import TLSClientHello - basedir = os.path.abspath(os.path.join(os.path.dirname(__file__),"../../")) sys.path=[basedir]+sys.path +from scapy.layers.tls.automaton import TLSClientAutomaton +from scapy.layers.tls.handshake import TLSClientHello + if len(sys.argv) == 2: ch = TLSClientHello(ciphers=int(sys.argv[1], 16)) diff --git a/test/tls/example_server.py b/test/tls/example_server.py index 30ffd2748bfe3451a8dbd199d978f5c3395e3512..7d4d9664c1ba49386032cca6e47f1a1a6c38cfae 100755 --- a/test/tls/example_server.py +++ b/test/tls/example_server.py @@ -14,11 +14,11 @@ will be preferred to any other suite the client might propose. import os import sys -from scapy.layers.tls.automaton import TLSServerAutomaton - basedir = os.path.abspath(os.path.join(os.path.dirname(__file__),"../../")) sys.path=[basedir]+sys.path +from scapy.layers.tls.automaton import TLSServerAutomaton + if len(sys.argv) == 2: pcs = int(sys.argv[1], 16) diff --git a/test/tls/travis_test_client.py b/test/tls/travis_test_client.py index edfa5a5bf962c2eadfba09c2d670ab70f35e16a6..7bbdeb9b3404f0f940667112cbe86a6cc95a708a 100755 --- a/test/tls/travis_test_client.py +++ b/test/tls/travis_test_client.py @@ -16,12 +16,12 @@ Reception of the exact send_data on the server is to be checked externally. import os import sys -from scapy.layers.tls.automaton import TLSClientAutomaton -from scapy.layers.tls.handshake import TLSClientHello - basedir = os.path.abspath(os.path.join(os.path.dirname(__file__),"../../")) sys.path=[basedir]+sys.path +from scapy.layers.tls.automaton import TLSClientAutomaton +from scapy.layers.tls.handshake import TLSClientHello + send_data = cipher_suite_code = version = None diff --git a/test/tls/travis_test_server.py b/test/tls/travis_test_server.py index 4db52f20df8300de51d1c100355ae49d87199fe9..e262c63ecb1e6d263c7e1af878c5bca02824b2db 100755 --- a/test/tls/travis_test_server.py +++ b/test/tls/travis_test_server.py @@ -18,11 +18,11 @@ import sys from contextlib import contextmanager from StringIO import StringIO -from scapy.layers.tls.automaton import TLSServerAutomaton - basedir = os.path.abspath(os.path.join(os.path.dirname(__file__),"../../")) sys.path=[basedir]+sys.path +from scapy.layers.tls.automaton import TLSServerAutomaton + @contextmanager def captured_output(): diff --git a/test/x509.uts b/test/x509.uts index 1d3b2333d5271a8e59a8361859e71166c534f25d..e481e0ea06bc2eb355691d642d52ef6bad01da22 100644 --- a/test/x509.uts +++ b/test/x509.uts @@ -243,3 +243,6 @@ assert(singleResponse.thisUpdate == ASN1_GENERALIZED_TIME("20160914121000Z")) assert(singleResponse.nextUpdate == ASN1_GENERALIZED_TIME("20160921112500Z")) singleResponse.singleExtensions is None += OCSP class : OCSP Response reconstruction +str(response) == s +