def create_signature(manifest): """ Creates a signature of the manifest signed with the PKCS#12. Warning to future contributors: this uses internal bindings of pyOpenSSL so I know this function isn't pretty but it's as good as it'll get. """ certificate_path = path.join(getcwd(), WEBAPN_CERT_NAME) certificate_password_path = path.join(getcwd(), WEBAPN_CERT_PASSWORD_NAME) with open(certificate_password_path, 'r') as password_file: passphrase = password_file.read().strip() with open(certificate_path, 'rb') as cert_file: cert_data = cert_file.read() p12 = load_pkcs12(cert_data, passphrase) cert = p12.get_certificate() pkey = p12.get_privatekey() # TODO: when pyOpenSSL responds to my issue and we get a BIO_flush method then # we'll use that to directly to BIO instead of copying here and there input_bio = _new_mem_buf(manifest.encode('utf-8')) output_bio = _new_mem_buf() # This is now our signature pkcs7 = lib.PKCS7_sign(cert._x509, pkey._pkey, ffi.NULL, input_bio, lib.PKCS7_BINARY | lib.PKCS7_DETACHED) # i2d converts the internal OpenSSL type (AIS.1/i) to DER/d lib.i2d_PKCS7_bio(output_bio, pkcs7) return _bio_to_string(output_bio)
def create_embeded_pkcs7_signature(data, cert, key): """ Creates an embeded ("nodetached") pkcs7 signature. This is equivalent to the output of:: openssl smime -sign -signer cert -inkey key -outform DER -nodetach < data :type data: bytes :type cert: str :type key: str """ # noqa: E501 assert isinstance(data, bytes) assert isinstance(cert, str) try: pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, key) signcert = crypto.load_certificate(crypto.FILETYPE_PEM, cert) except crypto.Error as e: raise exceptions.CorruptCertificate from e bio_in = crypto._new_mem_buf(data) pkcs7 = crypto._lib.PKCS7_sign(signcert._x509, pkey._pkey, crypto._ffi.NULL, bio_in, PKCS7_NOSIGS) bio_out = crypto._new_mem_buf() crypto._lib.i2d_PKCS7_bio(bio_out, pkcs7) signed_data = crypto._bio_to_string(bio_out) return signed_data
def sign(p12_b64_cert, p12_passphrase, signed_text): p12 = crypto.load_pkcs12(base64.b64decode(p12_b64_cert), p12_passphrase.encode()) signcert = p12.get_certificate() pkey = p12.get_privatekey() bio_in = crypto._new_mem_buf(signed_text.encode('utf8')) pkcs7 = crypto._lib.PKCS7_sign( signcert._x509, pkey._pkey, crypto._ffi.NULL, bio_in, crypto._lib.PKCS7_NOATTR | crypto._lib.PKCS7_NOSMIMECAP | crypto._lib.PKCS7_PARTIAL) signer_info = crypto._lib.PKCS7_sign_add_signer( pkcs7, signcert._x509, pkey._pkey, crypto._lib.EVP_get_digestbyname(b'sha1'), 0) crypto._lib.PKCS7_final(pkcs7, bio_in, 0) bio_out = crypto._new_mem_buf() #crypto._lib.PEM_write_bio_PKCS7(bio_out, pkcs7) #sigbytes = crypto._bio_to_string(bio_out) crypto._lib.i2d_PKCS7_bio(bio_out, pkcs7) sigbytes = crypto._bio_to_string(bio_out) signed_data = base64.b64encode(sigbytes) verified = crypto._lib.PKCS7_verify(pkcs7, crypto._ffi.NULL, crypto._ffi.NULL, crypto._ffi.NULL, bio_out, crypto._lib.PKCS7_NOVERIFY) return verified, signed_data
def create_embeded_pkcs7_signature(data, cert, key): """ Creates an embeded ("nodetached") pkcs7 signature. This is equivalent to the output of:: openssl smime -sign -signer cert -inkey key -outform DER -nodetach < data :type data: bytes :type cert: str :type key: str """ # noqa: E501 assert isinstance(data, bytes) assert isinstance(cert, str) try: pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, key) signcert = crypto.load_certificate(crypto.FILETYPE_PEM, cert) except crypto.Error as e: raise exceptions.CorruptCertificate from e bio_in = crypto._new_mem_buf(data) pkcs7 = crypto._lib.PKCS7_sign( signcert._x509, pkey._pkey, crypto._ffi.NULL, bio_in, PKCS7_NOSIGS ) bio_out = crypto._new_mem_buf() crypto._lib.i2d_PKCS7_bio(bio_out, pkcs7) signed_data = crypto._bio_to_string(bio_out) return signed_data
def make_signature(config: dict, manifest: Path, signature: Path): """Package the signature file for the package.""" logging.debug("signing the manifest...") p12 = load_certificates(config) # https://stackoverflow.com/questions/33634379/pkcs-7-detached-signature-with-python-and-pyopenssl/33726421#33726421 # How the f**k did this guy even figure this out? # Create the memory buffer for the signature with manifest.open("rb") as file: buffer_in = crypto._new_mem_buf(file.read()) # Grab the flags from source # https://github.com/openssl/openssl/blob/52df25cf2e656146cb3b206d8220124f0417d03f/include/openssl/pkcs7.h PKCS7_DETACHED = 0x40 PKCS7_BINARY = 0x80 # Sign the actual file pkcs7 = crypto._lib.PKCS7_sign(p12.get_certificate()._x509, p12.get_privatekey()._pkey, crypto._ffi.NULL, buffer_in, PKCS7_BINARY | PKCS7_DETACHED) # Write out the result buffer_out = crypto._new_mem_buf() crypto._lib.i2d_PKCS7_bio(buffer_out, pkcs7) der = crypto._bio_to_string(buffer_out) with signature.open("wb") as file: file.write(der)
def create_embedded_pkcs7_signature(data, cert, key, pkcs7_option): """ Creates an pkcs7 signature. For PKCS7_OPT == PKCS7_NOSIGS: equivalent to the output of `openssl smime -sign -signer cert -inkey key -outform DER -nodetach < data` Thanks to https://stackoverflow.com/a/47098879/8545455 For PKCS7_OPT == PKCS7_DETACHED: equivalent to the output of `openssl smime -sign -signer cert -inkey key -outform DER < data` :type data: bytes :type cert: str :type key: bytes :type pkcs7_option: int """ assert isinstance(data, bytes) assert isinstance(cert, str) assert isinstance(key, str) try: pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, key) signcert = crypto.load_certificate(crypto.FILETYPE_PEM, cert) except crypto.Error as e: raise ValueError('Certificates files are invalid') from e bio_in = crypto._new_mem_buf(data) pkcs7 = crypto._lib.PKCS7_sign(signcert._x509, pkey._pkey, crypto._ffi.NULL, bio_in, pkcs7_option) bio_out = crypto._new_mem_buf() crypto._lib.i2d_PKCS7_bio(bio_out, pkcs7) signed_data = crypto._bio_to_string(bio_out) return signed_data
def sign_manifest(self, manifest_data): # F**k me. Thanks @WhyNotHugo: https://stackoverflow.com/a/41553623 bio_in = crypto._new_mem_buf(manifest_data) PKCS7_NOSIGS = 0x4 # defined in pkcs7.h pkcs7 = crypto._lib.PKCS7_sign(self.cert._x509, self.key._pkey, crypto._ffi.NULL, bio_in, PKCS7_NOSIGS) # noqa bio_out = crypto._new_mem_buf() crypto._lib.i2d_PKCS7_bio(bio_out, pkcs7) sigbytes = crypto._bio_to_string(bio_out) return sigbytes
def sign_pkcs7_data(data, cert, key, stack=crypto._ffi.NULL): if isinstance(data, str): data = data.encode() bio_in = crypto._new_mem_buf(data) pkcs7 = crypto._lib.PKCS7_sign( cert._x509, key._pkey, stack, bio_in, crypto._lib.PKCS7_NOSIGS, ) bio_out = crypto._new_mem_buf() crypto._lib.i2d_PKCS7_bio(bio_out, pkcs7) return crypto._bio_to_string(bio_out)
def gen_dh_params(bits): dh = _lib.DH_new() # pylint: disable=no-member _lib.DH_generate_parameters_ex(dh, bits, 2, _ffi.NULL) # pylint: disable=no-member bio = _new_mem_buf() _lib.PEM_write_bio_DHparams(bio, dh) # pylint: disable=no-member return _bio_to_string(bio)
def load_dh_params_from_string(ctx, dh_params_string): bio = _new_mem_buf() _lib.BIO_write(bio, dh_params_string.encode('ascii'), len(dh_params_string.encode('ascii'))) # pylint: disable=no-member dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL) # pylint: disable=no-member dh = _ffi.gc(dh, _lib.DH_free) # pylint: disable=no-member _lib.SSL_CTX_set_tmp_dh(ctx._context, dh) # pylint: disable=no-member
def pkcs7_sign(cert, key, buf): with open(cert, 'r') as f: crt = crypto.load_certificate(crypto.FILETYPE_PEM, f.read()) with open(key, 'r') as f: pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, f.read()) PKCS7_BINARY = 0x80 PKCS7_DETACHED = 0x40 PKCS7_NOATTR = 0x100 bio_in = crypto._new_mem_buf(buf) p7 = crypto._lib.PKCS7_sign(crt._x509, pkey._pkey, crypto._ffi.NULL, bio_in, PKCS7_BINARY|PKCS7_DETACHED|PKCS7_NOATTR) bio_out = crypto._new_mem_buf() crypto._lib.i2d_PKCS7_bio(bio_out, p7) return crypto._bio_to_string(bio_out)
def get_namestr(x509name): bio = crypto._new_mem_buf() print_result = crypto._lib.X509_NAME_print_ex( bio, x509name._name, 0, crypto._lib.XN_FLAG_RFC2253 ) assert print_result >= 0 return crypto._native(crypto._bio_to_string(bio))
def get_fingerprint(path, passphrase=None, content=None, backend='pyopenssl'): """Generate the fingerprint of the public key. """ privatekey = load_privatekey(path, passphrase=passphrase, content=content, check_passphrase=False, backend=backend) if backend == 'pyopenssl': try: publickey = crypto.dump_publickey(crypto.FILETYPE_ASN1, privatekey) except AttributeError: # If PyOpenSSL < 16.0 crypto.dump_publickey() will fail. try: bio = crypto._new_mem_buf() rc = crypto._lib.i2d_PUBKEY_bio(bio, privatekey._pkey) if rc != 1: crypto._raise_current_error() publickey = crypto._bio_to_string(bio) except AttributeError: # By doing this we prevent the code from raising an error # yet we return no value in the fingerprint hash. return None elif backend == 'cryptography': publickey = privatekey.public_key().public_bytes( serialization.Encoding.DER, serialization.PublicFormat.SubjectPublicKeyInfo) return get_fingerprint_of_bytes(publickey)
def firmar_tra_con(tra, pkcs12=None, cert=None, key=None): if pkcs12 is not None: cert = pkcs12.get_certificate() key = pkcs12.get_privatekey() elif cert is None or key is None: raise Exception('No tengo con que firmar :(') bio_in = crypto._new_mem_buf(tra.encode()) PKCS7_NOSIGS = 0x4 pkcs7 = crypto._lib.PKCS7_sign(cert._x509, key._pkey, crypto._ffi.NULL, bio_in, PKCS7_NOSIGS) bio_out = crypto._new_mem_buf() crypto._lib.i2d_PKCS7_bio(bio_out, pkcs7) sigbytes = crypto._bio_to_string(bio_out) signed_data = base64.b64encode(sigbytes) return signed_data
def getHash(self, selector, type): key = (selector, type) if key not in self.__hashCache: cert = crypto.load_certificate(crypto.FILETYPE_PEM, sir.util.readFile(self.certFile)) if selector == TlsaSelector.FULL: data = crypto.dump_certificate(crypto.FILETYPE_ASN1, cert) elif selector == TlsaSelector.SPKI: bio = crypto._new_mem_buf() cryptolib.i2d_PUBKEY_bio(bio, cert.get_pubkey()._pkey) data = crypto._bio_to_string(bio) else: raise Exception('Unknown TLSA selector %s' % selector) if type == TlsaType.EXACT: self.__hashCache[key] = binascii.b2a_hex(data).decode('ascii') elif type == TlsaType.SHA256: self.__hashCache[key] = hashlib.sha256(data).hexdigest() elif type == TlsaType.SHA512: self.__hashCache[key] = hashlib.sha512(data).hexdigest() else: raise Exception('Unknown TLSA type %s' % type) return self.__hashCache[key]
def remove_signature(content): """ Remove the PKCS#7 envelope from given content, making a '.xml.p7m' file content readable as it was '.xml'. As OpenSSL may not be installed, in that case a warning is issued and None is returned. """ # Prevent using the library if it had import errors if not ssl_crypto: _logger.warning( "Error reading the content, check if the OpenSSL library is installed for for PKCS#7 envelope extraction." ) return None # Load some tools from the library null = ssl_util.ffi.NULL verify = ssl_util.lib.PKCS7_verify # By default ignore the validity of the certificates, just validate the structure flags = ssl_util.lib.PKCS7_NOVERIFY | ssl_util.lib.PKCS7_NOSIGS # Read the signed data fron the content out_buffer = ssl_crypto._new_mem_buf() # This method is deprecated, but there are actually no alternatives with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) loaded_data = ssl_crypto.load_pkcs7_data(ssl_crypto.FILETYPE_ASN1, content) # Verify the signature if verify(loaded_data._pkcs7, null, null, null, out_buffer, flags) != 1: ssl_crypto._raise_current_error() # Get the content as a byte-string decoded_content = ssl_crypto._bio_to_string(out_buffer) return decoded_content
def load_dh_params_from_string(ctx, dh_params_string): bio = _new_mem_buf() _lib.BIO_write(bio, str(dh_params_string), len(str(dh_params_string))) dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL) dh = _ffi.gc(dh, _lib.DH_free) _lib.SSL_CTX_set_tmp_dh(ctx._context, dh)
def _get_public_key(self, binary): try: return crypto.dump_publickey( crypto.FILETYPE_ASN1 if binary else crypto.FILETYPE_PEM, self.cert.get_pubkey()) except AttributeError: try: # pyOpenSSL < 16.0: bio = crypto._new_mem_buf() if binary: rc = crypto._lib.i2d_PUBKEY_bio( bio, self.cert.get_pubkey()._pkey) else: rc = crypto._lib.PEM_write_bio_PUBKEY( bio, self.cert.get_pubkey()._pkey) if rc != 1: crypto._raise_current_error() return crypto._bio_to_string(bio) except AttributeError: self.module.warn( 'Your pyOpenSSL version does not support dumping public keys. ' 'Please upgrade to version 16.0 or newer, or use the cryptography backend.' )
def get_public_key(private_key): if not isinstance(private_key, crypto.PKey): private_key = crypto.load_privatekey(crypto.FILETYPE_PEM, private_key) bio = crypto._new_mem_buf() cryptolib.PEM_write_bio_PUBKEY(bio, private_key._pkey) public_key = crypto._bio_to_string(bio) return public_key
def gen_dh_params(bits): dh = _lib.DH_new() _lib.DH_generate_parameters_ex(dh, bits, 2L, _ffi.NULL) bio = _new_mem_buf() _lib.PEM_write_bio_DHparams(bio, dh) return _bio_to_string(bio)
def sign(content: str, crt: crypto.X509, pkey: crypto.PKey) -> str: """ Подписывает параметры запроса цифровой подписью Args: data: Данные, которые необходимо подписать crt: Путь до сертификата pkey: Путь до приватного ключа """ bio_in = crypto._new_mem_buf(content.encode()) PKCS7_DETACHED = 0x40 pkcs7 = crypto._lib.PKCS7_sign(crt._x509, pkey._pkey, crypto._ffi.NULL, bio_in, PKCS7_DETACHED) bio_out = crypto._new_mem_buf() crypto._lib.i2d_PKCS7_bio(bio_out, pkcs7) sigbytes = crypto._bio_to_string(bio_out) return base64.urlsafe_b64encode(sigbytes).decode()
def data_received(self, data): print("###SSL layer data received called!###") self.deserializer.update(data) for packet in self.deserializer.nextPackets(): if isinstance(packet, PlsHello): print( "\nReceived Client Hello packet. Trying to verify issuer..." ) if self.validate(packet.Certs[0], packet.Certs[1], packet.Certs[2]): print("Certificate Validated. Sending Server hello!\n") self.clientnonce = packet.Nonce serverhello = PlsHello() serverhello.Nonce = 12345678 idcert = getIDCertsForAddr() pubkey = getCertsForAddr() root = getRootCertsForAddr() serverhello.Certs = [] serverhello.Certs.append(idcert) serverhello.Certs.append(pubkey) serverhello.Certs.append(root) srvhello = serverhello.__serialize__() print("Sent Server Hello!\n") self.transport.write(srvhello) if isinstance(packet, PlsKeyExchange): print("Received Client Key Exchange.") privkey = getPrivateKeyForAddr() priv_key = RSA.importKey(privkey) Data = packet.PreKey Dataint = int(Data) enc = (Dataint, ) dec_data = priv_key.decrypt(enc) print("Decrypted Pre-Master Secret: ", dec_data) #==================================== #Creating Server Pre-Master serverkey = PlsKeyExchange() randomvalue = 1234567887659999 serverkey.NoncePlusOne = self.clientnonce + 1 cert1 = crypto.load_certificate(crypto.FILETYPE_PEM, self.certificate[0]) k = cert1.get_pubkey() bio = crypto._new_mem_buf() rsa = crypto._lib.EVP_PKEY_get1_RSA(k._pkey) crypto._lib.PEM_write_bio_RSAPublicKey(bio, rsa) s = crypto._bio_to_string(bio) pubkey1 = s.decode() pubkey = RSA.importKey(pubkey1) pub_key = pubkey.publickey() enc_data = pub_key.encrypt(randomvalue, self.clientnonce + 1) enc1 = str(enc_data[0]) enc2 = enc1.encode() serverkey.PreKey = enc2 ckey = serverkey.__serialize__() print("\nSent the Server Key Exchange.") self.transport.write(ckey)
def decrypt_p7s(data: bytes) -> str: """ openssl cms -verify -in xxx.p7s -inform DER -noverify -outform DER -signer cert.pem -print """ p7 = crypto.load_pkcs7_data(crypto.FILETYPE_ASN1, BytesIO(data).getvalue()) bio_out = crypto._new_mem_buf() _lib.PKCS7_verify(p7._pkcs7, _ffi.NULL, _ffi.NULL, _ffi.NULL, bio_out, _lib.PKCS7_NOVERIFY) return crypto._bio_to_string(bio_out)
def get_data_without_certificate_verification(pkcs7_der): """ Return blob containing the signed data without certificate chain verification (but with signature verification). Throw PKCS7VerifyError if signature verification failed. """ p7 = load_pkcs7_bio_der(pkcs7_der) out = crypto._new_mem_buf() if not crypto._lib.PKCS7_verify(p7._pkcs7, ffi.NULL, ffi.NULL, ffi.NULL, out, crypto._lib.PKCS7_NOVERIFY): raise PKCS7VerifyError(crypto._lib.ERR_get_error()) return crypto._bio_to_string(out)
def verify_pkcs7_data(data): pdata = crypto.load_pkcs7_data(crypto.FILETYPE_ASN1, data) bio_out = crypto._new_mem_buf() crypto._lib.PKCS7_verify( pdata._pkcs7, crypto._ffi.NULL, crypto._ffi.NULL, crypto._ffi.NULL, bio_out, crypto._lib.PKCS7_NOVERIFY ) return crypto._bio_to_string(bio_out)
def verifySignature(self, certificate_pem, original_data, signature): cert_obj = crypto.load_certificate(crypto.FILETYPE_PEM, certificate_pem) bio = crypto._new_mem_buf() cryptolib.PEM_write_bio_PUBKEY(bio, cert_obj.get_pubkey()._pkey) pkey_pem = crypto._bio_to_string(bio) b64 = pkey_pem.replace("\n","").\ replace("-----BEGIN PUBLIC KEY-----","").\ replace("-----END PUBLIC KEY-----","") keyder = b64decode(b64) keypub = RSA.importKey(keyder) verifier = PKCS1_v1_5.new(keypub) digest = SHA.new() digest.update(original_data) return verifier.verify(digest, signature)
def verify_data(self, pkcs7_der, verify_time=None): """ Verify signature on signed PKCS7 DER blob. Return blob containing the signed data. Throw PKCS7VerifyError if verification failed. This will fail if the CA cert has not been loaded. """ store = self.store or crypto.X509Store() if verify_time: store.set_time(verify_time) p7 = load_pkcs7_bio_der(pkcs7_der) out = crypto._new_mem_buf() if not crypto._lib.PKCS7_verify(p7._pkcs7, ffi.NULL, store._store, ffi.NULL, out, 0): raise PKCS7VerifyError() return crypto._bio_to_string(out)
def parse_x509_der_hex(self): """Parse X509 cert in DER format X.509 is an ITU-T standard for a public key infrastructure (PKI) and Privilege Management Infrastructure (PMI). It is commonly involved with SSL/TLS security.<br><br>This operation displays the contents of a certificate in a human readable format, similar to the openssl command line tool. Returns: Chepy: A Chepy object. """ cert = _pyssl_crypto.load_certificate(_pyssl_crypto.FILETYPE_ASN1, self._convert_to_bytes()) issuer = cert.get_issuer() subject = cert.get_subject() pubkey = cert.get_pubkey() bio = _pyssl_crypto._new_mem_buf() info = { "version": cert.get_version(), "serial": cert.get_serial_number(), "algo": cert.get_signature_algorithm(), "before": cert.get_notBefore(), "after": cert.get_notAfter(), "issuer": { "C": issuer.C, "ST": issuer.ST, "L": issuer.L, "O": issuer.O, "OU": issuer.OU, "CN": issuer.CN, "email": issuer.emailAddress, }, "subject": { "C": subject.C, "ST": subject.ST, "L": subject.L, "O": subject.O, "OU": subject.OU, "CN": subject.CN, "email": subject.emailAddress, }, "pubkey": { "bits": pubkey.bits() }, } self.state = info return self
def get_fingerprint(path, passphrase=None): """Generate the fingerprint of the public key. """ privatekey = load_privatekey(path, passphrase, check_passphrase=False) try: publickey = crypto.dump_publickey(crypto.FILETYPE_ASN1, privatekey) except AttributeError: # If PyOpenSSL < 16.0 crypto.dump_publickey() will fail. try: bio = crypto._new_mem_buf() rc = crypto._lib.i2d_PUBKEY_bio(bio, privatekey._pkey) if rc != 1: crypto._raise_current_error() publickey = crypto._bio_to_string(bio) except AttributeError: # By doing this we prevent the code from raising an error # yet we return no value in the fingerprint hash. return None return get_fingerprint_of_bytes(publickey)
def dump_rsa_privatekey(pkey): """ Dump a private rsa key to a buffer :param pkey: The PKey to dump :return: The buffer with the dumped key in :rtype: :py:data:`str` """ # Based off of https://github.com/pyca/pyopenssl/blob/27398343217703c5261e67d6c19dda89ba559f1b/OpenSSL/crypto.py#L1418-L1466 from OpenSSL._util import (ffi as _ffi, lib as _lib, exception_from_error_queue as _exception_from_error_queue) from OpenSSL import crypto from functools import partial class Error(Exception): """ An error occurred in an `OpenSSL.crypto` API. """ _raise_current_error = partial(_exception_from_error_queue, Error) bio = crypto._new_mem_buf() cipher_obj = _ffi.NULL rsa = _lib.EVP_PKEY_get1_RSA(pkey._pkey) helper = crypto._PassphraseHelper(crypto.FILETYPE_PEM, None) result_code = _lib.PEM_write_bio_RSAPrivateKey(bio, rsa, cipher_obj, _ffi.NULL, 0, helper.callback, helper.callback_args) helper.raise_if_problem() if result_code == 0: _raise_current_error() return crypto._bio_to_string(bio)
def dump_rsa_privatekey(pkey): """ Dump a private rsa key to a buffer :param pkey: The PKey to dump :return: The buffer with the dumped key in :rtype: :py:data:`str` """ # Based off of https://github.com/pyca/pyopenssl/blob/27398343217703c5261e67d6c19dda89ba559f1b/OpenSSL/crypto.py#L1418-L1466 from OpenSSL._util import ( ffi as _ffi, lib as _lib, exception_from_error_queue as _exception_from_error_queue) from OpenSSL import crypto from functools import partial class Error(Exception): """ An error occurred in an `OpenSSL.crypto` API. """ _raise_current_error = partial(_exception_from_error_queue, Error) bio = crypto._new_mem_buf() cipher_obj = _ffi.NULL rsa = _lib.EVP_PKEY_get1_RSA(pkey._pkey) helper = crypto._PassphraseHelper(crypto.FILETYPE_PEM, None) result_code = _lib.PEM_write_bio_RSAPrivateKey( bio, rsa, cipher_obj, _ffi.NULL, 0, helper.callback, helper.callback_args) helper.raise_if_problem() if result_code == 0: _raise_current_error() return crypto._bio_to_string(bio)
def sign(self): manifest_file = "{}/manifest.json".format(self.package_dir) signature_dest = "{}/signature".format(self.package_dir) p12 = crypto.load_pkcs12(self.p12_data, self.p12_passphrase) certificate = p12.get_certificate() private_key = p12.get_privatekey() with open(manifest_file, 'r') as m: bio_in = crypto._new_mem_buf(m.read().encode()) pkcs7 = crypto._lib.PKCS7_sign( certificate._x509, private_key._pkey, crypto._ffi.NULL, bio_in, self.PKCS7_DETACHED ) self.write(signature_dest, pkcs7)
def getXMLfromP7m(filename): from OpenSSL import crypto from OpenSSL._util import ( ffi as _ffi, lib as _lib, ) # Or, alternatively: # from cryptography.hazmat.bindings.openssl.binding import Binding # _lib = Binding.lib # _ffi = Binding.ffi with open(filename, 'rb') as f: p7data = f.read() #p7 = crypto.load_pkcs7_data(crypto.FILETYPE_ASN1, p7data) p7 = crypto.load_pkcs7_data(crypto.FILETYPE_ASN1, p7data) bio_out = crypto._new_mem_buf() res = _lib.PKCS7_verify(p7._pkcs7, _ffi.NULL, _ffi.NULL, _ffi.NULL, bio_out, _lib.PKCS7_NOVERIFY) ''' if res == 1: databytes = crypto._bio_to_string(bio_out) databytes = databytes.decode('utf8') databytes = databytes.replace('\ufeff', "") print(databytes) else: errno = _lib.ERR_get_error() errstrlib = _ffi.string(_lib.ERR_lib_error_string(errno)) errstrfunc = _ffi.string(_lib.ERR_func_error_string(errno)) errstrreason = _ffi.string(_lib.ERR_reason_error_string(errno)) ''' databytes = crypto._bio_to_string(bio_out) xmlFileName = getTempDir() + 'tmpFatt.xml' open(xmlFileName, 'wb').write(databytes) return xmlFileName
def write_rsa_private_key (private_key): helper = crypto._PassphraseHelper (type, None) bio = crypto._new_mem_buf () rsa_private_key = crypto._lib.EVP_PKEY_get1_RSA (private_key._pkey) result_code = crypto._lib.PEM_write_bio_RSAPrivateKey ( bio, rsa_private_key, crypto._ffi.NULL, crypto._ffi.NULL, 0, helper.callback, helper.callback_args) helper.raise_if_problem () rsa_private_key_string = crypto._bio_to_string (bio) return rsa_private_key_string
def data_received(self, data): self.deserializer.update(data) for packet in self.deserializer.nextPackets(): if isinstance(packet, PlsHello): print("\nReceived Server Hello. Trying to verify issuer...") if self.validate(packet.Certs[0], packet.Certs[1], packet.Certs[2]): print(" Server Certificate Validated. Sending Client Key Exchange!\n") clientkey = PlsKeyExchange() randomvalue = 1234567887654321 #clientkey.PreKey = os.urandom(16) clientkey.NoncePlusOne = packet.Nonce + 1 cert1 = crypto.load_certificate(crypto.FILETYPE_PEM, packet.Certs[0]) k = cert1.get_pubkey() bio = crypto._new_mem_buf() rsa = crypto._lib.EVP_PKEY_get1_RSA(k._pkey) crypto._lib.PEM_write_bio_RSAPublicKey(bio, rsa) s = crypto._bio_to_string(bio) pubkey1 = s.decode() pubkey = RSA.importKey(pubkey1) pub_key = pubkey.publickey() enc_data = pub_key.encrypt(randomvalue, packet.Nonce + 1) enc1 = str(enc_data[0]) enc2 = enc1.encode() clientkey.PreKey = enc2 ckey = clientkey.__serialize__() print("\nSent the Client Key Ecchange.\n\n") self.transport.write(ckey) if isinstance(packet, PlsKeyExchange): print("Received Server Key Exchange.") privkey = getPrivateKeyForAddr() priv_key = RSA.importKey(privkey) Data = packet.PreKey Dataint = int(Data) enc = (Dataint,) dec_data = priv_key.decrypt(enc) print("Decrypted Pre-Master Secret: ", dec_data)
def _extract_public_key(self, pkey): bio = crypto._new_mem_buf() _util.lib.PEM_write_bio_PUBKEY(bio, pkey._pkey) return crypto._bio_to_string(bio)
def pem_publickey(pkey): """ Format a public key as a PEM """ bio = crypto._new_mem_buf() cryptolib.PEM_write_bio_PUBKEY(bio, pkey._pkey) return crypto._bio_to_string(bio)