def sign_tra(self, private_key, certificate): smime = SMIME.SMIME() ks = BIO.MemoryBuffer(private_key.encode('ascii')) cs = BIO.MemoryBuffer(certificate.encode('ascii')) bf = BIO.MemoryBuffer(str(self._create_tra())) out = BIO.MemoryBuffer() try: smime.load_key_bio(ks, cs) except Exception: raise Exception( 'Error en el formato del certificado o clave privada') sbf = smime.sign(bf) smime.write(out, sbf) head, body, end = out.read().split('\n\n') return body
def load_request_der_string(string): # type: (AnyStr) -> Request """ Load certificate request from a string. :param string: String containing a certificate request in DER format. :return: M2Crypto.X509.Request object. """ string = six.ensure_binary(string) bio = BIO.MemoryBuffer(string) return load_request_bio(bio, FORMAT_DER)
def generate_rsa_key(length = 1024): """ Generate new RSA key and return (PEM, fingerprint). """ key = RSA.gen_key(length, m2.RSA_F4, callback = lambda: None) kmem = BIO.MemoryBuffer() key.save_key_bio(kmem, cipher = None) keypem = kmem.getvalue() pub_kmem = BIO.MemoryBuffer() key.save_pub_key_bio(pub_kmem) pub_keypem = pub_kmem.getvalue() pkey = EVP.PKey(md = "sha1") pkey.assign_rsa(key) fingerprint = key_fingerprint(pkey) return (keypem, pub_keypem, fingerprint)
def get_value(self, flag=0, indent=0): # type: (int, int) -> str """ Get the extension value, for example 'DNS:www.example.com'. :param flag: Flag to control what and how to print. :param indent: How many spaces to print before actual value. """ buf = BIO.MemoryBuffer() m2.x509_ext_print(buf.bio_ptr(), self.x509_ext, flag, indent) return util.py3str(buf.read_all())
def unpack_certificate(certificatePem): """ Unpack X509 PEM-encoded certificate. :param certificatePem: PEM encoded X509 certificate. :type certificatePem: str :returns dict -- Detailed information from the certificate. """ cert = X509.load_cert_bio(BIO.MemoryBuffer(certificatePem)) cert_pkey_fingerprint = key_fingerprint(cert.get_pubkey()) res = {} ## we include the reserialized PEM encoding (which in principle ## should be identical to certificatePem .. but who knows .. this ## is x509 crap) res["pem"] = cert.as_pem() res["text"] = cert.as_text() res["fingerprint"] = cert_fingerprint(cert) ## we convert this to dotted hex, since the version ## might be a unsigned long (8 bytes) which i.e. JavaScript ## can't consume serial = "0x%x" % cert.get_serial_number() res["serial"] = dotted(serial[2:]) res["version"] = cert.get_version() res["issuer"] = info_from_x509name(cert.get_issuer()) res["subject"] = info_from_x509name(cert.get_subject()) now = datetime.datetime.utcnow() ## we need to strip of timezone info, since we cannot compare ## datetime with/without tzinfo, and Python utcnow() for strange ## reasons does not contain tzinfo. The date returned from cert ## should be UTC anyway. before = cert.get_not_before().get_datetime() before = before.replace(tzinfo = None) after = cert.get_not_after().get_datetime() after = after.replace(tzinfo = None) UTC_TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%SZ" res["not-valid-before"] = before.strftime(UTC_TIMESTAMP_FORMAT) res["not-valid-after"] = after.strftime(UTC_TIMESTAMP_FORMAT) res["valid-now"] = before <= now and now <= after pubkey = cert.get_pubkey() res["public-key"] = {"length": pubkey.size() * 8, "fingerprint": key_fingerprint(pubkey)} res["is-selfsigned"] = True if cert.verify(pubkey) == 1 else False return res
def sign_tra(tra, cert=CERT, privatekey=PRIVATEKEY, passphrase=""): "Firmar PKCS#7 el TRA y devolver CMS (recortando los headers SMIME)" if BIO: # Firmar el texto (tra) usando m2crypto (openssl bindings para python) buf = BIO.MemoryBuffer(tra) # Crear un buffer desde el texto #Rand.load_file('randpool.dat', -1) # Alimentar el PRNG s = SMIME.SMIME() # Instanciar un SMIME # soporte de contraseña de encriptación (clave privada, opcional) callback = lambda *args, **kwarg: passphrase # Cargar clave privada y certificado if privatekey.startswith("-----BEGIN RSA PRIVATE KEY-----"): key_bio = BIO.MemoryBuffer(privatekey) crt_bio = BIO.MemoryBuffer(cert) s.load_key_bio(key_bio, crt_bio, callback) # (desde buffer) elif os.path.exists(privatekey) and os.path.exists(cert): s.load_key(privatekey, cert, callback) # (desde archivo) else: raise RuntimeError("Archivos no encontrados: %s, %s" % (privatekey, cert)) p7 = s.sign(buf, 0) # Firmar el buffer out = BIO.MemoryBuffer() # Crear un buffer para la salida s.write(out, p7) # Generar p7 en formato mail #Rand.save_file('randpool.dat') # Guardar el estado del PRNG's # extraer el cuerpo del mensaje (parte firmada) msg = email.message_from_string(out.read()) for part in msg.walk(): filename = part.get_filename() if filename == "smime.p7m": # es la parte firmada? return part.get_payload(decode=False) # devolver CMS else: # Firmar el texto (tra) usando OPENSSL directamente out = Popen([ "openssl", "smime", "-sign", "-signer", cert, "-inkey", privatekey, "-outform", "DER", "-nodetach" ], stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate(tra)[0] return b64encode(out)
def load_key_string_pubkey(string, callback=util.passphrase_callback): # type: (AnyStr, Callable) -> PKey """ Load an M2Crypto.EVP.PKey from a public key as a string. :param string: String containing the key in PEM format. :param callback: A Python callable object that is invoked to acquire a passphrase with which to protect the key. :return: M2Crypto.EVP.PKey object. """ bio = BIO.MemoryBuffer(string) return load_key_bio_pubkey(bio, callback)
def processSignedPlist(infile): certstore_path = "/etc/ssl/certs/ca-certificates.crt" file_descriptor = infile input_bio = BIO.MemoryBuffer(file_descriptor) signer = SMIME.SMIME() cert_store = X509.X509_Store() cert_store.load_info(certstore_path) signer.set_x509_store(cert_store) try: p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(input_bio._ptr()), 1) except SMIME.SMIME_Error, e: logging.error('load pkcs7 error: ' + str(e))
def sign_file_with_ds_certificate(self, filename): if not os.access(filename, os.R_OK): # se riesco a leggere il file da firmare self.logger.error("No file to sign '%s' found" % filename) return None if not self.load_engine(): return None # nel caso sia fallito il caricamento scard_pin = self.config.get_smartcard_pin( ) # ottengo il pin della smartcard if scard_pin is None: return None filename_desc = open(filename) input_bio = BIO.File(filename_desc) smartcard = SmartcardFetcher.SmartcardFetcher( self.smartcard_driver_path, self.logger) self.logger.status("get digital signature id") ds_id = smartcard.get_ds_id( ) # ottengo l'id per estrarre il certificato dall smartcard # ottengo la chiave privata self.logger.status("get private key reference") pkey = self.get_ds_private_key( ds_id) # otteno la chiave privata tramite l'id if pkey is None: return False # ottengo il certificato self.logger.status("get certificate reference") certificate = self.get_ds_certificate(ds_id) if certificate is None: return False signer = SMIME.SMIME() signer.pkey = pkey signer.x509 = certificate # firmo il buffer pkcs7 = signer.sign(input_bio) # TODO da aggiungere try-except # creo un buffere di uscita out = BIO.MemoryBuffer() pkcs7.write_der(out) # per scriverlo in pem pkcs11.write(out) p7m_out = open("%s.p7m" % filename, "w") p7m_out.write(out.read()) self.logger.status('file firmato correttamente') return True
def ca_do_everything(DevicePublicKey): rsa = generate_rsa_key() privateKey = make_pkey(rsa) req = make_request(privateKey, 'The Issuer Monkey') cert = make_cert(req, privateKey) rsa2 = load_pub_key_bio( BIO.MemoryBuffer(convert_pkcs1_to_pkcs8_pubkey(DevicePublicKey))) pkey2 = EVP.PKey() pkey2.assign_rsa(rsa2) req = make_request(pkey2, 'Device') cert2 = make_cert(req, privateKey) return cert.as_pem(), privateKey.as_pem(None), cert2.as_pem()
def m2_MemoryBuffer_from_ct_ptr(ct_bio): # generate and immeidately free a BIO object so that we can get a # reference to the underlying SwigPyObject m2_buf = BIO.MemoryBuffer() m2.bio_free( m2_buf._ptr()) # even though we've free'd we still have the ref # replace the pointer change_swig_ptr(m2_buf._ptr(), ct_bio) # return the MemoryBuffer object (that references our ctypes BIO obj) return m2_buf
def GenerateRSAKey(passphrase=None, key_length=2048): """Generate an RSA key and return tuple of pem strings for (priv,pub) keys.""" if passphrase is not None: passphrase_cb = lambda: passphrase else: passphrase_cb = None key = RSA.gen_key(key_length, 65537) priv_key = key.as_pem(passphrase_cb) bio = BIO.MemoryBuffer() key.save_pub_key_bio(bio) pub_key = bio.read() return priv_key, pub_key
def as_text(self, flags=0): # type: (int) -> str """output an ASN1_STRING structure according to the set flags. @param flags: determine the format of the output by using predetermined constants, see ASN1_STRING_print_ex(3) manpage for their meaning. @return: output an ASN1_STRING structure. """ buf = BIO.MemoryBuffer() m2.asn1_string_print_ex(buf.bio_ptr(), self.asn1str, flags) return buf.read_all()
def test_007_test_key_generation(self): user = self.users.get_user('test1') private_key, fingerprint = user.generate_key_pair('public2') key = RSA.load_key_string(private_key, callback=lambda: None) bio = BIO.MemoryBuffer() public_key = user.get_key_pair('public2').public_key key.save_pub_key_bio(bio) converted = crypto.ssl_pub_to_ssh_pub(bio.read()) # assert key fields are equal self.assertEqual( public_key.split(" ")[1].strip(), converted.split(" ")[1].strip())
def RSA_keypair_to_pub_key_in_der(keypair): from M2Crypto import RSA, BIO bio = BIO.MemoryBuffer() keypair.save_pub_key_bio(bio) pem = bio.read_all() stream = StringIO(pem) lines = stream.readlines() s = '' for i in range(1, len(lines) - 1): s += lines[i] return base64.standard_b64decode(s)
def verifySignature(signaturePkcs7, hash, chainOfTrust): # see also in AM: src/crypto-lib/signature.cpp / Signature::verify() s = SMIME.SMIME() bioSignature = BIO.MemoryBuffer(data=base64.decodestring(signaturePkcs7)) signature = SMIME.load_pkcs7_bio(bioSignature) bioHash = BIO.MemoryBuffer(data=hash) certChain = X509.X509_Store() for trustedCert in chainOfTrust: bioCert = BIO.MemoryBuffer(data=trustedCert) while len(bioCert): cert = X509.load_cert_bio(bioCert, X509.FORMAT_PEM) certChain.add_x509(cert) s.set_x509_store(certChain) s.set_x509_stack(X509.X509_Stack()) s.verify(signature, bioHash, SMIME.PKCS7_NOCHAIN)
def load_request_der_string(string): """ Load certificate request from a string. @type string: string @param string: String containing a certificate request in DER format. @rtype: M2Crypto.X509.Request @return: M2Crypto.X509.Request object. """ bio = BIO.MemoryBuffer(string) return load_request_bio(bio, FORMAT_DER)
def encrypt(self, plaintext, receiver_name): """Encrypt message. Requires recipient cert. Returns encrypted message. """ sm = self.get_encrypt_ctx(receiver_name) # encrypt data bdata = BIO.MemoryBuffer(plaintext) pk = sm.encrypt(bdata, SMIME.PKCS7_BINARY) # return ciphertext buf = BIO.MemoryBuffer() if RAW_MESSAGES: pk.write_der(buf) else: pk.write(buf) return buf.read()
def from_pem_data(cls, data=None, filename=None): """Alternative constructor for loading from PEM format data.""" self = cls.__new__(cls) if data is not None: bio = BIO.MemoryBuffer(str(data)) elif filename is not None: bio = BIO.openfile(filename) else: msg = "Please specify either 'data' or 'filename' argument." raise ValueError(msg) self.keyobj = self.KEY_MODULE.load_pub_key_bio(bio) return self
def test_signing(self): message = 'hello' key = RSA.load_key_bio(BIO.MemoryBuffer(RSA_KEY)) # test authenticator = Authenticator() authenticator.rsa_key = key signature = authenticator.sign(message) #validation self.assertEqual(signature, key.sign(message))
def _constructEcFromRawKeys(self, rawPrivateKey, rawPublicKey): assert (len(rawPrivateKey) == 32) assert (len(rawPublicKey) == 64) bytes1 = a2b_hex("02010104") bytes2 = a2b_hex("a00a06082a8648ce3d030107a14403420004") rawPrivateKey = toAsn1IntBytes(rawPrivateKey) b = bytes1 + asn1Length(len(rawPrivateKey)) + rawPrivateKey +\ bytes2 + rawPublicKey b = bytearray([0x30]) + asn1Length(len(b)) + b pemPrivKeyBytes = PEMEncoder(b).getEncoded("EC PRIVATE KEY") return EC.load_key_bio(BIO.MemoryBuffer(pemPrivKeyBytes))
def generateMasterkey(): """Generate an M2Crypto Elliptic Curve key. """ membuffer = BIO.MemoryBuffer() keypair = EC.gen_params(EC.NID_sect233k1) keypair.gen_key() keypair.save_pub_key_bio(membuffer) rawpubkey = membuffer.read() membuffer.reset() fpubkey = rawpubkey[27:] fpubkey = fpubkey[:string.find(fpubkey, '-')] return fpubkey # BASE64 ENCODED
def _readX509List(self, pemString): x509List = [] bio = BIO.MemoryBuffer(pemString) try: while True: cert = X509.load_cert_bio(bio) x509List.append(cert) except X509.X509Error: pass return x509List
def ca_do_everything(DevicePublicKey): rsa = generateRSAKey() privateKey = makePKey(rsa) req = makeRequest(privateKey, "The Issuer Monkey") cert = makeCert(req, privateKey) rsa2 = load_pub_key_bio( BIO.MemoryBuffer(convertPKCS1toPKCS8pubKey(DevicePublicKey))) pkey2 = EVP.PKey() pkey2.assign_rsa(rsa2) req = makeRequest(pkey2, "Device") cert2 = makeCert(req, privateKey) return cert.as_pem(), privateKey.as_pem(None), cert2.as_pem()
def get_key(consumer_id): """ Get the consumer's public RSA key. :return: The consumer's public RSA key. :rtype: RSA.RSA """ rsa_pub = 'rsa_pub' manager = managers.consumer_manager() consumer = manager.get_consumer(consumer_id, fields=[rsa_pub]) pem = consumer[rsa_pub] bfr = BIO.MemoryBuffer(str(pem)) return RSA.load_pub_key_bio(bfr)
def encrypt(self, attributes): plaintext = '' for key, value in attributes.items(): plaintext += u'%s=%s\n' % (key, value) plaintext = plaintext.encode('utf-8') # Instantiate an SMIME object. s = SMIME.SMIME() # Load signer's key and cert. Sign the buffer. s.load_key_bio(BIO.openfile(PAYPAL_PRIVATE_KEY), BIO.openfile(PAYPAL_PUBLIC_KEY)) p7 = s.sign(BIO.MemoryBuffer(plaintext), flags=SMIME.PKCS7_BINARY) # Load target cert to encrypt the signed message to. x509 = X509.load_cert_bio(BIO.openfile(PAYPAL_PAYPAL_CERT)) sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) # Set cipher: 3-key triple-DES in CBC mode. s.set_cipher(SMIME.Cipher('des_ede3_cbc')) # Create a temporary buffer. tmp = BIO.MemoryBuffer() # Write the signed message into the temporary buffer. p7.write_der(tmp) # Encrypt the temporary buffer. p7 = s.encrypt(tmp, flags=SMIME.PKCS7_BINARY) # Output p7 in mail-friendly format. out = BIO.MemoryBuffer() p7.write(out) return out.read()
def _encrypt_data(self, data): """ Encrypt the form data. Refer to http://sandbox.rulemaker.net/ngps/m2/howto.smime.html """ # Don't import at top because these are only required if user wants encryption from M2Crypto import BIO, SMIME, X509 certid = self.settings["PUBLIC_CERT_ID"] # Assemble form data and encode in utf-8 raw = ["cert_id=%s" % certid] raw.extend([u"%s=%s" % (key, val) for key, val in data.items() if val]) raw = "\n".join(raw) raw = raw.encode("utf-8") self.log.debug('Encrypted Paypal data: %s' % raw) # make an smime object s = SMIME.SMIME() # load our public and private keys s.load_key_bio(BIO.openfile(self.localprikey), BIO.openfile(self.localpubkey)) # put the data in the buffer buf = BIO.MemoryBuffer(raw) # sign the text p7 = s.sign(buf, flags=SMIME.PKCS7_BINARY) # Load target cert to encrypt to. x509 = X509.load_cert_bio(BIO.openfile(self.paypalpubkey)) sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) # Set cipher: 3-key triple-DES in CBC mode. s.set_cipher(SMIME.Cipher("des_ede3_cbc")) # save data to buffer tmp = BIO.MemoryBuffer() p7.write_der(tmp) # encrypt p7 = s.encrypt(tmp, flags=SMIME.PKCS7_BINARY) out = BIO.MemoryBuffer() # write into a new buffer p7.write(out) return out.read()
def _createRegistrationResponseMessage(self, client_data, key_set=None, correct=True): """ Create a registration response message according to the FIDO U2F specification """ if not key_set: raise ValueError("Unknown key number requested!") (key_handle_hex, ecc_key) = key_set # # Create the registration_data object # registration_data = chr(0x05) # First byte must be 0x05 # The public key length is set to a fixed length of 65 characters in the U2F specification public_key = str(ecc_key.pub().get_der())[-65:] registration_data += public_key key_handle = binascii.unhexlify(key_handle_hex) registration_data += chr(len(key_handle)) registration_data += key_handle attestation_cert_der = binascii.unhexlify(self.ATTESTATION_CERT_HEX) registration_data += attestation_cert_der # Create the ECDSA signature digest = sha256() digest.update( chr(0x00) + sha256(self.origin).digest() + sha256(client_data).digest() + key_handle + public_key) cert_private_key = EC.load_key_bio( BIO.MemoryBuffer(self.ATTESTATION_PRIVATE_KEY_PEM)) signature = cert_private_key.sign_dsa_asn1(digest.digest()) if correct is False: # Change the signature to create an invalid registration response signature = signature[:-1] registration_data += signature # # Create the registration_response # registration_response = { 'registrationData': base64.urlsafe_b64encode(registration_data), 'clientData': base64.urlsafe_b64encode(client_data) } return json.dumps(registration_response)
def _encrypt(self): """Use your key thing to encrypt things.""" from M2Crypto import BIO, SMIME, X509 # ### ToDo: Could we move this to conf.py? CERT = settings.PAYPAL_PRIVATE_CERT PUB_CERT = settings.PAYPAL_PUBLIC_CERT PAYPAL_CERT = settings.PAYPAL_CERT CERT_ID = settings.PAYPAL_CERT_ID # Iterate through the fields and pull out the ones that have a value. plaintext = 'cert_id=%s\n' % CERT_ID for name, field in self.fields.iteritems(): value = None if name in self.initial: value = self.initial[name] elif field.initial is not None: value = field.initial if value is not None: # ### Todo - make this less hackish and put it in the widget. if name == "return_url": name = "return" plaintext += u'%s=%s\n' % (name, value) plaintext = plaintext.encode('utf-8') # Begin crypto weirdness. s = SMIME.SMIME() s.load_key_bio(BIO.openfile(CERT), BIO.openfile(PUB_CERT)) p7 = s.sign(BIO.MemoryBuffer(plaintext), flags=SMIME.PKCS7_BINARY) x509 = X509.load_cert_bio(BIO.openfile(settings.PAYPAL_CERT)) sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) s.set_cipher(SMIME.Cipher('des_ede3_cbc')) tmp = BIO.MemoryBuffer() p7.write_der(tmp) p7 = s.encrypt(tmp, flags=SMIME.PKCS7_BINARY) out = BIO.MemoryBuffer() p7.write(out) return out.read()
def load_key_string(string, callback=util.passphrase_callback): # type: (AnyStr, Callable) -> RSA """ Load an RSA key pair from a string. @param string: String containing RSA key pair in PEM format. @param callback: A Python callable object that is invoked to acquire a passphrase with which to unlock the key. The default is util.passphrase_callback. @return: M2Crypto.RSA.RSA object. """ bio = BIO.MemoryBuffer(string) return load_key_bio(bio, callback)