def _recomputeDigest(self): """ Digest the fields and set self._digest to the hex digest. """ sha256 = hashes.Hash(hashes.SHA256(), backend=default_backend()) number = bytearray(4) # Debug: sync-state.proto defines seq and session as uint64, but # the original ChronoChat-js only digests 32 bits. self._int32ToLittleEndian(self._sessionNo, number) sha256.update(Blob(number, False).toBytes()) self._int32ToLittleEndian(self._sequenceNo, number) sha256.update(Blob(number, False).toBytes()) sequenceDigest = sha256.finalize() sha256 = hashes.Hash(hashes.SHA256(), backend=default_backend()) # Use Blob to convert a string to UTF-8 if needed. sha256.update(Blob(self._dataPrefix, False).toBytes()); nameDigest = sha256.finalize() sha256 = hashes.Hash(hashes.SHA256(), backend=default_backend()) sha256.update(nameDigest) sha256.update(sequenceDigest) nodeDigest = sha256.finalize() # Use Blob to convert a str (Python 2) or bytes (Python 3) to hex. self._digest = Blob(nodeDigest, False).toHex()
def _verify_signature_with_pubkey(self, signed_info_c14n, raw_signature, key_value, signature_alg): if "ecdsa-" in signature_alg: ec_key_value = self._find(key_value, "ECKeyValue", namespace="dsig11") named_curve = self._find(ec_key_value, "NamedCurve", namespace="dsig11") public_key = self._find(ec_key_value, "PublicKey", namespace="dsig11") key_data = b64decode(public_key.text)[1:] x = bytes_to_long(key_data[:len(key_data)//2]) y = bytes_to_long(key_data[len(key_data)//2:]) curve_class = self.known_ecdsa_curves[named_curve.get("URI")] key = ec.EllipticCurvePublicNumbers(x=x, y=y, curve=curve_class()).public_key(backend=default_backend()) verifier = key.verifier(raw_signature, ec.ECDSA(self._get_signature_digest_method(signature_alg))) elif "dsa-" in signature_alg: dsa_key_value = self._find(key_value, "DSAKeyValue") p = self._get_long(dsa_key_value, "P") q = self._get_long(dsa_key_value, "Q") g = self._get_long(dsa_key_value, "G", require=False) y = self._get_long(dsa_key_value, "Y") pn = dsa.DSAPublicNumbers(y=y, parameter_numbers=dsa.DSAParameterNumbers(p=p, q=q, g=g)) key = pn.public_key(backend=default_backend()) der_seq = DERSequenceOfIntegers([bytes_to_long(raw_signature[:len(raw_signature)//2]), bytes_to_long(raw_signature[len(raw_signature)//2:])]) sig_as_der_seq = der_encoder.encode(der_seq) verifier = key.verifier(sig_as_der_seq, self._get_signature_digest_method(signature_alg)) elif "rsa-" in signature_alg: rsa_key_value = self._find(key_value, "RSAKeyValue") modulus = self._get_long(rsa_key_value, "Modulus") exponent = self._get_long(rsa_key_value, "Exponent") key = rsa.RSAPublicNumbers(e=exponent, n=modulus).public_key(backend=default_backend()) verifier = key.verifier(raw_signature, padding=PKCS1v15(), algorithm=self._get_signature_digest_method(signature_alg)) else: raise NotImplementedError() verifier.update(signed_info_c14n) verifier.verify()
def test_invalid_key(self): kdf = PBKDF2HMAC(hashes.SHA1(), 20, b"salt", 10, default_backend()) key = kdf.derive(b"password") kdf = PBKDF2HMAC(hashes.SHA1(), 20, b"salt", 10, default_backend()) with pytest.raises(InvalidKey): kdf.verify(b"password2", key)
def create_ca(self, cn=ISSUER_CN): """Create root CA. :returns: bytes -- Root CA in PEM format. """ self.ca_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend(), ) self.ca_public_key = self.ca_key.public_key() subject = self.issuer = x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, six.text_type(cn)), ]) builder = x509.CertificateBuilder() builder = builder.subject_name(subject) builder = builder.issuer_name(self.issuer) builder = builder.public_key(self.ca_public_key) builder = builder.serial_number(x509.random_serial_number()) builder = builder.not_valid_before(self.now) builder = builder.not_valid_after(self.now + self.delta) builder = builder.add_extension( x509.KeyUsage( digital_signature=False, content_commitment=False, key_encipherment=False, data_encipherment=False, key_agreement=False, key_cert_sign=True, crl_sign=True, encipher_only=False, decipher_only=False, ), critical=True, ) builder = builder.add_extension( x509.BasicConstraints(ca=True, path_length=None), critical=True, ) builder = builder.add_extension( x509.SubjectKeyIdentifier.from_public_key(self.ca_public_key), critical=False, ) builder = builder.add_extension( x509.AuthorityKeyIdentifier.from_issuer_public_key( self.ca_public_key ), critical=False, ) cert = builder.sign(self.ca_key, hashes.SHA256(), default_backend()) return cert.public_bytes(serialization.Encoding.PEM)
def setUp(self): self.example_xml_files = (os.path.join(os.path.dirname(__file__), "example.xml"), os.path.join(os.path.dirname(__file__), "example2.xml")) self.keys = dict(hmac=b"secret", rsa=rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()), dsa=dsa.generate_private_key(key_size=1024, backend=default_backend()), ecdsa=ec.generate_private_key(curve=ec.SECP384R1(), backend=default_backend()))
def __init__(self, secret, algorithm=None): if algorithm is None: algorithm = DEFAULT_SIGN_ALGORITHM assert algorithm in ALGORITHMS, "Unknown algorithm" if isinstance(secret, six.string_types): secret = secret.encode("ascii") self._rsa_public = None self._rsa_private = None self._hash = None self.sign_algorithm, self.hash_algorithm = algorithm.split('-') if self.sign_algorithm == 'rsa': try: self._rsahash = HASHES[self.hash_algorithm] self._rsa_private = serialization.load_pem_private_key(secret, None, backend=default_backend()) self._rsa_public = self._rsa_private.public_key() except ValueError as e: try: self._rsa_public = serialization.load_pem_public_key(secret, backend=default_backend()) except ValueError as e: raise HttpSigException("Invalid key.") elif self.sign_algorithm == 'hmac': self._hash = hmac.HMAC(secret, HASHES[self.hash_algorithm](), backend=default_backend())
def getPublicKey(registry=None): ''' Return the user's public key (generating and saving a new key pair if necessary) ''' registry = registry or Registry_Base_URL pubkey_pem = None if _isPublicRegistry(registry): pubkey_pem = settings.getProperty('keys', 'public') else: for s in _getSources(): if _sourceMatches(s, registry): if 'keys' in s and s['keys'] and 'public' in s['keys']: pubkey_pem = s['keys']['public'] break if not pubkey_pem: pubkey_pem, privatekey_pem = _generateAndSaveKeys() else: # settings are unicode, we should be able to safely decode to ascii for # the key though, as it will either be hex or PEM encoded: pubkey_pem = pubkey_pem.encode('ascii') # if the key doesn't look like PEM, it might be hex-encided-DER (which we # used historically), so try loading that: if b'-----BEGIN PUBLIC KEY-----' in pubkey_pem: pubkey = serialization.load_pem_public_key(pubkey_pem, default_backend()) else: pubkey_der = binascii.unhexlify(pubkey_pem) pubkey = serialization.load_der_public_key(pubkey_der, default_backend()) return _pubkeyWireFormat(pubkey)
def encrypt(keyBits, plainData, params): """ Encrypt the plainData using the keyBits according the encrypt params. :param Blob keyBits: The key value. :param Blob plainData: The data to encrypt. :param EncryptParams params: This encrypts according to params.getAlgorithmType() and other params as needed such as params.getInitialVector(). :return: The encrypted data. :rtype: Blob """ # For the cryptography package, we have to do the padding. padLength = 16 - (plainData.size() % 16) if sys.version_info[0] <= 2: pad = chr(padLength) * padLength else: pad = bytes([padLength]) * padLength if params.getAlgorithmType() == EncryptAlgorithmType.AesEcb: cipher = Cipher(algorithms.AES( keyBits.toBytes()), modes.ECB(), backend = default_backend()) elif params.getAlgorithmType() == EncryptAlgorithmType.AesCbc: cipher = Cipher(algorithms.AES( keyBits.toBytes()), modes.CBC(params.getInitialVector().toBytes()), backend = default_backend()) else: raise RuntimeError("unsupported encryption mode") encryptor = cipher.encryptor() return Blob( encryptor.update(plainData.toBytes() + pad) + encryptor.finalize(), False)
def decrypt(keyBits, encryptedData, params): """ Decrypt the encryptedData using the keyBits according the encrypt params. :param Blob keyBits: The key value. :param Blob encryptedData: The data to decrypt. :param EncryptParams params: This decrypts according to params.getAlgorithmType() and other params as needed such as params.getInitialVector(). :return: The decrypted data. :rtype: Blob """ if params.getAlgorithmType() == EncryptAlgorithmType.AesEcb: cipher = Cipher(algorithms.AES( keyBits.toBytes()), modes.ECB(), backend = default_backend()) elif params.getAlgorithmType() == EncryptAlgorithmType.AesCbc: cipher = Cipher(algorithms.AES( keyBits.toBytes()), modes.CBC(params.getInitialVector().toBytes()), backend = default_backend()) else: raise RuntimeError("unsupported encryption mode") # For the cryptography package, we have to remove the padding. decryptor = cipher.decryptor() resultWithPad = decryptor.update(encryptedData.toBytes()) + decryptor.finalize() if sys.version_info[0] <= 2: padLength = ord(resultWithPad[-1]) else: padLength = resultWithPad[-1] return Blob(resultWithPad[:-padLength], False)
def test_encode_decode_with_rsa_sha512(self): # PEM-formatted RSA key with open('tests/testkey_rsa', 'r') as rsa_priv_file: priv_rsakey = load_pem_private_key(ensure_bytes(rsa_priv_file.read()), password=None, backend=default_backend()) jwt_message = jwt.encode(self.payload, priv_rsakey, algorithm='RS512') with open('tests/testkey_rsa.pub', 'r') as rsa_pub_file: pub_rsakey = load_ssh_public_key(ensure_bytes(rsa_pub_file.read()), backend=default_backend()) assert jwt.decode(jwt_message, pub_rsakey) load_output = jwt.load(jwt_message) jwt.verify_signature(key=pub_rsakey, *load_output) # string-formatted key with open('tests/testkey_rsa', 'r') as rsa_priv_file: priv_rsakey = rsa_priv_file.read() jwt_message = jwt.encode(self.payload, priv_rsakey, algorithm='RS512') with open('tests/testkey_rsa.pub', 'r') as rsa_pub_file: pub_rsakey = rsa_pub_file.read() assert jwt.decode(jwt_message, pub_rsakey) load_output = jwt.load(jwt_message) jwt.verify_signature(key=pub_rsakey, *load_output)
def test_encode_decode_with_ecdsa_sha384(self): # PEM-formatted EC key with open('tests/testkey_ec', 'r') as ec_priv_file: priv_eckey = load_pem_private_key(ensure_bytes(ec_priv_file.read()), password=None, backend=default_backend()) jwt_message = jwt.encode(self.payload, priv_eckey, algorithm='ES384') with open('tests/testkey_ec.pub', 'r') as ec_pub_file: pub_eckey = load_pem_public_key(ensure_bytes(ec_pub_file.read()), backend=default_backend()) assert jwt.decode(jwt_message, pub_eckey) load_output = jwt.load(jwt_message) jwt.verify_signature(key=pub_eckey, *load_output) # string-formatted key with open('tests/testkey_ec', 'r') as ec_priv_file: priv_eckey = ec_priv_file.read() jwt_message = jwt.encode(self.payload, priv_eckey, algorithm='ES384') with open('tests/testkey_ec.pub', 'r') as ec_pub_file: pub_rsakey = ec_pub_file.read() assert jwt.decode(jwt_message, pub_eckey) load_output = jwt.load(jwt_message) jwt.verify_signature(key=pub_eckey, *load_output)
def generatePrivateKey(keyParams): """ Generate a key pair according to keyParams and return a new TpmPrivateKey with the private key. You can get the public key with derivePublicKey. :param KeyParams keyParams: The parameters of the key. :return: A new TpmPrivateKey. :rtype: TpmPrivateKey :raises ValueError: If the key type is not supported. :raises TpmPrivateKey.Error: For an invalid key size, or an error generating. """ if (keyParams.getKeyType() == KeyType.RSA or keyParams.getKeyType() == KeyType.EC): if keyParams.getKeyType() == KeyType.RSA: privateKey = rsa.generate_private_key( public_exponent = 65537, key_size = keyParams.getKeySize(), backend = default_backend()) else: privateKey = ec.generate_private_key( TpmPrivateKey._getEcCurve(keyParams.getKeySize()), default_backend()) else: raise ValueError( "Cannot generate a key pair of type " + str(keyParams.getKeyType())) result = TpmPrivateKey() result._privateKey = privateKey result._keyType = keyParams.getKeyType() return result
def test_generate_cert_key_pair(self): cn = 'testCN' bit_length = 512 # Attempt to generate a cert/key pair cert_object = self.cert_generator.generate_cert_key_pair( cn=cn, validity=2 * 365 * 24 * 60 * 60, bit_length=bit_length, passphrase=self.ca_private_key_passphrase, ca_cert=self.ca_certificate, ca_key=self.ca_private_key, ca_key_pass=self.ca_private_key_passphrase ) # Validate that the cert and key are loadable cert = x509.load_pem_x509_certificate( data=cert_object.certificate, backend=backends.default_backend()) self.assertIsNotNone(cert) key = serialization.load_pem_private_key( data=cert_object.private_key, password=cert_object.private_key_passphrase, backend=backends.default_backend()) self.assertIsNotNone(key)
def _format_public_key(self, key): if isinstance(key, str): jwkey = json_decode(key) if 'kty' not in jwkey: raise ValueError('Invalid key, missing "kty" attribute') if jwkey['kty'] == 'RSA': pubnum = rsa.RSAPublicNumbers(jwkey['e'], jwkey['n']) pubkey = pubnum.public_key(default_backend()) elif jwkey['kty'] == 'EC': if jwkey['crv'] == 'P-256': curve = ec.SECP256R1 elif jwkey['crv'] == 'P-384': curve = ec.SECP384R1 elif jwkey['crv'] == 'P-521': curve = ec.SECP521R1 else: raise TypeError('Unsupported Elliptic Curve') pubnum = ec.EllipticCurvePublicNumbers( jwkey['x'], jwkey['y'], curve) pubkey = pubnum.public_key(default_backend()) else: raise ValueError('Unknown key type: %s' % jwkey['kty']) elif isinstance(key, rsa.RSAPublicKey): pubkey = key elif isinstance(key, ec.EllipticCurvePublicKey): pubkey = key else: raise TypeError('Unknown key type: %s' % type(key)) return pubkey.public_bytes( encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo)
def load_certificate(path): _, ext = os.path.splitext(path) with open(path, "rb") as f: if ext == ".pem": return x509.load_pem_x509_certificate(f.read(), default_backend()) else: return x509.load_der_x509_certificate(f.read(), default_backend())
def prepare_key(key_path, key_type=None): if key_type is None: key_type = 'pub' try: assert key_type.strip().lower() in PUB_TYPES + PRIV_TYPES except: raise ValueError("The type of key is not qualified. " + key_type) if key_type in PUB_TYPES: with open(key_path, 'rb') as pk_stream: key = serialization.load_ssh_public_key( data=pk_stream.read(), backend=default_backend() ) elif key_type in PRIV_TYPES: with open(key_path, 'rb') as sk_stream: key = serialization.load_pem_private_key( data=sk_stream.read(), password=None, backend=default_backend() ) else: key = None return key
def sign_update_sparkle(dmg, dsaprivpem): """ Signs the Darwin dmg and returns the base64 encoded hash. This replaces the functionality in: https://github.com/brave/Sparkle/blob/master/bin/sign_update Need to run the equivalent of the command: `$openssl dgst -sha1 -binary < "$1" | $openssl dgst -sha1 -sign "$2" | $openssl enc -base64` """ import base64 from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import padding digest = hashes.Hash(hashes.SHA1(), backend=default_backend()) sha1digest = None with open(dmg, 'rb') as dmg: with open(dsaprivpem, 'rb') as key: dmgcontent = dmg.read() digest.update(dmgcontent) sha1digest = digest.finalize() private_key = serialization.load_pem_private_key(key.read(), password=None, backend=default_backend()) signature = private_key.sign(sha1digest, hashes.SHA1()) encoded_sign = base64.encodestring(signature) if sha1digest is not None: return encoded_sign
def issue_certificate(csr, options): csr = x509.load_pem_x509_csr(csr, default_backend()) builder = x509.CertificateBuilder( issuer_name=x509.Name([ x509.NameAttribute( x509.OID_ORGANIZATION_NAME, options['authority'].authority_certificate.issuer )] ), subject_name=csr.subject, public_key=csr.public_key(), not_valid_before=options['validity_start'], not_valid_after=options['validity_end'], extensions=csr.extensions) # TODO figure out a better way to increment serial builder = builder.serial_number(int(uuid.uuid4())) private_key = serialization.load_pem_private_key( options['authority'].authority_certificate.private_key, password=None, backend=default_backend() ) cert = builder.sign(private_key, hashes.SHA256(), default_backend()) return cert.public_bytes( encoding=serialization.Encoding.PEM )
def generate_csr_and_key(common_name): """Return a dict with a new csr, public key and private key.""" private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend()) public_key = private_key.public_key() csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([ x509.NameAttribute(x509.oid.NameOID.COMMON_NAME, common_name), ])).sign(private_key, hashes.SHA256(), default_backend()) result = { 'csr': csr.public_bytes( encoding=serialization.Encoding.PEM).decode("utf-8"), 'private_key': private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption()).decode("utf-8"), 'public_key': public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo).decode( "utf-8"), } return result
def generate_key(self, slot, algorithm, pin_policy=PIN_POLICY.DEFAULT, touch_policy=TOUCH_POLICY.DEFAULT): if ALGO.is_rsa(algorithm): ensure_not_cve201715361_vulnerable_firmware_version(self.version) if algorithm not in self.supported_algorithms: raise UnsupportedAlgorithm( 'Algorithm not supported on this YubiKey: {}' .format(algorithm), algorithm_id=algorithm) data = Tlv(TAG.ALGO, six.int2byte(algorithm)) if pin_policy: data += Tlv(TAG.PIN_POLICY, six.int2byte(pin_policy)) if touch_policy: data += Tlv(TAG.TOUCH_POLICY, six.int2byte(touch_policy)) data = Tlv(0xac, data) resp = self.send_cmd(INS.GENERATE_ASYMMETRIC, 0, slot, data) if algorithm in [ALGO.RSA1024, ALGO.RSA2048]: data = _parse_tlv_dict(Tlv(resp[1:]).value) return rsa.RSAPublicNumbers( int_from_bytes(data[0x82], 'big'), int_from_bytes(data[0x81], 'big') ).public_key(default_backend()) elif algorithm in [ALGO.ECCP256, ALGO.ECCP384]: curve = ec.SECP256R1 if algorithm == ALGO.ECCP256 else ec.SECP384R1 return ec.EllipticCurvePublicNumbers.from_encoded_point( curve(), resp[5:] ).public_key(default_backend()) raise UnsupportedAlgorithm( 'Invalid algorithm: {}'.format(algorithm), algorithm_id=algorithm)
def download_crt(self, key=None): one_day = datetime.timedelta(1, 0, 0) private_key = serialization.load_pem_private_key( key, password=None, backend=default_backend() ) public_key = private_key.public_key() builder = x509.CertificateBuilder() builder = builder.subject_name(x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, self.domain), ])) builder = builder.issuer_name(x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, self.domain), ])) builder = builder.not_valid_before(datetime.datetime.today() - one_day) builder = builder.not_valid_after(datetime.datetime(2018, 8, 2)) builder = builder.serial_number(int(uuid.uuid4())) builder = builder.public_key(public_key) builder = builder.add_extension( x509.BasicConstraints(ca=False, path_length=None), critical=True, ) certificate = builder.sign( private_key=private_key, algorithm=hashes.SHA256(), backend=default_backend() ) return certificate.public_bytes(serialization.Encoding.PEM)
def generate_self_signed_cert(cert_file, key_file): """Given two file-like objects, generate an SSL key and certificate.""" one_day = datetime.timedelta(1, 0, 0) private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend() ) public_key = private_key.public_key() builder = x509.CertificateBuilder() builder = builder.subject_name(x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'), ])) builder = builder.issuer_name(x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'), ])) builder = builder.not_valid_before(datetime.datetime.today() - one_day) builder = builder.not_valid_after(datetime.datetime.today() + datetime.timedelta(365*10)) builder = builder.serial_number(int(uuid.uuid4())) builder = builder.public_key(public_key) builder = builder.add_extension( x509.BasicConstraints(ca=False, path_length=None), critical=True, ) certificate = builder.sign( private_key=private_key, algorithm=hashes.SHA256(), backend=default_backend() ) key_file.write(private_key.private_bytes( Encoding.PEM, PrivateFormat.TraditionalOpenSSL, NoEncryption() )) cert_file.write(certificate.public_bytes(Encoding.PEM))
def new_cipher(self, key, iv, digest=None): """ @param key: the secret key, a byte string @param iv: the initialization vector, a byte string. Used as the initial nonce in counter mode @param digest: also known as tag or icv. A byte string containing the digest of the encrypted data. Only use this during decryption! @return: an initialized cipher object for this algo """ if type(key) is str: key = key.encode('ascii') if self.is_aead and digest is not None: # With AEAD, the mode needs the digest during decryption. return Cipher( self.cipher(key), self.mode(iv, digest, len(digest)), default_backend(), ) else: return Cipher( self.cipher(key), self.mode(iv), default_backend(), )
def scan(self, offset=0, maxlen=None): for hit in super(CertScanner, self).scan(offset=offset, maxlen=maxlen): signature = self.address_space.read(hit + 4, 3) size = self.profile.Object( "unsigned be short", offset=hit+2, vm=self.address_space) description = None if signature.startswith(b"\x30\x82"): data = self.address_space.read(hit, size + 4) if x509: try: cert = x509.load_der_x509_certificate(data, default_backend()) description = dict(( attr.oid._name, attr.value) for attr in cert.subject) except Exception: pass yield hit, "X509", data, description elif signature.startswith(b"\x02\x01\x00"): data = self.address_space.read(hit, size + 4) if x509: try: pem = (b"-----BEGIN RSA PRIVATE KEY-----\n" + base64.b64encode(data) + b"-----END RSA PRIVATE KEY-----") key = serialization.load_pem_private_key( pem, password=None, backend=default_backend()) description = "" except Exception: pass yield hit, "RSA", data, description
def main(): message = 'This is my benchmarking message; it should really be longer' e1 = time.time() #Time key generation: EC eck1 = ec.generate_private_key(ec.SECP384R1(), default_backend()) eck2 = ec.generate_private_key(ec.SECP384R1(), default_backend()) e2 = time.time() #Time key generation: RSA rsak = rsa.generate_private_key(public_exponent=65537, key_size=4096, backend=default_backend()) e3 = time.time() #Time Encryption: EC ecct = transport_security.construct_message(message, srcprivkey=eck1, destpubkey=eck2.public_key()) e4 = time.time() #Time Encryption: RSA rsact = transport_security.get_raw_encrypted(message, pubkey=rsak.public_key()) e5 = time.time() #Time Decryption: EC ecpt = transport_security.deconstruct_message(message_dict=ecct, destprivkey=eck2, srcpubkey=eck1.public_key()) e6 = time.time() if ecpt == message: print("EC Decryption successful") else: print("EC Decryption failed") #Time Decryption: RSA rsapt = transport_security.get_raw_decrypted(ciphertext=rsact, privkey=rsak) e7 = time.time() if ecpt == message: print("RSA Decryption successful") else: print("RSA Decryption failed") with open('timing.out', 'a') as f: record = "{}\t{}\t{}\t{}\t{}\t{}\n".format(e2-e1, e3-e2, e4-e3, e5-e4, e6-e5, e7-e6) f.write(record)
def regenerate_certificate_revocation_list(self, certification_authority): logger.info("Updating CRL for CA %s" % certification_authority.common_name) one_day = datetime.timedelta(1, 0, 0) ca_cert = x509.load_pem_x509_certificate(str(certification_authority.certificate), default_backend()) ca_key = serialization.load_pem_private_key(str(certification_authority.private_key), None, default_backend()) builder = x509.CertificateRevocationListBuilder() builder = builder.issuer_name(ca_cert.subject) builder = builder.last_update(datetime.datetime.today()) builder = builder.next_update(datetime.datetime.today() + one_day) for certificate in SSLRevokedCertificate.objects.filter(certification_authority=certification_authority): logger.info("Adding certificate 0x%X" % certificate.serial_number) revoked_cert = x509.RevokedCertificateBuilder().serial_number( certificate.serial_number ).revocation_date( certificate.revocation_date.replace(tzinfo=None) ).build(default_backend()) builder = builder.add_revoked_certificate(revoked_cert) crl = builder.sign( private_key=ca_key, algorithm=hashes.SHA256(), backend=default_backend() ) logger.info('Saving models') certification_authority.revocation_list = crl.public_bytes(serialization.Encoding.PEM) print certification_authority.revocation_list certification_authority.save()
def verify_hit(self, hit, address_space): signature = address_space.read(hit + 4, 3) size = self.profile.Object( "unsigned be short", offset=hit+2, vm=address_space) description = None if signature.startswith(b"\x30\x82"): data = address_space.read(hit, size + 4) if x509: try: cert = x509.load_der_x509_certificate(data, default_backend()) description = dict(( attr.oid._name, attr.value) for attr in cert.subject) except Exception: pass return "X509", data, description elif signature.startswith(b"\x02\x01\x00"): data = address_space.read(hit, size + 4) if x509: try: pem = (b"-----BEGIN RSA PRIVATE KEY-----\n" + base64.b64encode(data) + b"-----END RSA PRIVATE KEY-----") key = serialization.load_pem_private_key( pem, password=None, backend=default_backend()) description = "" except Exception: pass return "RSA", data, description return None, None, None
def test_works_with_lowercase_attr_type_shortname(self, generator): principal = { 'uid': ['testuser'], 'mail': ['*****@*****.**'], } template_env = { 'ipacertificatesubjectbase': [ 'o=DOMAIN.EXAMPLE.COM' # lower-case attr type shortname ], } config = generator.csr_config(principal, template_env, 'userCert') key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend(), ) adaptor = csrgen.OpenSSLAdaptor(key=key) reqinfo = bytes(csrgen_ffi.build_requestinfo( config.encode('utf-8'), adaptor.get_subject_public_key_info())) csr_der = adaptor.sign_csr(reqinfo) csr = x509.load_der_x509_csr(csr_der, default_backend()) assert ( csr.subject.get_attributes_for_oid(x509.NameOID.COMMON_NAME) == [x509.NameAttribute(x509.NameOID.COMMON_NAME, u'testuser')] ) assert ( csr.subject.get_attributes_for_oid(x509.NameOID.ORGANIZATION_NAME) == [x509.NameAttribute( x509.NameOID.ORGANIZATION_NAME, u'DOMAIN.EXAMPLE.COM')] )
def update(self, data): self.buf += data if self.cipher is None: if len(self.buf) < 8: return b"" if self.buf[0:6] != FILEMAGIC: raise EncryptorError("Invalid magic bytes") cipherkeylen = struct.unpack(">H", self.buf[6:8])[0] if len(self.buf) < 8 + cipherkeylen: return b"" pad = padding.OAEP(mgf=padding.MGF1(algorithm=SHA1()), algorithm=SHA1(), label=None) try: plainkey = self.rsa_private_key.decrypt(self.buf[8:8 + cipherkeylen], pad) except AssertionError: raise EncryptorError("Decrypting key data failed") if len(plainkey) != 64: raise EncryptorError("Integrity check failed") key = plainkey[0:16] nonce = plainkey[16:32] auth_key = plainkey[32:64] self.cipher = Cipher(algorithms.AES(key), modes.CTR(nonce), backend=default_backend()).decryptor() self.authenticator = HMAC(auth_key, SHA256(), backend=default_backend()) self.buf = self.buf[8 + cipherkeylen:] if len(self.buf) < 32: return b"" self.authenticator.update(self.buf[:-32]) result = self.cipher.update(self.buf[:-32]) self.buf = self.buf[-32:] return result
def sign_csr_builder(self, slot, public_key, builder, touch_callback=None): algorithm = ALGO.from_public_key(public_key) dummy_key = _dummy_key(algorithm) csr = builder.sign(dummy_key, hashes.SHA256(), default_backend()) seq = parse_tlvs(Tlv(csr.public_bytes(Encoding.DER)).value) # Replace public key pub_format = PublicFormat.PKCS1 if algorithm.name.startswith('RSA') \ else PublicFormat.SubjectPublicKeyInfo dummy_bytes = dummy_key.public_key().public_bytes( Encoding.DER, pub_format) pub_bytes = public_key.public_bytes(Encoding.DER, pub_format) seq[0] = seq[0].replace(dummy_bytes, pub_bytes) if touch_callback is not None: touch_timer = Timer(0.500, touch_callback) touch_timer.start() sig = self.sign(slot, algorithm, seq[0]) if touch_callback is not None: touch_timer.cancel() # Replace signature, add unused bits = 0 seq[2] = Tlv(seq[2].tag, b'\0' + sig) # Re-assemble sequence der = Tlv(0x30, b''.join(seq)) return x509.load_der_x509_csr(der, default_backend())
def serialize(self): rsa_pub = self.public_key(default_backend()) return (rsa_pub.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo))
def load_csr(data): """ Loads a PEM X.509 CSR. """ return x509.load_pem_x509_csr(data, default_backend())
def read_public_key(public_key_pem): with open(public_key_pem, "rb") as key_file: private_key = serialization.load_pem_public_key( key_file.read(), backend=default_backend()) return private_key
def key_from_pem(self, pem): "Get the EC from a public PEM." return serialization.load_pem_public_key(pem, backend=default_backend())
from paramiko import py3compat from sshaolin import common from sshaolin.models import CommandResponse # this is a hack to preimport dependencies imported in a thread during connect # which causes a deadlock. https://github.com/paramiko/paramiko/issues/104 py3compat.u("".encode()) # dirty hack 2.0 also issue 104 # Try / Catch to prevent users using paramiko<2.0.0 from raising an ImportError try: from cryptography.hazmat.backends import default_backend from cryptography.utils import int_from_bytes int_from_bytes(b"a", "big") default_backend() except ImportError: pass class CommandOperationTimeOut(socket.timeout): pass class ProxyTypes(object): SOCKS5 = 2 SOCKS4 = 1 def read_pipe(pipe, fp_out): def target():
def get_certificate_as_certificate(self): """ Retrieves the certificate as a cryptography.x509.Certificate """ return x509.load_pem_x509_certificate( self.certificate_and_private_key['certificate'], default_backend())
def deserialize(self, data): key = serialization.load_pem_public_key(data, default_backend()) self._e = key.public_numbers().e self._n = key.public_numbers().n
def _encrypt_RSA(self, modulus, passphrase, text): public_numbers = rsa.RSAPublicNumbers(passphrase, modulus) public_key = public_numbers.public_key(default_backend()) ciphertext = public_key.encrypt(text.encode('ascii'), padding.PKCS1v15()) return ciphertext
class TtypePushAPITestCase(MyApiTestCase): """ test /ttype/push """ server_private_key = rsa.generate_private_key(public_exponent=65537, key_size=4096, backend=default_backend()) server_private_key_pem = to_unicode( server_private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption())) server_public_key_pem = to_unicode( server_private_key.public_key().public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo)) # We now allow white spaces in the firebase config name firebase_config_name = "my firebase config" smartphone_private_key = rsa.generate_private_key( public_exponent=65537, key_size=4096, backend=default_backend()) smartphone_public_key = smartphone_private_key.public_key() smartphone_public_key_pem = to_unicode( smartphone_public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo)) # The smartphone sends the public key in URLsafe and without the ----BEGIN header smartphone_public_key_pem_urlsafe = strip_key( smartphone_public_key_pem).replace("+", "-").replace("/", "_") serial_push = "PIPU001" def _create_push_token(self): tparams = {'type': 'push', 'genkey': 1} tparams.update(FB_CONFIG_VALS) tok = init_token(param=tparams) tok.add_tokeninfo(PUSH_ACTION.FIREBASE_CONFIG, self.firebase_config_name) tok.add_tokeninfo(PUBLIC_KEY_SMARTPHONE, self.smartphone_public_key_pem_urlsafe) tok.add_tokeninfo('firebase_token', 'firebaseT') tok.add_tokeninfo(PUBLIC_KEY_SERVER, self.server_public_key_pem) tok.add_tokeninfo(PRIVATE_KEY_SERVER, self.server_private_key_pem, 'password') tok.del_tokeninfo("enrollment_credential") tok.token.rollout_state = "enrolled" tok.token.active = True return tok def test_00_create_realms(self): self.setUp_user_realms() def test_01_api_enroll_push(self): self.authenticate() # Failed enrollment due to missing policy with self.app.test_request_context('/token/init', method='POST', data={ "type": "push", "genkey": 1 }, headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertNotEqual(res.status_code, 200) error = res.json.get("result").get("error") self.assertEqual( error.get("message"), "Missing enrollment policy for push token: push_firebase_configuration" ) self.assertEqual(error.get("code"), 303) r = set_smsgateway( self.firebase_config_name, u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider', "myFB", FB_CONFIG_VALS) self.assertTrue(r > 0) set_policy("push1", scope=SCOPE.ENROLL, action="{0!s}={1!s}".format(PUSH_ACTION.FIREBASE_CONFIG, self.firebase_config_name)) # 1st step with self.app.test_request_context('/token/init', method='POST', data={ "type": "push", "genkey": 1 }, headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertEqual(res.status_code, 200) detail = res.json.get("detail") serial = detail.get("serial") self.assertEqual(detail.get("rollout_state"), "clientwait") self.assertTrue("pushurl" in detail) # check that the new URL contains the serial number self.assertTrue( "&serial=PIPU" in detail.get("pushurl").get("value")) self.assertTrue("appid=" in detail.get("pushurl").get("value")) self.assertTrue("appidios=" in detail.get("pushurl").get("value")) self.assertTrue("apikeyios=" in detail.get("pushurl").get("value")) self.assertFalse("otpkey" in detail) enrollment_credential = detail.get("enrollment_credential") # 2nd step. Failing with wrong serial number with self.app.test_request_context( '/ttype/push', method='POST', data={ "serial": "wrongserial", "pubkey": self.smartphone_public_key_pem_urlsafe, "fbtoken": "firebaseT" }): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 404, res) status = res.json.get("result").get("status") self.assertFalse(status) error = res.json.get("result").get("error") self.assertEqual( error.get("message"), "No token with this serial number in the rollout state 'clientwait'." ) # 2nd step. Fails with missing enrollment credential with self.app.test_request_context( '/ttype/push', method='POST', data={ "serial": serial, "pubkey": self.smartphone_public_key_pem_urlsafe, "fbtoken": "firebaseT", "enrollment_credential": "WRonG" }): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 400, res) status = res.json.get("result").get("status") self.assertFalse(status) error = res.json.get("result").get("error") self.assertEqual( error.get("message"), "ERR905: Invalid enrollment credential. You are not authorized to finalize this token." ) # 2nd step: as performed by the smartphone with self.app.test_request_context( '/ttype/push', method='POST', data={ "enrollment_credential": enrollment_credential, "serial": serial, "pubkey": self.smartphone_public_key_pem_urlsafe, "fbtoken": "firebaseT" }): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) detail = res.json.get("detail") # still the same serial number self.assertEqual(serial, detail.get("serial")) self.assertEqual(detail.get("rollout_state"), "enrolled") # Now the smartphone gets a public key from the server augmented_pubkey = "-----BEGIN RSA PUBLIC KEY-----\n{}\n-----END RSA PUBLIC KEY-----\n".format( detail.get("public_key")) parsed_server_pubkey = serialization.load_pem_public_key( to_bytes(augmented_pubkey), default_backend()) self.assertIsInstance(parsed_server_pubkey, rsa.RSAPublicKey) pubkey = detail.get("public_key") # Now check, what is in the token in the database toks = get_tokens(serial=serial) self.assertEqual(len(toks), 1) token_obj = toks[0] self.assertEqual(token_obj.token.rollout_state, u"enrolled") self.assertTrue(token_obj.token.active) tokeninfo = token_obj.get_tokeninfo() self.assertEqual(tokeninfo.get("public_key_smartphone"), self.smartphone_public_key_pem_urlsafe) self.assertEqual(tokeninfo.get("firebase_token"), u"firebaseT") self.assertEqual( tokeninfo.get("public_key_server").strip().strip( "-BEGIN END RSA PUBLIC KEY-").strip(), pubkey) # The token should also contain the firebase config self.assertEqual(tokeninfo.get(PUSH_ACTION.FIREBASE_CONFIG), self.firebase_config_name) # remove the token remove_token(serial) def test_02_api_push_poll(self): r = set_smsgateway( self.firebase_config_name, u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider', "myFB", FB_CONFIG_VALS) self.assertGreater(r, 0) # create a new push token tokenobj = self._create_push_token() serial = tokenobj.get_serial() # set PIN tokenobj.set_pin("pushpin") tokenobj.add_user(User("cornelius", self.realm1)) # We mock the ServiceAccountCredentials, since we can not directly contact the Google API with mock.patch( 'privacyidea.lib.smsprovider.FirebaseProvider.service_account.Credentials' '.from_service_account_file') as mySA: # alternative: side_effect instead of return_value mySA.return_value = _create_credential_mock() # add responses, to simulate the communication to firebase responses.add( responses.POST, 'https://fcm.googleapis.com/v1/projects/test-123456/messages:send', body="""{}""", content_type="application/json") # Send the first authentication request to trigger the challenge. # No push notification is submitted to firebase, but a challenge is created anyway with self.app.test_request_context('/validate/check', method='POST', data={ "user": "******", "realm": self.realm1, "pass": "******" }): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 400, res) jsonresp = res.json self.assertFalse(jsonresp.get("result").get("status")) self.assertEqual( jsonresp.get("result").get("error").get("code"), 401) self.assertEqual( jsonresp.get("result").get("error").get("message"), "ERR401: Failed to submit message to firebase service.") # first create a signature ts = datetime.utcnow().isoformat() sign_string = u"{serial}|{timestamp}".format(serial=serial, timestamp=ts) sig = self.smartphone_private_key.sign(sign_string.encode('utf8'), padding.PKCS1v15(), hashes.SHA256()) # now check that we receive the challenge when polling with self.app.test_request_context('/ttype/push', method='GET', data={ "serial": serial, "timestamp": ts, "signature": b32encode(sig) }): res = self.app.full_dispatch_request() # check that the serial was set in flask g (via before_request in ttype.py) self.assertTrue(self.app_context.g.serial, serial) self.assertTrue(res.status_code == 200, res) self.assertTrue(res.json['result']['status']) chall = res.json['result']['value'][0] self.assertTrue(chall) challenge = chall["nonce"] # This is what the smartphone answers. # create the signature: sign_data = "{0!s}|{1!s}".format(challenge, serial) signature = b32encode_and_unicode( self.smartphone_private_key.sign(sign_data.encode("utf-8"), padding.PKCS1v15(), hashes.SHA256())) # Answer the challenge with self.app.test_request_context('/ttype/push', method='POST', data={ "serial": serial, "nonce": challenge, "signature": signature }): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) self.assertTrue(res.json['result']['status']) self.assertTrue(res.json['result']['value'])
def deserialize(self, data): cert = x509.load_pem_x509_certificate(data, default_backend()) key_material = cert.public_key().public_numbers() self._e = key_material.e self._n = key_material.n
class ChainKeyKDF(KDF): """ An implementations of the KDF interface based on a recommendation by WhisperSystems: HMAC with SHA-256 or SHA-512 is recommended, using ck as the HMAC key and using separate constants as input (e.g. a single byte 0x01 as input to produce the message key, and a single byte 0x02 as input to produce the next chain key). Notice: Following these recommendations, the calculate method ignored both the data and the length parameters. """ CRYPTOGRAPHY_BACKEND = default_backend() HASH_FUNCTIONS = { "SHA-256": hashes.SHA256, "SHA-512": hashes.SHA512 } def __init__(self, hash_function, ck_constant = b"\x02", mk_constant = b"\x01"): """ Prepare a ChainKeyKDF, following a recommendation by WhisperSystems. :param hash_function: One of (the strings) "SHA-256" and "SHA-512". :param ck_constant: A single byte used for derivation of the next chain key. :param mk_constant: A single byte used for derivation of the next message key. """ super(ChainKeyKDF, self).__init__() if not hash_function in ChainKeyKDF.HASH_FUNCTIONS: raise ValueError("Invalid value passed for the hash_function parameter.") if not isinstance(ck_constant, bytes): raise TypeError("Wrong type passed for the ck_constant parameter.") if len(ck_constant) != 1: raise ValueError("Invalid value passed for the ck_constant parameter.") if not isinstance(mk_constant, bytes): raise TypeError("Wrong type passed for the mk_constant parameter.") if len(mk_constant) != 1: raise ValueError("Invalid value passed for the mk_constant parameter.") self.__hash_function = ChainKeyKDF.HASH_FUNCTIONS[hash_function] self.__ck_constant = ck_constant self.__mk_constant = mk_constant def calculate(self, key, data = None, length = None): chain_key = hmac.HMAC( key, self.__hash_function(), backend = self.__class__.CRYPTOGRAPHY_BACKEND ) chain_key.update(self.__ck_constant) message_key = hmac.HMAC( key, self.__hash_function(), backend = self.__class__.CRYPTOGRAPHY_BACKEND ) message_key.update(self.__mk_constant) return chain_key.finalize() + message_key.finalize()
def setup_cipher(self): algorithm = algorithms.ARC4(self.key) self._cipher = Cipher(algorithm, mode=None, backend=default_backend()) self.encryptor = self._cipher.encryptor() self.decryptor = self._cipher.decryptor()
def nc_kdf(shared_secret, kep2, kep3) -> list: """ Return a list of results from the kdf procedure. :param shared_secret: bytes :param kep2: bytes, sent by the dsc :param kep3: bytes, sent by the adv :return: list of results Kep2 might be containied in a single payload together with Kep1. Interesting return values: rv[6] = cli2ser_key: dsc (encrypt) --> adv (decrypt) rv[8] = ser2cli_key: adv (encrypt) --> dsc (decrypt) rv[9] = auth token """ validate_shared_secret("nc_kdf", shared_secret) validate_kep2("nc_kdf", kep2) validate_kep3("nc_kdf", kep3) rv = [] kdf1 = Hash(SHA256(), backend=default_backend()) kdf1.update(shared_secret) kdf1_out = kdf1.finalize() # log.debug("nc_kdf kdf1_out: {}, {}".format(kdf1_out, type(kdf1_out))) rv.append(kdf1_out) kdf2 = HMAC(NC_STR_UKEY2v1auth, SHA256(), backend=default_backend()) kdf2.update(kdf1_out) kdf2_out = kdf2.finalize() # log.debug("nc_kdf kdf2_out: {}, {}".format(kdf2_out, type(kdf2_out))) rv.append(kdf2_out) kdf3 = HMAC(kdf2_out, SHA256(), backend=default_backend()) kdf3_inp_hex = kep2[4:].hex() + kep3[4:].hex() # log.debug("nc_kdf kdf3_inp_hex: {}, {}".format(kdf3_inp_hex, len(kdf3_inp_hex))) kdf3_inp = unhexlify(kdf3_inp_hex) # NOTE: heuristic assert len(kdf3_inp) == 252 or len(kdf3_inp) == 253 or len(kdf3_inp) == 254 kdf3.update(kdf3_inp) kdf3.update(b'\x01') kdf3_out = kdf3.finalize() # log.debug("nc_kdf kdf3_out: {}, {}".format(kdf3_out, type(kdf3_out))) rv.append(kdf3_out) kdf4 = HMAC(NC_STR_UKEY2v1next, SHA256(), backend=default_backend()) kdf4.update(kdf1_out) kdf4_out = kdf4.finalize() # log.debug("nc_kdf kdf4_out: {}, {}".format(kdf4_out, type(kdf4_out))) rv.append(kdf4_out) # NOTE: same inputs of kdf3 kdf5 = HMAC(kdf4_out, SHA256(), backend=default_backend()) kdf5.update(kdf3_inp) kdf5.update(b'\x01') kdf5_out = kdf5.finalize() # log.debug("nc_kdf kdf5_out: {}, {}".format(kdf5_out, type(kdf5_out))) rv.append(kdf5_out) kdf6 = HMAC(NC_KDF_KEY, SHA256(), backend=default_backend()) kdf6.update(kdf5_out) kdf6_out = kdf6.finalize() # log.debug("nc_kdf kdf6_out: {}, {}".format(kdf6_out, type(kdf6_out))) rv.append(kdf6_out) # NOTE: computes cli2ser_key kdf7 = HMAC(kdf6_out, SHA256(), backend=default_backend()) kdf7.update(NC_STR_CLIENT) kdf7.update(b'\x01') kdf7_out = kdf7.finalize() # log.debug("nc_kdf kdf7_out: {}, {}".format(kdf7_out, type(kdf7_out))) cli2ser_key = kdf7_out log.debug("nc_kdf cli2ser_key: {}, {}".format(kdf7_out, len(kdf7_out))) rv.append(kdf7_out) # NOTE: same as kdf6 kdf8 = HMAC(NC_KDF_KEY, SHA256(), backend=default_backend()) kdf8.update(kdf5_out) kdf8_out = kdf8.finalize() # log.debug("nc_kdf kdf8_out: {}, {}".format(kdf8_out, type(kdf8_out))) rv.append(kdf8_out) # NOTE: computes ser2cli_key kdf9 = HMAC(kdf8_out, SHA256(), backend=default_backend()) kdf9.update(NC_STR_SERVER) kdf9.update(b'\x01') kdf9_out = kdf9.finalize() # log.debug("nc_kdf kdf9_out: {}, {}".format(kdf9_out, type(kdf9_out))) ser2cli_key = kdf9_out log.debug("nc_kdf ser2cli_key: {}, {}".format(kdf9_out, len(kdf9_out))) rv.append(kdf9_out) # NOTE: computes auth token from kdf3_out r_auth_token = b64encode(kdf3_out)[:5] auth_token = r_auth_token.decode('utf-8').upper() assert len(auth_token) == 5 log.debug("nc_kdf auth_token: {}, {}".format(auth_token, len(auth_token))) rv.append(auth_token) return rv
def test_01_api_enroll_push(self): self.authenticate() # Failed enrollment due to missing policy with self.app.test_request_context('/token/init', method='POST', data={ "type": "push", "genkey": 1 }, headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertNotEqual(res.status_code, 200) error = res.json.get("result").get("error") self.assertEqual( error.get("message"), "Missing enrollment policy for push token: push_firebase_configuration" ) self.assertEqual(error.get("code"), 303) r = set_smsgateway( self.firebase_config_name, u'privacyidea.lib.smsprovider.FirebaseProvider.FirebaseProvider', "myFB", FB_CONFIG_VALS) self.assertTrue(r > 0) set_policy("push1", scope=SCOPE.ENROLL, action="{0!s}={1!s}".format(PUSH_ACTION.FIREBASE_CONFIG, self.firebase_config_name)) # 1st step with self.app.test_request_context('/token/init', method='POST', data={ "type": "push", "genkey": 1 }, headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertEqual(res.status_code, 200) detail = res.json.get("detail") serial = detail.get("serial") self.assertEqual(detail.get("rollout_state"), "clientwait") self.assertTrue("pushurl" in detail) # check that the new URL contains the serial number self.assertTrue( "&serial=PIPU" in detail.get("pushurl").get("value")) self.assertTrue("appid=" in detail.get("pushurl").get("value")) self.assertTrue("appidios=" in detail.get("pushurl").get("value")) self.assertTrue("apikeyios=" in detail.get("pushurl").get("value")) self.assertFalse("otpkey" in detail) enrollment_credential = detail.get("enrollment_credential") # 2nd step. Failing with wrong serial number with self.app.test_request_context( '/ttype/push', method='POST', data={ "serial": "wrongserial", "pubkey": self.smartphone_public_key_pem_urlsafe, "fbtoken": "firebaseT" }): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 404, res) status = res.json.get("result").get("status") self.assertFalse(status) error = res.json.get("result").get("error") self.assertEqual( error.get("message"), "No token with this serial number in the rollout state 'clientwait'." ) # 2nd step. Fails with missing enrollment credential with self.app.test_request_context( '/ttype/push', method='POST', data={ "serial": serial, "pubkey": self.smartphone_public_key_pem_urlsafe, "fbtoken": "firebaseT", "enrollment_credential": "WRonG" }): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 400, res) status = res.json.get("result").get("status") self.assertFalse(status) error = res.json.get("result").get("error") self.assertEqual( error.get("message"), "ERR905: Invalid enrollment credential. You are not authorized to finalize this token." ) # 2nd step: as performed by the smartphone with self.app.test_request_context( '/ttype/push', method='POST', data={ "enrollment_credential": enrollment_credential, "serial": serial, "pubkey": self.smartphone_public_key_pem_urlsafe, "fbtoken": "firebaseT" }): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) detail = res.json.get("detail") # still the same serial number self.assertEqual(serial, detail.get("serial")) self.assertEqual(detail.get("rollout_state"), "enrolled") # Now the smartphone gets a public key from the server augmented_pubkey = "-----BEGIN RSA PUBLIC KEY-----\n{}\n-----END RSA PUBLIC KEY-----\n".format( detail.get("public_key")) parsed_server_pubkey = serialization.load_pem_public_key( to_bytes(augmented_pubkey), default_backend()) self.assertIsInstance(parsed_server_pubkey, rsa.RSAPublicKey) pubkey = detail.get("public_key") # Now check, what is in the token in the database toks = get_tokens(serial=serial) self.assertEqual(len(toks), 1) token_obj = toks[0] self.assertEqual(token_obj.token.rollout_state, u"enrolled") self.assertTrue(token_obj.token.active) tokeninfo = token_obj.get_tokeninfo() self.assertEqual(tokeninfo.get("public_key_smartphone"), self.smartphone_public_key_pem_urlsafe) self.assertEqual(tokeninfo.get("firebase_token"), u"firebaseT") self.assertEqual( tokeninfo.get("public_key_server").strip().strip( "-BEGIN END RSA PUBLIC KEY-").strip(), pubkey) # The token should also contain the firebase config self.assertEqual(tokeninfo.get(PUSH_ACTION.FIREBASE_CONFIG), self.firebase_config_name) # remove the token remove_token(serial)
def __init__(self, msg=None, data=None, filename=None, password=None, vals=None, file_obj=None, validate_point=True, _raw=None): self.verifying_key = None self.signing_key = None self.public_blob = None if file_obj is not None: _raw = self._from_private_key(file_obj, password) if filename is not None: _raw = self._from_private_key_file(filename, password) if _raw is not None: self._decode_key(_raw) return if (msg is None) and (data is not None): msg = Message(data) if vals is not None: self.signing_key, self.verifying_key = vals c_class = self.signing_key.curve.__class__ self.ecdsa_curve = self._ECDSA_CURVES.get_by_curve_class(c_class) else: # Must set ecdsa_curve first; subroutines called herein may need to # spit out our get_name(), which relies on this. key_type = msg.get_text() # But this also means we need to hand it a real key/curve # identifier, so strip out any cert business. (NOTE: could push # that into _ECDSACurveSet.get_by_key_format_identifier(), but it # feels more correct to do it here?) suffix = '*****@*****.**' if key_type.endswith(suffix): key_type = key_type[:-len(suffix)] self.ecdsa_curve = self._ECDSA_CURVES.get_by_key_format_identifier( key_type) key_types = self._ECDSA_CURVES.get_key_format_identifier_list() cert_types = [ '{}[email protected]'.format(x) for x in key_types ] self._check_type_and_load_cert( msg=msg, key_type=key_types, cert_type=cert_types, ) curvename = msg.get_text() if curvename != self.ecdsa_curve.nist_name: raise SSHException( "Can't handle curve of type {}".format(curvename)) pointinfo = msg.get_binary() try: if hasattr(ec.EllipticCurvePublicKey, 'from_encoded_point'): key = ec.EllipticCurvePublicKey.from_encoded_point( self.ecdsa_curve.curve_class(), pointinfo) self.verifying_key = key else: numbers = ec.EllipticCurvePublicNumbers.from_encoded_point( self.ecdsa_curve.curve_class(), pointinfo) self.verifying_key = numbers.public_key( backend=default_backend()) except ValueError: raise SSHException("Invalid public key")
def cert_pem_to_der(certificate): """Convert a PEM formatted cert to DER.""" c = x509.load_pem_x509_certificate(certificate.encode(), default_backend()) return c.public_bytes(serialization.Encoding.DER)
def add_from_der(self, crt_str): self.certificates.append( x509.load_der_x509_certificate(crt_str, default_backend())) status('Successfully added 1 certificate')
def nc_scapy_pkt(pt_type, fields) -> bytes: """ Generates NC scapy packets, :param pt_type: string in NC_PT_TYPES :param fields: list content depends on pt_type :return: scapy packet kep1 fields: fields[0]: eid, str fields[1]: ncname, str fields[2]: strategy, str fields[3]: wifi_mode, str kep4 fields: fields[0]: pri_key, bytes fields[1]: pub_key, tuple of bytes kep2 fields: fields[0]: kep4, bytes kep3 fields: fields[0]: pri_key, bytes fields[1]: pub_key, tuple of bytes eka fields: fields[0]: key, bytes fields[1]: iv, bytes fields[2]: count, int ewl fields: fields[0]: key, bytes fields[1]: iv, bytes fields[2]: count, int fields[3]: ip, list fields[4]: tcp_port, bytes eha fields: fields[0]: key, bytes fields[1]: iv, bytes fields[2]: count, int fields[3]: essid, bytes, 28 or DIRECT- fields[4]: password, bytes, 12 or 8 fields[5]: tcp_port, bytes, 3 esh fields: fields[0]: key, bytes fields[1]: iv, bytes fields[2]: count, int esh2 fields: fields[0]: key, bytes fields[1]: iv, bytes fields[2]: count, int pay fields: fields[0]: key, bytes fields[1]: iv, bytes fields[2]: count, int fields[3]: pt, bytes fields[4]: pid, bytes pay2 fields: fields[0]: key, bytes fields[1]: iv, bytes fields[2]: count, int fields[3]: pay_len, int fields[4]: pid, bytes iw fields: fields[0]: key, bytes fields[1]: iv, bytes fields[2]: count, int fields[3]: eid, str """ validate_pt_type("nc_scapy_pkt", pt_type) rv = b'' if pt_type == 'kep1': eid = fields[0] validate_str('nc_scapy_pkt kep1', eid) ncname = fields[1] validate_str('nc_scapy_pkt kep1', ncname) strategy = fields[2] validate_strategy('nc_scapy_pkt kep1', strategy) wifi_mode = fields[3] validate_wifi_mode('nc_scapy_pkt kep1', wifi_mode) # NOTE: use only latest version if strategy == 'P2P_STAR': if wifi_mode == 'hostapd': kep1_scapy = SCAPY_KEP1_STAR_HA_TEMPLATE elif wifi_mode == 'direct': kep1_scapy = SCAPY_KEP1_STAR_WD_TEMPLATE elif strategy == 'P2P_CLUSTER': kep1_scapy = SCAPY_KEP1_CLUS_TEMPLATE kep1_scapy.eid = eid kep1_scapy.ncname = ncname # NOTE: 4 depends on SCAPY_KEP1_TEMPLATE if len(ncname) != 4: delta = 4 - len(ncname) kep1_scapy.ncname_len = len(ncname) kep1_scapy.len1 -= delta kep1_scapy.len2 -= delta kep1_scapy.len3 -= delta # log.debug("nc_scapy_pkt kep1: {}".format(repr(kep1_scapy))) # log.debug("nc_scapy_pkt kep1_scapy.name: {}".format(kep1_scapy.name)) rv = kep1_scapy elif pt_type == 'kep4': pri_key = fields[0] validate_pri_key('nc_scapy_pkt kep4', pri_key) pub_key = None pub_key = fields[1] if pub_key is not None: validate_pub_key('nc_scapy_pkt kep4', pub_key) # NOTE: not validating if it is in the curve else: pri_key_int = bytes_to_int(pri_key) pub_key_int = scalar_mult(pri_key_int, (EC_XG_INT, EC_YG_INT)) pub_key = (int_to_bytes(pub_key_int[0]), int_to_bytes(pub_key_int[1])) validate_point('nc_scapy_pkt kep4', pub_key) xD = pub_key[0] yD = pub_key[1] # NOTE: preprend \x00 if coordinate starts with 0b1 if bin(xD[0]).startswith('0b1'): xD = b'\x00' + xD if bin(yD[0]).startswith('0b1'): yD = b'\x00' + yD kep4_scapy = SCAPY_KEP4_TEMPLATE # NOTE: 32 depends on the SCAPY_KEP4_TEMPLATE delta = 32 - len(xD) + 32 - len(yD) kep4_scapy.len1 -= delta kep4_scapy.len2 -= delta kep4_scapy.len3 -= delta kep4_scapy.len4 -= delta kep4_scapy.xD = xD kep4_scapy.xD_len = len(xD) kep4_scapy.yD = yD kep4_scapy.yD_len = len(yD) # log.debug("nc_scapy_pkt kep4_hex: {}".format(raw(kep4_scapy).hex())) rv = kep4_scapy # NOTE: so far passing constant kdf1 and kdf2 elif pt_type == 'kep2': kep4 = fields[0] validate_bytes('nc_scapy_pkt kep2', kep4) kep2_scapy = SCAPY_KEP2_TEMPLATE kep0 = Hash(SHA512(), backend=default_backend()) kep0.update(kep4[4:]) kep2_kdf2 = kep0.finalize() kep2_scapy.kdf2 = kep2_kdf2 rv = kep2_scapy elif pt_type == 'kep3': pri_key = fields[0] validate_pri_key('nc_scapy_pkt kep3', pri_key) pub_key = None pub_key = fields[1] # NOTE: if fields[1] contains a pub_key if pub_key is not None: validate_pub_key('nc_scapy_pkt kep3', pub_key) # NOTE: not validating if it is in the curve else: pri_key_int = bytes_to_int(pri_key) pub_key_int = scalar_mult(pri_key_int, (EC_XG_INT, EC_YG_INT)) pub_key = (int_to_bytes(pub_key_int[0]), int_to_bytes(pub_key_int[1])) validate_point('nc_scapy_pkt kep3', pub_key) xA = pub_key[0] yA = pub_key[1] # NOTE: preprend \x00 if coordinate starts with 0b1 if bin(xA[0]).startswith('0b1'): xA = b'\x00' + xA if bin(yA[0]).startswith('0b1'): yA = b'\x00' + yA # NOTE: kdf field is kept constant so far kep3_scapy = SCAPY_KEP3_TEMPLATE # NOTE: 32 depends on the SCAPY_KEP3_TEMPLATE delta = 32 - len(xA) + 32 - len(yA) kep3_scapy.len1 -= delta kep3_scapy.len2 -= delta kep3_scapy.len3 -= delta kep3_scapy.len4 -= delta kep3_scapy.xA = xA kep3_scapy.xA_len = len(xA) kep3_scapy.yA = yA kep3_scapy.yA_len = len(yA) # log.debug("nc_scapy_pkt kep3_hex: {}".format(raw(kep3_scapy).hex())) rv = kep3_scapy elif pt_type == 'eka': key = fields[0] validate_aes256_key("nc_scapy_pkt eka", key) iv = fields[1] validate_iv("nc_scapy_pkt eka", iv) count = fields[2] validate_int("nc_scapy_pkt eka", count) pt_scapy = SCAPY_KA_TEMPLATE pt_scapy.count = count pt = raw(pt_scapy) # log.debug("nc_scapy_pkt eka pt_hex: {} {}, count {}".format(pt.hex(), # len(pt.hex()), count)) ct = nc_encrypt(key, pt, iv)[2] mac = nc_mac(key, ct, iv, pt_type)[2] eka_scapy = SCAPY_EKA_TEMPLATE eka_scapy.iv = iv eka_scapy.ct = ct eka_scapy.mac = mac rv = eka_scapy elif pt_type == 'ewl': key = fields[0] validate_aes256_key("nc_scapy_pkt ewl", key) iv = fields[1] validate_iv("nc_scapy_pkt ewl", iv) count = fields[2] validate_int("nc_scapy_pkt ewl", count) ip = fields[3] validate_ip("nc_scapy_pkt ewl", ip) wl_scapy = SCAPY_WL_TEMPLATE wl_scapy.count = count wl_scapy.ip = ip if fields[4] == None: # NOTE: use the tcp_port from the template pass else: tcp_port = fields[4] validate_tcp_port("nc_scapy_pkt ewl", tcp_port) wl_scapy.tcp_port = tcp_port pt = raw(wl_scapy) ct = nc_encrypt(key, pt, iv)[2] mac = nc_mac(key, ct, iv, pt_type)[2] # NOTE: similar to eka_scapy ewl_scapy = SCAPY_EWL_TEMPLATE ewl_scapy.iv = iv ewl_scapy.ct = ct ewl_scapy.mac = mac rv = ewl_scapy elif pt_type == 'eha': key = fields[0] validate_aes256_key("nc_scapy_pkt eha", key) iv = fields[1] validate_iv("nc_scapy_pkt eha", iv) count = fields[2] validate_int("nc_scapy_pkt eha", count) essid = fields[3] validate_essid("nc_scapy_pkt eha", essid) password = fields[4] validate_password("nc_scapy_pkt eha", password) ha_scapy = SCAPY_HA_TEMPLATE ha_scapy.count = count ha_scapy.essid = essid ha_scapy.password = password if fields[5] == None: # NOTE: use the tcp_port from the template pass else: tcp_port = fields[5] validate_tcp_port("nc_scapy_pkt eha", tcp_port) ha_scapy.tcp_port = tcp_port pt = raw(ha_scapy) ct = nc_encrypt(key, pt, iv)[2] mac = nc_mac(key, ct, iv, pt_type)[2] # NOTE: similar to eka_scapy eha_scapy = SCAPY_EHA_TEMPLATE eha_scapy.iv = iv eha_scapy.ct = ct eha_scapy.mac = mac rv = eha_scapy elif pt_type == 'esh': key = fields[0] validate_aes256_key("nc_scapy_pkt esh", key) iv = fields[1] validate_iv("nc_scapy_pkt esh", iv) count = fields[2] validate_int("nc_scapy_pkt esh", count) sh_scapy = SCAPY_SH_TEMPLATE sh_scapy.count = count pt = raw(sh_scapy) ct = nc_encrypt(key, pt, iv)[2] mac = nc_mac(key, ct, iv, pt_type)[2] esh_scapy = SCAPY_EKA_TEMPLATE esh_scapy.iv = iv esh_scapy.ct = ct esh_scapy.mac = mac rv = esh_scapy elif pt_type == 'esh2': key = fields[0] validate_aes256_key("nc_scapy_pkt esh2", key) iv = fields[1] validate_iv("nc_scapy_pkt esh2", iv) count = fields[2] validate_int("nc_scapy_pkt esh2", count) sh2_scapy = SCAPY_SH2_TEMPLATE sh2_scapy.count = count pt = raw(sh2_scapy) ct = nc_encrypt(key, pt, iv)[2] mac = nc_mac(key, ct, iv, pt_type)[2] esh2_scapy = SCAPY_EKA_TEMPLATE esh2_scapy.iv = iv esh2_scapy.ct = ct esh2_scapy.mac = mac rv = esh2_scapy elif pt_type == 'pay': key = fields[0] validate_aes256_key("nc_scapy_pkt pay", key) iv = fields[1] validate_iv("nc_scapy_pkt pay", iv) count = fields[2] validate_int("nc_scapy_pkt pay", count) pay = fields[3] validate_bytes("nc_scapy_pkt pay", pay) # pid = fields[4] # validate_bytes("nc_scapy_pkt pay", pid) # NOTE: uses Pt class pt_scapy = SCAPY_PT_TEMPLATE # NOTE: 4 depends on SCAPY_PT_TEMPLATE if len(pay) != 4: delta = 4 - len(pay) pt_scapy.len1 -= delta pt_scapy.len2 -= delta pt_scapy.len3 -= delta pt_scapy.pt_len = len(pay) pt_scapy.len4 -= delta pt_scapy.pay_len = len(pay) pt_scapy.pay = pay pt_scapy.count = count # log.debug("nc_scapy_pkt pt: {}".format(repr(pt_scapy))) pt = raw(pt_scapy) log.debug("nc_scapy_pkt pt_hex: {}".format(pt.hex())) ct = nc_encrypt(key, pt, iv)[2] mac = nc_mac(key, ct, iv, pt_type)[2] # NOTE: len fields should not be affected by len(Pt) pay_scapy = SCAPY_PAY_TEMPLATE pay_scapy.iv = iv pay_scapy.ct = ct pay_scapy.mac = mac rv = pay_scapy elif pt_type == 'pay2': key = fields[0] validate_aes256_key("nc_scapy_pkt pay2", key) iv = fields[1] validate_iv("nc_scapy_pkt pay2", iv) count = fields[2] validate_int("nc_scapy_pkt pay2", count) pay_len = fields[3] # this is the len of Pt (not Pt2) validate_int("nc_scapy_pkt pay2", pay_len) # pid = fields[4] # validate_bytes("nc_scapy_pkt pay2", pid) # NOTE: uses Pt2 class pt2_scapy = SCAPY_PT2_TEMPLATE if pay_len != 4: delta = 4 - pay_len pt2_scapy.pt_len = pay_len pt2_scapy.pt_len2 = pay_len pt2_scapy.count = count # log.debug("nc_scapy_pkt pt2: {}".format(repr(pt2_scapy))) pt = raw(pt2_scapy) log.debug("nc_scapy_pkt pt2_hex: {}".format(pt.hex())) # log.debug("nc_scapy_pkt pay pt_hex: {} {}, count {}".format(pt.hex(), # len(pt.hex()), count)) ct = nc_encrypt(key, pt, iv)[2] mac = nc_mac(key, ct, iv, pt_type)[2] pay2_scapy = SCAPY_PAY2_TEMPLATE pay2_scapy.iv = iv pay2_scapy.ct = ct pay2_scapy.mac = mac rv = pay2_scapy # NOTE: not encrypted, key and iv not used elif pt_type == 'iw': key = fields[0] validate_aes256_key("nc_scapy_pkt iw", key) iv = fields[1] validate_iv("nc_scapy_pkt iw", iv) count = fields[2] validate_int("nc_scapy_pkt iw", count) eid = eid[2] validate_str("nc_scapy_pkt iw", eid) iw_scapy = SCAPY_IW_TEMPLATE iw_scapy.count = count iw_scapy.eid = eid pt = raw(iw_scapy) # log.debug("nc_scapy_pkt iw pt_hex: {} {}, count {}".format(pt.hex(), # len(pt.hex()), count)) rv = iw_scapy else: log.error('nc_scapy_pkt: pt_type {} not managed.'.format(pt_type)) return rv
def get_backend(): from cryptography.hazmat.backends import default_backend return default_backend()
hexstr = binascii.hexlify(content).decode("UTF-8") hexstr = hexstr.upper() array = ["0x" + hexstr[i:i + 2] + "" for i in range(0, len(hexstr), 2)] array = make_sublist_group(array, 10) return sum(len(a) for a in array ), "\n".join([", ".join(e) + ", " for e in array]) #Creating a Certificate with open(sys.argv[1], "rb") as keyfile: private_key = serialization.load_pem_private_key( keyfile.read(), password=None, backend=default_backend() ) key_der = private_key.private_bytes( serialization.Encoding.DER, serialization.PrivateFormat.TraditionalOpenSSL, serialization.NoEncryption() ) key_length , keyArray=do_convension(key_der) keyHeaderTemplate=Template(""" /*GENERATED FILE*/ #ifndef _KEY_TEST_H_ #define _KEY_TEST_H_
def getCertificateSignature(certificate_data): cert = crypto.x509.load_pem_x509_certificate(certificate_data, default_backend()) return cert.signature
async def start_client( self, target_node: PeerInfo, on_connect: Callable = None, auth: bool = False, is_feeler: bool = False, ) -> bool: """ Tries to connect to the target node, adding one connection into the pipeline, if successful. An on connect method can also be specified, and this will be saved into the instance variables. """ if self.is_duplicate_or_self_connection(target_node): return False if target_node.host in self.banned_peers and time.time() < self.banned_peers[target_node.host]: self.log.warning(f"Peer {target_node.host} is still banned, not connecting to it") return False if auth: ssl_context = ssl_context_for_client( self.ca_private_crt_path, self.ca_private_key_path, self._private_cert_path, self._private_key_path ) else: ssl_context = ssl_context_for_client( self.chia_ca_crt_path, self.chia_ca_key_path, self.p2p_crt_path, self.p2p_key_path ) session = None connection: Optional[WSChiaConnection] = None try: timeout = ClientTimeout(total=10) session = ClientSession(timeout=timeout) try: if type(ip_address(target_node.host)) is IPv6Address: target_node = PeerInfo(f"[{target_node.host}]", target_node.port) except ValueError: pass url = f"wss://{target_node.host}:{target_node.port}/ws" self.log.debug(f"Connecting: {url}, Peer info: {target_node}") try: ws = await session.ws_connect( url, autoclose=True, autoping=True, heartbeat=60, ssl=ssl_context, max_msg_size=50 * 1024 * 1024 ) except ServerDisconnectedError: self.log.debug(f"Server disconnected error connecting to {url}. Perhaps we are banned by the peer.") await session.close() return False except asyncio.TimeoutError: self.log.debug(f"Timeout error connecting to {url}") await session.close() return False if ws is not None: assert ws._response.connection is not None and ws._response.connection.transport is not None transport = ws._response.connection.transport # type: ignore cert_bytes = transport._ssl_protocol._extra["ssl_object"].getpeercert(True) # type: ignore der_cert = x509.load_der_x509_certificate(cert_bytes, default_backend()) peer_id = bytes32(der_cert.fingerprint(hashes.SHA256())) if peer_id == self.node_id: raise RuntimeError(f"Trying to connect to a peer ({target_node}) with the same peer_id: {peer_id}") connection = WSChiaConnection( self._local_type, ws, self._port, self.log, True, False, target_node.host, self.incoming_messages, self.connection_closed, peer_id, self._inbound_rate_limit_percent, self._outbound_rate_limit_percent, session=session, ) handshake = await connection.perform_handshake( self._network_id, protocol_version, self._port, self._local_type, ) assert handshake is True await self.connection_added(connection, on_connect) connection_type_str = "" if connection.connection_type is not None: connection_type_str = connection.connection_type.name.lower() self.log.info(f"Connected with {connection_type_str} {target_node}") if is_feeler: asyncio.create_task(connection.close()) return True else: await session.close() return False except client_exceptions.ClientConnectorError as e: self.log.info(f"{e}") except ProtocolError as e: if connection is not None: await connection.close(self.invalid_protocol_ban_seconds, WSCloseCode.PROTOCOL_ERROR, e.code) if e.code == Err.INVALID_HANDSHAKE: self.log.warning(f"Invalid handshake with peer {target_node}. Maybe the peer is running old software.") elif e.code == Err.INCOMPATIBLE_NETWORK_ID: self.log.warning("Incompatible network ID. Maybe the peer is on another network") elif e.code == Err.SELF_CONNECTION: pass else: error_stack = traceback.format_exc() self.log.error(f"Exception {e}, exception Stack: {error_stack}") except Exception as e: if connection is not None: await connection.close(self.invalid_protocol_ban_seconds, WSCloseCode.PROTOCOL_ERROR, Err.UNKNOWN) error_stack = traceback.format_exc() self.log.error(f"Exception {e}, exception Stack: {error_stack}") if session is not None: await session.close() return False
def calc_hmac(self, plainbytes, mac): h = hmac.HMAC(mac, hashes.SHA256(), backend=default_backend()) h.update(plainbytes) hmac_ = h.finalize().hex() return hmac_ #sec = Security() #secret = sec.updateEncryptor("3asdasdx") #print("recovered", sec.updateDecryptor(secret)) with open("my_key.pem", "rb") as private_key_file_object: my_private_pem = private_key_file_object.read() my_private_key = serialization.load_pem_private_key( my_private_pem, backend=default_backend(), password=None) with open("my_key_pub.pem", "rb") as public_key_file_object: my_public_pem = public_key_file_object.read() my_public_key = serialization.load_pem_public_key( my_public_pem, backend=default_backend()) with open("server_key.pem", "rb") as private_key_file_object: server_private_pem = private_key_file_object.read() server_private_key = serialization.load_pem_private_key( server_private_pem, backend=default_backend(), password=None) with open("server_key_pub.pem", "rb") as public_key_file_object: server_public_pem = public_key_file_object.read() server_public_key = serialization.load_pem_public_key( server_public_pem, backend=default_backend())
def register(config, account_storage, tos_cb=None): """Register new account with an ACME CA. This function takes care of generating fresh private key, registering the account, optionally accepting CA Terms of Service and finally saving the account. It should be called prior to initialization of `Client`, unless account has already been created. :param .IConfig config: Client configuration. :param .AccountStorage account_storage: Account storage where newly registered account will be saved to. Save happens only after TOS acceptance step, so any account private keys or `.RegistrationResource` will not be persisted if `tos_cb` returns ``False``. :param tos_cb: If ACME CA requires the user to accept a Terms of Service before registering account, client action is necessary. For example, a CLI tool would prompt the user acceptance. `tos_cb` must be a callable that should accept `.RegistrationResource` and return a `bool`: ``True`` iff the Terms of Service present in the contained `.Registration.terms_of_service` is accepted by the client, and ``False`` otherwise. ``tos_cb`` will be called only if the client acction is necessary, i.e. when ``terms_of_service is not None``. This argument is optional, if not supplied it will default to automatic acceptance! :raises letsencrypt.errors.Error: In case of any client problems, in particular registration failure, or unaccepted Terms of Service. :raises acme.errors.Error: In case of any protocol problems. :returns: Newly registered and saved account, as well as protocol API handle (should be used in `Client` initialization). :rtype: `tuple` of `.Account` and `acme.client.Client` """ # Log non-standard actions, potentially wrong API calls if account_storage.find_all(): logger.info("There are already existing accounts for %s", config.server) if config.email is None: if not config.register_unsafely_without_email: msg = ("No email was provided and " "--register-unsafely-without-email was not present.") logger.warn(msg) raise errors.Error(msg) if not config.dry_run: logger.warn("Registering without email!") # Each new registration shall use a fresh new key key = jose.JWKRSA(key=jose.ComparableRSAKey( rsa.generate_private_key( public_exponent=65537, key_size=config.rsa_key_size, backend=default_backend()))) acme = acme_from_config_key(config, key) # TODO: add phone? regr = perform_registration(acme, config) if regr.terms_of_service is not None: if tos_cb is not None and not tos_cb(regr): raise errors.Error( "Registration cannot proceed without accepting " "Terms of Service.") regr = acme.agree_to_tos(regr) acc = account.Account(regr, key) account.report_new_account(acc, config) account_storage.save(acc) return acc, acme
def read_private(filename="private_noshare.pem"): with open(filename, "rb") as key_file: private_key = serialization.load_pem_private_key( key_file.read(), password=None, backend=default_backend()) return private_key
def calc_hmac(self, plainbytes, mac): h = hmac.HMAC(mac, hashes.SHA256(), backend=default_backend()) h.update(plainbytes) hmac_ = h.finalize().hex() return hmac_
def decode_message(b64msg): global _crypt_keys global _public_keys global _ca_file # get the message try: msgstr = base64.b64decode(b64msg).decode('utf-8', 'ignore') iam_message = json.loads(msgstr) except json.decoder.JSONDecodeError as e: logging.info('Not an iam message: invalid json') raise MessageException('Not an iam message: invalid json', MessageException.not_iam_message) if 'header' not in iam_message: logging.info('Not an iam message: no header') raise MessageException('Not an iam message: no header', MessageException.not_iam_message) iamHeader = iam_message['header'] try: # check the version if iamHeader[u'version'] != 'UWIT-2': logging.error('unknown version: ' + iamHeader[u'version']) raise MessageException('Unknown message version: ' + iamHeader[u'version'], MessageException.bad_version) # fetch the signing cert if it's not cached certurl = iamHeader[u'signingCertUrl'] if certurl not in _public_keys: logging.info('Fetching signing cert: ' + certurl) pem = '' if certurl.startswith('file:'): with open(certurl[5:], 'r') as f: pem = f.read() elif certurl.startswith('http'): if _ca_file is not None: http = urllib3.PoolManager( cert_reqs='CERT_REQUIRED', # Force certificate check. ca_certs=_ca_file, ) else: http = urllib3.PoolManager() certdoc = http.request('GET', certurl) if certdoc.status != 200: logger.error('sws cert get failed: ' + certdoc.status) raise SigningCertException('Signers public key not found, url=%s, status=%d' % (certurl, certdoc.status)) logger.debug('got it') pem = certdoc.data else: raise SigningCertException('Invalid signers public key: ' + certurl) crt = x509.load_pem_x509_certificate(pem.encode('utf-8', 'ignore'), default_backend()) key = crt.public_key() _public_keys[certurl] = key enctxt64 = iam_message[u'body'] # print (enctxt64) # check the signature sigmsg = _build_sig_msg(iamHeader, enctxt64) pre = hashlib.sha256(sigmsg).digest() # print('dec sig = ' + iamHeader[u'signature']) sig = base64.b64decode(iamHeader[u'signature'].encode('utf-8', 'ignore')) pubkey = _public_keys[certurl] pubkey.verify(sig, sigmsg, a_padding.PSS(mgf=a_padding.MGF1(hashes.SHA256()), salt_length=32), hashes.SHA256()) # decrypt the message if 'keyId' in iamHeader: iv64 = iamHeader[u'iv'] iv = base64.b64decode(iv64.encode('utf-8', 'ignore')) keyid = iamHeader[u'keyId'] if keyid not in _crypt_keys: logger.error('key ' + keyid + ' not found') raise CryptKeyException('Decryption key not found: ' + keyid) key = _crypt_keys[keyid] enctxt = base64.b64decode(enctxt64.encode('utf-8', 'ignore')) cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) dec = cipher.decryptor() ptxt = dec.update(enctxt) + dec.finalize() unpadder = padding.PKCS7(128).unpadder() txt = unpadder.update(ptxt) + unpadder.finalize() else: txt = base64.b64decode(enctxt64.encode('utf-8', 'ignore')) txt = txt.decode('utf-8', 'ignore') iam_message[u'body'] = txt # context is b64 encoded try: iamHeader[u'messageContext'] = base64.b64decode(iamHeader[u'messageContext'].encode('utf-8', 'ignore')).decode('utf-8', 'ignore') except TypeError: logger.info('context not base64') iamHeader[u'messageContext'] = None except InvalidSignature as e: logger.error('signature verify fails') raise SignatureVerifyException(str(e)) except KeyError as e: if 'AlarmName' in iam_message: logger.debug('alarm: ' + iam_message['AlarmName']) return iam_message logger.error('Unknown message key: ') raise MessageException('Message key: ' + str(e)) return iam_message
parser.add_argument("--host", type=str, default="::") parser.add_argument("--port", type=int, default=4433) parser.add_argument("--private-key", type=str, required=True) parser.add_argument("--secrets-log-file", type=str) parser.add_argument("--stateless-retry", action="store_true") parser.add_argument("--verbose", "-v", action="store_true") args = parser.parse_args() logging.basicConfig( format="%(asctime)s %(levelname)s %(name)s %(message)s", level=logging.DEBUG if args.verbose else logging.INFO, ) with open(args.certificate, "rb") as fp: certificate = x509.load_pem_x509_certificate( fp.read(), backend=default_backend() ) with open(args.private_key, "rb") as fp: private_key = serialization.load_pem_private_key( fp.read(), password=None, backend=default_backend() ) if args.secrets_log_file: secrets_log_file = open(args.secrets_log_file, "a") else: secrets_log_file = None # session tickets ticket_store = SessionTicketStore() loop = asyncio.get_event_loop()
def encode_message(msg, header, cryptid, signid): iamHeader = {} iamHeader['version'] = 'UWIT-2' iamHeader['contentType'] = _if_simple(header['contentType']) iamHeader['messageType'] = _if_simple(header['messageType']) iamHeader['sender'] = _if_simple(header['sender']) iamHeader['messageId'] = str(uuid.uuid4()) iamHeader['messageContext'] = base64.b64encode(header['messageContext'].encode('utf-8', 'ignore')).decode('utf-8', 'ignore') iamHeader['timestamp'] = datetime.datetime.utcnow().isoformat() if signid not in _private_keys: raise SigningCertException('Signing key not found: ' + signid) iamHeader['signingCertUrl'] = _private_keys[signid]['url'] if cryptid is not None: if cryptid not in _crypt_keys: raise CryptKeyException('Encryption key not found: ' + cryptid) iamHeader['keyId'] = cryptid iv = os.urandom(16) iamHeader['iv'] = base64.b64encode(iv).decode('utf-8', 'ignore') padder = padding.PKCS7(128).padder() pmsg = padder.update(msg.encode('utf-8', 'ignore')) + padder.finalize() key = _crypt_keys[cryptid] cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) enc = cipher.encryptor() txt = enc.update(pmsg) + enc.finalize() enctxt64 = base64.b64encode(txt).decode('utf-8', 'ignore') # print (enctxt64) else: enctxt64 = base64.b64encode(msg.encode('utf-8', 'ignore')).decode('utf-8', 'ignore') # gen the signature sigmsg = _build_sig_msg(iamHeader, enctxt64) # print ('sigmsg:' + sigmsg.decode('utf-8')) key = _private_keys[signid]['key'] pre = hashlib.sha256(sigmsg).digest() # some advise the use of 'PSS.MAX_LENGTH' for the salt length, but # I don't see how that works with other languages sig = key.sign(sigmsg, a_padding.PSS(mgf=a_padding.MGF1(hashes.SHA256()), salt_length=32), hashes.SHA256()) sig64 = base64.b64encode(sig).decode('utf-8', 'ignore') # print ('enc sig64 = ' + sig64) iamHeader['signature'] = sig64 # debugging stuff # with open('sigmsg', 'w') as f: # f.write(sigmsg.decode('utf-8')) # with open('sigsig', 'wb') as f: # f.write(sig) body = {} body['Message'] = enctxt64 iamMessage = {} iamMessage['header'] = iamHeader iamMessage['body'] = enctxt64 m64 = base64.b64encode(json.dumps(iamMessage).encode('utf-8', 'ignore')).decode('utf-8', 'ignore') return m64
def read_public(filename="public_shared.pem"): with open("public_shared.pem", "rb") as key_file: public_key = serialization.load_pem_public_key( key_file.read(), backend=default_backend()) return public_key