def _makeContext(self): ctx = SSL.Context(self.method) if self.certificate is not None and self.privateKey is not None: if isinstance(self.certificate, basestring): ctx.use_certificate(crypto.load_certificate( crypto.FILETYPE_PEM, self.certificate)) else: ctx.use_certificate(crypto.load_certificate( crypto.FILETYPE_PEM, self.certificate.content)) if isinstance(self.privateKey, basestring): ctx.use_privatekey(crypto.load_privatekey( crypto.FILETYPE_PEM, self.privateKey)) else: ctx.use_privatekey(crypto.load_privatekey( crypto.FILETYPE_PEM, self.privateKey.privateKey)) # Sanity check ctx.check_privatekey() verifyFlags = SSL.VERIFY_NONE if self.verify: verifyFlags = SSL.VERIFY_PEER if self.requireCertificate: verifyFlags |= SSL.VERIFY_FAIL_IF_NO_PEER_CERT if self.verifyOnce: verifyFlags |= SSL.VERIFY_CLIENT_ONCE if self.caCerts: store = ctx.get_cert_store() if isinstance(self.caCerts, basestring): store.add_cert(crypto.load_certificate( crypto.FILETYPE_PEM, self.caCerts)) else: for cert in self.caCerts: content = None if isinstance(cert, basestring): content = cert else: content = cert.content store.add_cert(crypto.load_certificate( crypto.FILETYPE_PEM, content)) ctx.set_verify(verifyFlags, self._verify) if self.verifyDepth is not None: ctx.set_verify_depth(self.verifyDepth) if self.enableSingleUseKeys: ctx.set_options(SSL.OP_SINGLE_DH_USE) if self.fixBrokenPeers: ctx.set_options(self._OP_ALL) if self.enableSessions: sessionName = md5.md5("%s-%d" % (reflect.qual(self.__class__), _sessionCounter())).hexdigest() ctx.set_session_id(sessionName) return ctx
def test_certificateRoundtrip(self): """A certificate can be dumped to a string and read again. """ cert = certificate._makeCertificate(testKey, u"*****@*****.**") data = crypto.dump_certificate(crypto.FILETYPE_PEM, cert) crypto.load_certificate(crypto.FILETYPE_PEM, data)
def test_create_ca_and_signing_pairs(self): # use one common test to avoid generating CA pair twice # do not mock out pyOpenSSL, test generated keys/certs # create CA pair ca_key_pem, ca_cert_pem = keystone_pki.create_ca_pair() ca_key = crypto.load_privatekey(crypto.FILETYPE_PEM, ca_key_pem) ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, ca_cert_pem) # check CA key properties self.assertTrue(ca_key.check()) self.assertEqual(2048, ca_key.bits()) # check CA cert properties self.assertFalse(ca_cert.has_expired()) self.assertEqual('Keystone CA', ca_cert.get_issuer().CN) self.assertEqual('Keystone CA', ca_cert.get_subject().CN) # create signing pair signing_key_pem, signing_cert_pem = keystone_pki.create_signing_pair( ca_key_pem, ca_cert_pem) signing_key = crypto.load_privatekey(crypto.FILETYPE_PEM, signing_key_pem) signing_cert = crypto.load_certificate(crypto.FILETYPE_PEM, signing_cert_pem) # check signing key properties self.assertTrue(signing_key.check()) self.assertEqual(2048, signing_key.bits()) # check signing cert properties self.assertFalse(signing_cert.has_expired()) self.assertEqual('Keystone CA', signing_cert.get_issuer().CN) self.assertEqual('Keystone Signing', signing_cert.get_subject().CN)
def _getCertsFromCell(cell): if cell.num_certs != 2: msg = ("Expected 2 certificates in CertsCell, found " "{}.".format(cell.num_certs)) raise ValueError(msg) link_cert = None id_cert = None for cert_item in cell.cert_payload_items: try: pem_cert = ssl.DER_cert_to_PEM_cert(cert_item.cert) if cert_item.cert_type == LINK_CERT_TYPE: link_cert = SSLCrypto.load_certificate(SSLCrypto.FILETYPE_PEM, pem_cert) elif cert_item.cert_type == ID_CERT_TYPE: id_cert = SSLCrypto.load_certificate(SSLCrypto.FILETYPE_PEM, pem_cert) else: msg = ("Expected a link certificate type or an id certificate " "type. Got {} certificate type." .format(cert_item.cert_type)) raise ValueError(msg) except SSLCrypto.Error as e: raise ValueError("Certificate decoding failed: {}.", e) if link_cert is None or id_cert is None: msg = ("CertsCell must have both a link certificate and an id " "certificate.") raise ValueError(msg) return (link_cert, id_cert)
def cacheContext(self): if self._context is None: ctx = SSL.Context(self.sslmethod) ctx.set_options(SSL.OP_CIPHER_SERVER_PREFERENCE | SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3 | SSL.OP_SINGLE_DH_USE | SSL.OP_NO_COMPRESSION | SSL.OP_NO_TICKET) ctx.set_mode(SSL.MODE_RELEASE_BUFFERS) first = True if os.path.isfile(self.certificateFilePath): with open(self.certificateFilePath, 'r') as f: first = False x509 = load_certificate(FILETYPE_PEM, f.read()) ctx.use_certificate(x509) if os.path.isfile(self.intermediateFilePath): if first: ctx.use_certificate_chain_file(self.intermediateFilePath) else: with open(self.intermediateFilePath, 'r') as f: x509 = load_certificate(FILETYPE_PEM, f.read()) ctx.add_extra_chain_cert(x509) ctx.use_privatekey_file(self.privateKeyFilePath) ctx.set_cipher_list(self.cipherList) ctx.load_tmp_dh(self.dhFilePath) self._context = ctx
def ssl_context(cacert, srvcrt, srvkey): # general setup: TLSv1.2, no compression, paranoid ciphers sslctx = SSL.Context(SSL.TLSv1_2_METHOD) sslctx.set_verify_depth(9) sslctx.set_options(SSL.OP_NO_COMPRESSION) sslctx.set_mode(_ssl_lib.SSL_MODE_ENABLE_PARTIAL_WRITE | _ssl_lib.SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) sslctx.set_cipher_list(libmu.defs.Defs.cipher_list) sslctx.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, lambda _, __, ___, ____, ok: ok) # use CA cert provided during lambda invocation fmt_cert = format_ssl_cert(cacert) x509_cert = crypto.load_certificate(crypto.FILETYPE_PEM, fmt_cert) sslctx.get_cert_store().add_cert(x509_cert) # add my certificate chain has_cert = False for cert in srvcrt.split(' '): x509_cert = crypto.load_certificate(crypto.FILETYPE_PEM, format_ssl_cert(cert)) if not has_cert: sslctx.use_certificate(x509_cert) has_cert = True else: sslctx.add_extra_chain_cert(x509_cert) # private key sslctx.use_privatekey(crypto.load_privatekey(crypto.FILETYPE_PEM, format_ssl_key(srvkey))) # check that all's well sslctx.check_privatekey() return sslctx
def __init__(self, cert_str, inform='PEM'): if inform == 'PEM': c = XY509cert.pem_add_rfc7468_delimiters(cert_str) self.cert = crypto.load_certificate(crypto.FILETYPE_PEM, c) elif inform == 'DER': self.cert = crypto.load_certificate(crypto.FILETYPE_ASN1, cert_str) self.cert_str = cert_str
def loadCertificate(path): """Import an existing certificate from file to python object @param path [str] : the path to the certificate file to import @return [OpenSSL.crypto.X509] the certificate object that correspond to the certificate file [None] if an error occur """ assert path is not None try: # open file in binary mode f_cert = open(path, 'rb').read() except IOError as e: g_sys_log.error('Unable to open certificate file : ' + str(e)) return None try: # try to load the cert as PEM format cert = crypto.load_certificate(crypto.FILETYPE_PEM, f_cert) except crypto.Error as e: # if error try with another format try: # try to load the cert as ASN1 format cert = crypto.load_certificate(crypto.FILETYPE_ASN1, f_cert) g_sys_log.warning('Certificate "%s" is not in PEM recommanded format', path) except crypto.Error as e: g_sys_log.error('Unable to import certificate : ' + str(e)) return None return cert
def validate_tls_ca_cert(server_tls_dir, fs_name): pem, full_path = get_full_tls(server_tls_dir, 'ca-certs', fs_name) # Validate it's really a certificate and say, a public key crypto.load_certificate(crypto.FILETYPE_PEM, pem) return full_path
def get_first_certificates(ordered_list_of_certificates, result={}): """ctobs.issues.first_cert_dnsname""" """ctobs.issues.first_cert_cn""" """ctobs.issues.first_cert""" if (len(ordered_list_of_certificates) < 1): return result first_timestamp_str = crypto.load_certificate(crypto.FILETYPE_ASN1, bytes(ordered_list_of_certificates[0].certificate)).get_notBefore() first_timestamp = parser.parse(first_timestamp_str) for certificate in ordered_list_of_certificates: ID = certificate.id certificate_bin = certificate.certificate ca_id = certificate.issuer_ca.id certificate = crypto.load_certificate(crypto.FILETYPE_ASN1, bytes(certificate_bin)) current_timestamp_str = certificate.get_notBefore() current_timestamp = parser.parse(current_timestamp_str) if (current_timestamp == first_timestamp): if(ID not in result): result[ID] = [] result[ID].append("ctobs.issues.first_cert") else: # the certificates are ordered, so there will # be no certificate with a smaller timestamp break return result
def main(args): if len(args) < 1: print "Usage submitcert.py [filename(s) to certificate chain to submit]" sys.exit(1) fname = args[0] operation = 'ct/v1/add-chain' url = 'https://ct.googleapis.com/aviator/{}'.format(operation) certlist = [] for fname in args: # Read in cert file; if it is PEM formatted convert it # to DER first fhandle = io.BufferedReader(io.open(fname,'br')) pemflag = False b = fhandle.read(20) if not b: print "File empty" else: if("-----BEGIN" in b): pemflag = True b64str = "" dercert = "" if pemflag: # Convert the PEM cert in memory to DER format, then # base64 convert the result. This is safer than manually # parsing PEM cert to remove PEM headers and line breaks fhandle.seek(0) certdata = fhandle.read() # read all data certobj = crypto.load_certificate(crypto.FILETYPE_PEM,certdata) dercert = crypto.dump_certificate(crypto.FILETYPE_ASN1,certobj) # debug test fhandle = io.open(".\derconv.cer","wb+") fhandle.write(dercert) #b64str = base64.b64encode(dercert) else: fhandle.seek(0) certdata = fhandle.read() # confirm this is single DER encoded cert try: dercert = crypto.load_certificate(crypto.FILETYPE_ASN1,certdata) except: print "no der" b64str = base64.b64encode(dercert) certlist.append(b64str) payload = {'chain':certlist} headers = {'content-type':'application/json'} r = requests.post(url,data=json.dumps(payload),headers=headers) if r.status_code == 200: print "sent log" respbody = r.json() tstamp = int(respbody["timestamp"]) / 1000 # convert milliseconds to seconds print "Log ID: {0}, Timestamp: {1}".format(respbody["id"],datetime.datetime.fromtimestamp(tstamp).strftime('%Y-%m-%d %H:%M:%S')) else: print r.status_code print r.text
def test_create_temp_self_signed_cert_returns_cert_as_first_value(self): with open(self.cert, 'rb') as f: data = f.read() try: crypto.load_certificate(crypto.FILETYPE_PEM, data) except crypto.Error: self.fail('First file is not a certificate')
def make_pkcs12(key, cert, caCerts=None): pkc = crypto.PKCS12() pkc.set_certificate(crypto.load_certificate(crypto.FILETYPE_PEM,cert)) pkc.set_privatekey(crypto.load_privatekey(crypto.FILETYPE_PEM,key,b"mypassword")) if caCerts is not None: pkc.set_ca_certificates([crypto.load_certificate(crypto.FILETYPE_PEM,cert) for cert in caCerts]) pkc_bytes = pkc.export("mypassword") return pkc_bytes
def verify_valid_cert(self, secret_ref): secret_resp = self.secret_behaviors.get_secret( secret_ref, "application/pkix-cert") self.assertIsNotNone(secret_resp) self.assertIsNotNone(secret_resp.content) cert = secret_resp.content crypto.load_certificate(crypto.FILETYPE_PEM, cert)
def cert(self): self.ensure_exists() if self.cert_path: with open(self.cert_path) as cert_fh: return crypto.load_certificate(crypto.FILETYPE_PEM, cert_fh.read()) else: return crypto.load_certificate(crypto.FILETYPE_PEM, self._cert_val)
def test03_ssl_verification(self): # SSL verification callback # Ensure no relevant environment variables are set which might affect # the result try: serverDN = os.environ.get( MyProxyClient.MYPROXY_SERVER_DN_ENVVARNAME) if serverDN is not None: del os.environ[MyProxyClient.MYPROXY_SERVER_DN_ENVVARNAME] serverName = os.environ.get(MyProxyClient.MYPROXY_SERVER_ENVVARNAME) if serverName is not None: del os.environ[MyProxyClient.MYPROXY_SERVER_ENVVARNAME] client = MyProxyClient() connection = None errorStatus = False successStatus = True errorDepth = 0 valid_peer_cert_str = open(self.__class__.HOSTCERT_FILEPATH).read() valid_peer_cert = crypto.load_certificate(crypto.FILETYPE_PEM, valid_peer_cert_str) # This would normally be called implicitly during the SSL handshake status = client.ssl_verification(connection, valid_peer_cert, errorStatus, errorDepth, successStatus) self.assertTrue(status == successStatus) expired_peer_cert_str = open( self.__class__.EXPIREDCERT_FILEPATH).read() expired_peer_cert = crypto.load_certificate(crypto.FILETYPE_PEM, expired_peer_cert_str) # Match based on full DN instead - this takes precedence over # hostname match client.serverDN = self.__class__.HOSTCERT_DN status = client.ssl_verification(connection, valid_peer_cert, errorStatus, errorDepth, successStatus) self.assertTrue(status == successStatus) # Check for expired certificate status = client.ssl_verification(connection, expired_peer_cert, errorStatus, errorDepth, successStatus) self.assertTrue(status == errorStatus) finally: if serverDN is not None: os.environ[MyProxyClient.MYPROXY_SERVER_DN_ENVVARNAME ] = serverDN if serverName is not None: os.environ[MyProxyClient.MYPROXY_SERVER_ENVVARNAME ] = serverName
def test_04_create_token_on_server(self): self.setUp_user_realms() cwd = os.getcwd() # setup ca connector r = save_caconnector({"cakey": CAKEY, "cacert": CACERT, "type": "local", "caconnector": "localCA", "openssl.cnf": OPENSSLCNF, "CSRDir": "", "CertificateDir": "", "WorkingDir": cwd + "/" + WORKINGDIR}) db_token = Token(self.serial3, tokentype="certificate") db_token.save() token = CertificateTokenClass(db_token) # missing user self.assertRaises(ParameterError, token.update, {"ca": "localCA","genkey": 1}) token.update({"ca": "localCA", "genkey": 1, "user": "******"}) self.assertEqual(token.token.serial, self.serial3) self.assertEqual(token.token.tokentype, "certificate") self.assertEqual(token.type, "certificate") detail = token.get_init_detail() certificate = detail.get("certificate") # At each testrun, the certificate might get another serial number! x509obj = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) self.assertEqual("{0!r}".format(x509obj.get_issuer()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=CA001'>") self.assertEqual("{0!r}".format(x509obj.get_subject()), "<X509Name object '/OU=realm1/CN=cornelius/[email protected]'>") # Test, if the certificate is also completely stored in the tokeninfo # and if we can retrieve it from the tokeninfo token = get_tokens(serial=self.serial3)[0] certificate = token.get_tokeninfo("certificate") x509obj = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) self.assertEqual("{0!r}".format(x509obj.get_issuer()), "<X509Name object '/C=DE/ST=Hessen" "/O=privacyidea/CN=CA001'>") self.assertEqual("{0!r}".format(x509obj.get_subject()), "<X509Name object '/OU=realm1/CN=cornelius/[email protected]'>") privatekey = token.get_tokeninfo("privatekey") self.assertTrue(privatekey.startswith("-----BEGIN PRIVATE KEY-----")) # check for pkcs12 self.assertTrue(detail.get("pkcs12")) # revoke the token r = token.revoke() self.assertEqual(r, int_to_hex(x509obj.get_serial_number()))
def run(self, id, updated_fields): def update_all_signed_certs_and_get_ids(old_signing_name, new_signing_name): certs = self.datastore.query('crypto.certificates', ('signing_ca_name', '=', old_signing_name)) for c in certs: c['signing_ca_name'] = new_signing_name self.datastore.update('crypto.certificates', c['id'], c) return [c['id'] for c in certs] ids = [id] if not self.datastore.exists('crypto.certificates', ('id', '=', id)): raise TaskException(errno.ENOENT, 'Certificate ID {0} does not exist'.format(id)) cert = self.datastore.get_by_id('crypto.certificates', id) if cert['type'] in ('CA_EXISTING', 'CERT_EXISTING'): if 'certificate' in updated_fields: try: crypto.load_certificate(crypto.FILETYPE_PEM, updated_fields['certificate']) except Exception: raise TaskException(errno.EINVAL, 'Invalid certificate') if 'privatekey' in updated_fields: try: crypto.load_privatekey(crypto.FILETYPE_PEM, updated_fields['privatekey']) except Exception: raise TaskException(errno.EINVAL, 'Invalid privatekey') if 'name' in updated_fields: if self.datastore.exists('crypto.certificates', ('name', '=', updated_fields['name'])): raise TaskException(errno.EEXIST, 'Certificate name : "{0}" already in use'.format(updated_fields['name'])) else: if len(updated_fields) > 1 or 'name' not in updated_fields: raise TaskException(errno.EINVAL, 'Only "name" field can be modified'.format(id)) if self.datastore.exists('crypto.certificates', ('name', '=', updated_fields['name'])): raise TaskException(errno.EEXIST, 'Certificate name : "{0}" already in use'.format(updated_fields['name'])) try: if 'certificate' in updated_fields: cert['certificate'] = updated_fields['certificate'] cert.update(get_cert_info(cert['certificate'])) if 'privatekey' in updated_fields: cert['privatekey'] = updated_fields['privatekey'] if 'name' in updated_fields: old_name = cert['name'] cert['name'] = updated_fields['name'] ids.extend(update_all_signed_certs_and_get_ids(old_name, cert['name'])) pkey = self.datastore.update('crypto.certificates', id, cert) self.dispatcher.call_sync('etcd.generation.generate_group', 'crypto') self.dispatcher.dispatch_event('crypto.certificate.changed', { 'operation': 'update', 'ids': ids }) except DatastoreException as e: raise TaskException(errno.EBADMSG, 'Cannot update certificate: {0}'.format(str(e))) except RpcException as e: raise TaskException(errno.ENXIO, 'Cannot generate certificate: {0}'.format(str(e))) return pkey
def run(self, certificate): if self.datastore.exists('crypto.certificates', ('name', '=', certificate['name'])): raise TaskException(errno.EEXIST, 'Certificate named "{0}" already exists'.format(certificate['name'])) new_cert_db_entry = {} new_cert_db_entry['name'] = certificate['name'] new_cert_db_entry['type'] = certificate['type'] if certificate.get('certificate_path'): imported_cert = crypto.load_certificate( crypto.FILETYPE_PEM, get_file_contents(certificate['certificate_path']).encode('utf-8')) elif certificate.get('certificate'): imported_cert = crypto.load_certificate(crypto.FILETYPE_PEM, certificate['certificate'].encode('utf-8')) else: imported_cert = False if imported_cert: new_cert_db_entry['certificate'] = crypto.dump_certificate( crypto.FILETYPE_PEM, imported_cert).decode('utf-8') new_cert_db_entry.update(get_cert_info(imported_cert)) new_cert_db_entry['serial'] = str(imported_cert.get_serial_number()) #certificate['selfsigned'] = False new_cert_db_entry['not_before'] = get_utc_string_from_asn1generalizedtime( imported_cert.get_notBefore().decode('utf-8')) new_cert_db_entry['not_after'] = get_utc_string_from_asn1generalizedtime( imported_cert.get_notAfter().decode('utf-8')) new_cert_db_entry['lifetime'] = 3650 else: new_cert_db_entry['certificate'] = "" if certificate.get('privatekey_path'): imported_privkey = crypto.load_privatekey( crypto.FILETYPE_PEM, get_file_contents(certificate['privatekey_path'])) elif certificate.get('privatekey'): imported_privkey = crypto.load_privatekey(crypto.FILETYPE_PEM, certificate['privatekey']) else: imported_privkey = False if imported_privkey: new_cert_db_entry['privatekey'] = crypto.dump_privatekey( crypto.FILETYPE_PEM, imported_privkey).decode('utf-8') new_cert_db_entry['key_length'] = imported_privkey.bits() else: new_cert_db_entry['privatekey'] = "" try: pkey = self.datastore.insert('crypto.certificates', new_cert_db_entry) self.dispatcher.call_sync('etcd.generation.generate_group', 'crypto') self.dispatcher.dispatch_event('crypto.certificate.changed', { 'operation': 'create', 'ids': [pkey] }) except DatastoreException as e: raise TaskException(errno.EBADMSG, 'Cannot import certificate: {0}'.format(str(e))) except RpcException as e: raise TaskException(errno.ENXIO, 'Cannot generate certificate: {0}'.format(str(e))) return pkey
def test_issue_certificate_request_stored_key(self): req = certificate_utils.get_valid_csr_object() req_enc = crypto.dump_certificate_request(crypto.FILETYPE_PEM, req) self.barbican_meta_dto.generated_csr = req_enc resp = self.plugin.issue_certificate_request( self.order_id, {}, {}, self.barbican_meta_dto) crypto.load_certificate( crypto.FILETYPE_PEM, resp.certificate.decode('base64'))
def verify(self, signing_cert_str, cert_str): """ Verifies if a certificate is valid and signed by a given certificate. :param signing_cert_str: This certificate will be used to verify the signature. Must be a string representation of the certificate. If you only have a file use the method read_str_from_file to get a string representation. :param cert_str: This certificate will be verified if it is correct. Must be a string representation of the certificate. If you only have a file use the method read_str_from_file to get a string representation. :return: Valid, Message Valid = True if the certificate is valid, otherwise false. Message = Why the validation failed. """ try: ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, signing_cert_str) cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_str) if self.certificate_not_valid_yet(ca_cert): return False, "CA certificate is not valid yet." if ca_cert.has_expired() == 1: return False, "CA certificate is expired." if cert.has_expired() == 1: return False, "The signed certificate is expired." if self.certificate_not_valid_yet(cert): return False, "The signed certificate is not valid yet." if ca_cert.get_subject().CN == cert.get_subject().CN: return False, ("CN may not be equal for CA certificate and the " "signed certificate.") cert_algorithm = cert.get_signature_algorithm() if six.PY3: cert_algorithm = cert_algorithm.decode('ascii') cert_str = cert_str.encode('ascii') cert_crypto = saml2.cryptography.pki.load_pem_x509_certificate( cert_str) try: crypto.verify(ca_cert, cert_crypto.signature, cert_crypto.tbs_certificate_bytes, cert_algorithm) return True, "Signed certificate is valid and correctly signed by CA certificate." except crypto.Error as e: return False, "Certificate is incorrectly signed." except Exception as e: return False, "Certificate is not valid for an unknown reason. %s" % str(e)
def get_certificate_using_session(self, session, server_url, pem_out_filepath=None): '''Obtain a create a new key pair and invoke the SLCS service to obtain a certificate using authentication method determined by input session object: the latter can be username/password using HTTPBasicAuth object or OAuth 2.0 access token with OAuth2Session :param session: Requests session containing the authentication context: either a session with a HTTBasicAuth object as its auth attribute or a requests_oauthlib.OAuth2Session :param server_url: URL for get certificate endpoint :param pem_out_filepath: optionally set output path for file containing concatenated private key and certificate issued :return: tuple of key pair object and certificate ''' if not isinstance(session, requests.Session): raise TypeError('Expecting requests.Session or ' 'oauthlib_requests.OAuth2Session type for session ' 'object') key_pair = self.__class__.create_key_pair() cert_req = self.__class__.create_cert_req(key_pair) req = {self.__class__.CERT_REQ_POST_PARAM_KEYNAME: cert_req} res = session.post(server_url, data=req, verify=self.ca_cert_dir) if not res.ok: raise OnlineCaClientErrorResponse('Error getting certificate' ': status: {} {}'.format( res.status_code, res.reason), res) # Response contains PEM-encoded certificate just issued + any additional # CA certificates in the chain of trust configured on the server-side. # Parse into OpenSSL.crypto.X509 objects cert_s = res.content.decode(encoding='utf-8') cert_list = [] for pem_cert_frag in cert_s.split('-----BEGIN CERTIFICATE-----')[1:]: pem_cert = '-----BEGIN CERTIFICATE-----' + pem_cert_frag cert = crypto.load_certificate(crypto.FILETYPE_PEM, pem_cert) cert_list.append(cert) cert = crypto.load_certificate(crypto.FILETYPE_PEM, res.content) # Optionally output the private key and certificate together PEM # encoded in a single file if pem_out_filepath: pem_pkey = crypto.dump_privatekey(crypto.FILETYPE_PEM, key_pair) pem_cert = crypto.dump_certificate(crypto.FILETYPE_PEM, cert) with open(pem_out_filepath, 'wb', 0o400) as pem_out_file: pem_out_file.write(res.content) pem_out_file.write(pem_pkey) return key_pair, (cert, ) + tuple(cert_list)
def test_issue_certificate_request(self): key = crypto.PKey() key.generate_key(crypto.TYPE_RSA, 512) req = crypto.X509Req() req.set_pubkey(key) req_enc = crypto.dump_certificate_request(crypto.FILETYPE_PEM, req) order_meta = {'request_data': req_enc} resp = self.plugin.issue_certificate_request(self.order_id, order_meta, {}, {}) crypto.load_certificate(crypto.FILETYPE_PEM, resp.certificate)
def test_issue_certificate_request(self): req = certificate_utils.get_valid_csr_object() req_enc = crypto.dump_certificate_request(crypto.FILETYPE_PEM, req) order_meta = {'request_data': req_enc} resp = self.plugin.issue_certificate_request(self.order_id, order_meta, {}, self.barbican_meta_dto) crypto.load_certificate( crypto.FILETYPE_PEM, resp.certificate.decode('base64'))
def _create_subca_and_get_cacert(self, root_ca_ref): ca_model = self.get_subca_model(root_ca_ref) resp, ca_ref = self.ca_behaviors.create_ca(ca_model, user_name=admin_a) self.assertEqual(201, resp.status_code) resp = self.ca_behaviors.get_cacert(ca_ref, user_name=admin_a) self.assertEqual(200, resp.status_code) crypto.load_certificate(crypto.FILETYPE_PEM, resp.text) resp = self.ca_behaviors.delete_ca(ca_ref=ca_ref, user_name=admin_a) self.assertEqual(204, resp.status_code)
def main(): args = parse_args() ca_pem = args.ca.read() ca_key = crypto.load_privatekey(PEM, ca_pem, args.ca_pass) ca_cert = crypto.load_certificate(PEM, ca_pem) cert = crypto.load_certificate(PEM, args.cert.read()) new_cert, new_pkey = dupe(ca_cert, ca_key, cert) print crypto.dump_certificate(PEM, new_cert) print crypto.dump_privatekey(PEM, new_pkey)
def test_voms_failure(self): proxy = crypto.load_certificate(crypto.FILETYPE_PEM, fakes.user_proxies["not-supported-vo"]) chain = crypto.X509Store() chain.add_cert(crypto.load_certificate(crypto.FILETYPE_PEM, fakes.user_cert)) with voms.VOMSContext() as vc: self.assertRaises(exception.VomsError, vc.retrieve, proxy, chain)
def export_to_pkcs12(cert_path,priv_key_path,cacert_path, passphrase): pkcs12 = crypto.PKCS12() cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(cert_path, 'r').read()) cacert = crypto.load_certificate(crypto.FILETYPE_PEM, open(cacert_path, 'r').read()) priv_key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(priv_key_path, 'r').read()) pkcs12.set_ca_certificates([cacert]) pkcs12.set_certificate(cert) pkcs12.set_privatekey(priv_key) return pkcs12.export(passphrase=passphrase)
def test_voms_context(self): proxy = crypto.load_certificate(crypto.FILETYPE_PEM, fakes.user_proxies["dteam"]) chain = crypto.X509Store() chain.add_cert(crypto.load_certificate(crypto.FILETYPE_PEM, fakes.user_cert)) with self.voms_context() as vc: d = vc.retrieve(proxy, chain) expected = fakes.user_data["dteam"] self.assertDictEqual(expected, d)
def test_create_old_serial_ca(self): ca = self._create_ca(serial_number=3) self.assertEqual(int(ca.serial_number), 3) cert = crypto.load_certificate(crypto.FILETYPE_PEM, ca.certificate) self.assertEqual(int(cert.get_serial_number()), int(ca.serial_number))
from OpenSSL.crypto import load_certificate, FILETYPE_PEM from OpenSSL._util import lib as _lib, ffi as _ffi from pyasn1.type import univ, constraint, char, namedtype, tag from pyasn1.codec.der.decoder import decode from twisted.internet import ssl from twisted.protocols import tls certificateAuthorityMap = {} for certFileName in glob.glob("/etc/ssl/certs/*.pem"): # There might be some dead symlinks in there, so let's make sure it's real. if os.path.exists(certFileName): with open(certFileName) as f: data = f.read() x509 = load_certificate(FILETYPE_PEM, data) digest = x509.digest('sha1') # Now, de-duplicate in case the same cert has multiple names. certificateAuthorityMap[digest] = x509 class GeneralName(univ.Choice): # We are only interested in dNSNames. We use a default handler to ignore # other types. componentType = namedtype.NamedTypes( namedtype.NamedType('dNSName', char.IA5String().subtype( implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2) ) ), ) class GeneralNames(univ.SequenceOf):
def process_ocsp_response(self, issuer, cert_id, ocsp_response): try: res = der_decoder.decode(ocsp_response, OCSPResponse())[0] if self.test_mode is not None: ocsp_load_failure = getenv( "SF_TEST_OCSP_FORCE_BAD_OCSP_RESPONSE") if ocsp_load_failure is not None: raise RevocationCheckError("Force fail") except Exception: raise RevocationCheckError(msg='Invalid OCSP Response', errno=ER_INVALID_OCSP_RESPONSE) if res.getComponentByName('responseStatus') != OCSPResponseStatus( 'successful'): raise RevocationCheckError(msg="Invalid Status: {0}".format( res.getComponentByName('response_status')), errno=ER_INVALID_OCSP_RESPONSE) response_bytes = res.getComponentByName('responseBytes') basic_ocsp_response = der_decoder.decode( response_bytes.getComponentByName('response'), BasicOCSPResponse())[0] attached_certs = basic_ocsp_response.getComponentByName('certs') if self._has_certs_in_ocsp_response(attached_certs): logger.debug("Certificate is attached in Basic OCSP Response") cert_der = der_encoder.encode(attached_certs[0]) cert_openssl = load_certificate(FILETYPE_ASN1, cert_der) ocsp_cert = self._convert_openssl_to_pyasn1_certificate( cert_openssl) cur_time = datetime.utcnow().replace(tzinfo=pytz.utc) tbs_certificate = ocsp_cert.getComponentByName('tbsCertificate') """ Signature verification should happen before any kind of validation """ self.verify_signature( ocsp_cert.getComponentByName('signatureAlgorithm'), ocsp_cert.getComponentByName('signatureValue'), issuer, ocsp_cert.getComponentByName('tbsCertificate')) cert_valid, debug_msg = self.check_cert_time_validity( cur_time, tbs_certificate) if not cert_valid: raise RevocationCheckError(msg=debug_msg, errno=ER_INVALID_OCSP_RESPONSE_CODE) else: logger.debug("Certificate is NOT attached in Basic OCSP Response. " "Using issuer's certificate") ocsp_cert = issuer tbs_response_data = basic_ocsp_response.getComponentByName( 'tbsResponseData') logger.debug("Verifying the OCSP response is signed by the issuer.") self.verify_signature( basic_ocsp_response.getComponentByName('signatureAlgorithm'), basic_ocsp_response.getComponentByName('signature'), ocsp_cert, tbs_response_data) single_response = tbs_response_data.getComponentByName('responses')[0] cert_status = single_response.getComponentByName('certStatus') if self.test_mode is not None: test_cert_status = getenv("SF_TEST_OCSP_CERT_STATUS") if test_cert_status == 'revoked': cert_status = 'revoked' elif test_cert_status == 'unknown': cert_status = 'unknown' elif test_cert_status == 'good': cert_status = 'good' try: if cert_status.getName() == 'good': self._process_good_status(single_response, cert_id, ocsp_response) SnowflakeOCSP.OCSP_CACHE.update_cache(self, cert_id, ocsp_response) elif cert_status.getName() == 'revoked': self._process_revoked_status(single_response, cert_id) elif cert_status.getName() == 'unknown': self._process_unknown_status(cert_id) else: debug_msg = "Unknown revocation status was returned. " \ "OCSP response may be malformed: {0}. ".format(cert_status) raise RevocationCheckError(msg=debug_msg, errno=ER_INVALID_OCSP_RESPONSE_CODE) except RevocationCheckError as op_er: if not self.debug_ocsp_failure_url: debug_msg = op_er.msg else: debug_msg = "{0} Consider running curl -o ocsp.der {1}".\ format(op_er.msg, self.debug_ocsp_failure_url) raise RevocationCheckError(msg=debug_msg, errno=op_er.errno)
def sign_request(self, csr, options=None): """ Signs a certificate request with the key of the CA. options can be WorkingDir: The directory where the configuration like openssl.cnf can be found. CSRDir: The directory, where to save the certificate signing requests. This is relative to the WorkingDir. CertificateDir: The directory where to save the certificates. This is relative to the WorkingDir. :param csr: Certificate signing request :type csr: PEM string or SPKAC :param options: Additional options like the validity time or the template or spkac=1 :type options: dict :return: Returns the certificate :rtype: basestring """ # Sign the certificate for one year options = options or {} days = options.get("days", 365) spkac = options.get("spkac") config = options.get(ATTR.OPENSSL_CNF, self.config.get( ATTR.OPENSSL_CNF, "/etc/ssl/openssl.cnf")) extension = options.get("extension", "server") template_name = options.get("template") workingdir = options.get(ATTR.WORKING_DIR, self.config.get(ATTR.WORKING_DIR)) csrdir = options.get(ATTR.CSR_DIR, self.config.get(ATTR.CSR_DIR, "")) certificatedir = options.get(ATTR.CERT_DIR, self.config.get(ATTR.CERT_DIR, "")) if workingdir: if not csrdir.startswith("/"): # No absolut path csrdir = workingdir + "/" + csrdir if not certificatedir.startswith("/"): certificatedir = workingdir + "/" + certificatedir if template_name: t_data = self.templates.get(template_name) extension = t_data.get("extensions", extension) days = t_data.get("days", days) # Determine filename from the CN of the request if spkac: common_name = re.search("CN=(.*)", csr).group(0).split('=')[1] csr_filename = common_name + ".txt" certificate_filename = common_name + ".der" else: csr_obj = crypto.load_certificate_request(crypto.FILETYPE_PEM, csr) csr_filename = self._filename_from_x509(csr_obj.get_subject(), file_extension="req") certificate_filename = self._filename_from_x509( csr_obj.get_subject(), file_extension="pem") #csr_extensions = csr_obj.get_extensions() csr_filename = csr_filename.replace(" ", "_") certificate_filename = certificate_filename.replace(" ", "_") # dump the file with open(csrdir + "/" + csr_filename, "w") as f: f.write(csr) # TODO: use the template name to set the days and the extention! if spkac: cmd = CA_SIGN_SPKAC.format(cakey=self.cakey, cacert=self.cacert, days=days, config=config, extension=extension, spkacfile=csrdir + "/" + csr_filename, certificate=certificatedir + "/" + certificate_filename) else: cmd = CA_SIGN.format(cakey=self.cakey, cacert=self.cacert, days=days, config=config, extension=extension, csrfile=csrdir + "/" + csr_filename, certificate=certificatedir + "/" + certificate_filename) # run the command args = shlex.split(cmd) p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=workingdir) result, error = p.communicate() if p.returncode != 0: # pragma: no cover # Some error occurred raise CAError(error) with open(certificatedir + "/" + certificate_filename, "r") as f: certificate = f.read() # We return the cert_obj. if spkac: filetype = crypto.FILETYPE_ASN1 else: filetype = crypto.FILETYPE_PEM cert_obj = crypto.load_certificate(filetype, certificate) return cert_obj
def __init__(self, trustedCerts=None): self.store = crypto.X509Store() if trustedCerts is not None: for cert in trustedCerts: cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert) self.add_cert(cert)
def verify(self, data, require_x509=True, x509_cert=None, cert_subject_name=None, ca_pem_file=None, ca_path=None, hmac_key=None, validate_schema=True, parser=None, uri_resolver=None, id_attribute=None, expect_references=1): """ Verify the XML signature supplied in the data and return the XML node signed by the signature, or raise an exception if the signature is not valid. By default, this requires the signature to be generated using a valid X.509 certificate. To enable other means of signature validation, set the **require_x509** argument to `False`. .. admonition:: See what is signed It is important to understand and follow the best practice rule of "See what is signed" when verifying XML signatures. The gist of this rule is: if your application neglects to verify that the information it trusts is what was actually signed, the attacker can supply a valid signature but point you to malicious data that wasn't signed by that signature. In SignXML, you can ensure that the information signed is what you expect to be signed by only trusting the data returned by the ``verify()`` method. The return value is the XML node or string that was signed. Also, depending on the signature settings used, comments in the XML data may not be subject to signing, so may need to be untrusted. **Recommended reading:** http://www.w3.org/TR/xmldsig-bestpractices/#practices-applications .. admonition:: Establish trust If you do not supply any keyword arguments to ``verify()``, the default behavior is to trust **any** valid XML signature generated using a valid X.509 certificate trusted by your system's CA store. This means anyone can get an SSL certificate and generate a signature that you will trust. To establish trust in the signer, use the ``x509_cert`` argument to specify a certificate that was pre-shared out-of-band (e.g. via SAML metadata, as shown in :ref:`Verifying SAML assertions <verifying-saml-assertions>`), or ``cert_subject_name`` to specify a subject name that must be in the signing X.509 certificate given by the signature (verified as if it were a domain name), or ``ca_pem_file``/``ca_path`` to give a custom CA. :param data: Signature data to verify :type data: String, file-like object, or XML ElementTree Element API compatible object :param require_x509: If ``True``, a valid X.509 certificate-based signature with an established chain of trust is required to pass validation. If ``False``, other types of valid signatures (e.g. HMAC or RSA public key) are accepted. :type require_x509: boolean :param x509_cert: A trusted external X.509 certificate, given as a PEM-formatted string or OpenSSL.crypto.X509 object, to use for verification. Overrides any X.509 certificate information supplied by the signature. If left set to ``None``, requires that the signature supply a valid X.509 certificate chain that validates against the known certificate authorities. Implies **require_x509=True**. :type x509_cert: string or OpenSSL.crypto.X509 :param ca_pem_file: Filename of a PEM file containing certificate authority information to use when verifying certificate-based signatures. :type ca_pem_file: string or bytes :param ca_path: Path to a directory containing PEM-formatted certificate authority files to use when verifying certificate-based signatures. If neither **ca_pem_file** nor **ca_path** is given, the Mozilla CA bundle provided by :py:mod:`certifi` will be loaded. :type ca_path: string :param cert_subject_name: Subject Common Name to check the signing X.509 certificate against. Implies **require_x509=True**. :type cert_subject_name: string :param hmac_key: If using HMAC, a string containing the shared secret. :type hmac_key: string :param validate_schema: Whether to validate **data** against the XML Signature schema. :type validate_schema: boolean :param parser: Custom XML parser instance to use when parsing **data**. :type parser: :py:class:`lxml.etree.XMLParser` compatible parser :param uri_resolver: Function to use to resolve reference URIs that don't start with "#". :type uri_resolver: callable :param id_attribute: Name of the attribute whose value ``URI`` refers to. By default, SignXML will search for "Id", then "ID". :type id_attribute: string :param expect_references: Number of references to expect in the signature. If this is not 1, an array of VerifyResults is returned. If set to a non-integer, any number of references is accepted (otherwise a mismatch raises an error). :type expect_references: int or boolean :raises: :py:class:`cryptography.exceptions.InvalidSignature` :returns: VerifyResult object with the signed data, signed xml and signature xml :rtype: VerifyResult """ self.hmac_key = hmac_key self.require_x509 = require_x509 self.x509_cert = x509_cert self._parser = parser if x509_cert: self.require_x509 = True if id_attribute is not None: self.id_attributes = (id_attribute, ) root = self.get_root(data) if root.tag == ds_tag("Signature"): signature_ref = root else: signature_ref = self._find(root, "Signature", anywhere=True) # HACK: deep copy won't keep root's namespaces signature = fromstring(etree.tostring(signature_ref), parser=parser) if validate_schema: self.schema().assertValid(signature) signed_info = self._find(signature, "SignedInfo") c14n_method = self._find(signed_info, "CanonicalizationMethod") c14n_algorithm = c14n_method.get("Algorithm") signature_method = self._find(signed_info, "SignatureMethod") signature_value = self._find(signature, "SignatureValue") signature_alg = signature_method.get("Algorithm") raw_signature = b64decode(signature_value.text) x509_data = signature.find("ds:KeyInfo/ds:X509Data", namespaces=namespaces) signed_info_c14n = self._c14n(signed_info, algorithm=c14n_algorithm) if x509_data is not None or self.require_x509: from OpenSSL.crypto import load_certificate, X509, FILETYPE_PEM, verify, Error as OpenSSLCryptoError if self.x509_cert is None: if x509_data is None: raise InvalidInput("Expected a X.509 certificate based signature") certs = [cert.text for cert in self._findall(x509_data, "X509Certificate")] if not certs: msg = "Expected to find an X509Certificate element in the signature" msg += " (X509SubjectName, X509SKI are not supported)" raise InvalidInput(msg) cert_chain = [load_certificate(FILETYPE_PEM, add_pem_header(cert)) for cert in certs] signing_cert = verify_x509_cert_chain(cert_chain, ca_pem_file=ca_pem_file, ca_path=ca_path) elif isinstance(self.x509_cert, X509): signing_cert = self.x509_cert else: signing_cert = load_certificate(FILETYPE_PEM, add_pem_header(self.x509_cert)) if cert_subject_name and signing_cert.get_subject().commonName != cert_subject_name: raise InvalidSignature("Certificate subject common name mismatch") signature_digest_method = self._get_signature_digest_method(signature_alg).name try: verify(signing_cert, raw_signature, signed_info_c14n, signature_digest_method) except OpenSSLCryptoError as e: try: lib, func, reason = e.args[0][0] except Exception: reason = e raise InvalidSignature("Signature verification failed: {}".format(reason)) # TODO: CN verification goes here # TODO: require one of the following to be set: either x509_cert or (ca_pem_file or ca_path) or common_name # Use ssl.match_hostname or code from it to perform match elif "hmac-sha" in signature_alg: if self.hmac_key is None: raise InvalidInput('Parameter "hmac_key" is required when verifying a HMAC signature') from cryptography.hazmat.primitives.hmac import HMAC signer = HMAC(key=ensure_bytes(self.hmac_key), algorithm=self._get_hmac_digest_method(signature_alg), backend=default_backend()) signer.update(signed_info_c14n) if raw_signature != signer.finalize(): raise InvalidSignature("Signature mismatch (HMAC)") else: key_value = signature.find("ds:KeyInfo/ds:KeyValue", namespaces=namespaces) if key_value is None: raise InvalidInput("Expected to find either KeyValue or X509Data XML element in KeyInfo") self._verify_signature_with_pubkey(signed_info_c14n, raw_signature, key_value, signature_alg) verify_results = [] for reference in self._findall(signed_info, "Reference"): transforms = self._find(reference, "Transforms", require=False) digest_algorithm = self._find(reference, "DigestMethod").get("Algorithm") digest_value = self._find(reference, "DigestValue") payload = self._resolve_reference(root, reference, uri_resolver=uri_resolver) payload_c14n = self._apply_transforms(payload, transforms, signature_ref, c14n_algorithm) if digest_value.text != self._get_digest(payload_c14n, self._get_digest_method(digest_algorithm)): raise InvalidDigest("Digest mismatch for reference {}".format(len(verify_results))) # We return the signed XML (and only that) to ensure no access to unsigned data happens try: payload_c14n_xml = fromstring(payload_c14n) except etree.XMLSyntaxError: payload_c14n_xml = None verify_results.append(VerifyResult(payload_c14n, payload_c14n_xml, signature)) if type(expect_references) is int and len(verify_results) != expect_references: msg = "Expected to find {} references, but found {}" raise InvalidSignature(msg.format(expect_references, len(verify_results))) return verify_results if expect_references > 1 else verify_results[0]
def _read_pem(self, path: Path) -> Tuple[crypto.X509, crypto.PKey]: with path.open(mode="rb") as f: file_contents = f.read() cert = crypto.load_certificate(FILETYPE_PEM, file_contents) key = crypto.load_privatekey(FILETYPE_PEM, file_contents) return cert, key
ws.protocol = ProxyServer root = Root('./static') root.putChild(b"proxy", autobahn.twisted.resource.WebSocketResource(ws)) root.putChild(b"stats", SimpleStats(details, arguments["password"])) requestFactory = twisted.web.server.Site(root) if arguments["ssl"]: import OpenSSL from OpenSSL import crypto try: splitted = arguments["ssl"].split(":") key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(splitted[0], 'rt').read()) cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(splitted[1], 'rt').read()) chain = None if len(splitted) == 3: chain = [ crypto.load_certificate(crypto.FILETYPE_PEM, open(splitted[2], 'rt').read()) ] contextFactory = ssl.CertificateOptions(privateKey=key, certificate=cert, extraCertChain=chain) twisted.internet.reactor.listenSSL(arguments["websocket_port"], requestFactory, contextFactory) except (OpenSSL.SSL.Error, IOError): print("Invalid privatekey:certificate[:chain]") sys.exit(1) else:
def gen_signed_cert(domain, ca_crt="ca.crt", ca_key="ca.key", key_path="cert.key"): """ This function takes a domain name as a parameter and then creates a certificate and key with the domain name(replacing dots by underscores), finally signing the certificate using specified CA and returns the path of key and cert files. If you are yet to generate a CA then check the top comments """ certs_folder = "certs/" cert_path = os.path.join(certs_folder, domain.replace('.', '_') + ".crt") # The first conditions checks if file exists, and does nothing if true # If file doenst exist lock is obtained for writing (Other processes in race must wait) # After obtaining lock another check to handle race conditions gracefully if os.path.exists(key_path) and os.path.exists(cert_path): pass else: with FileLock(cert_path, timeout=2): # Check happens if the certificate and key pair already exists for a domain if os.path.exists(key_path) and os.path.exists(cert_path): pass else: # Serial Generation - Serial number must be unique for each certificate, # so serial is generated based on domain name md5_hash = hashlib.md5() md5_hash.update(str.encode(domain)) serial = int(md5_hash.hexdigest(), 36) # The CA stuff is loaded from the same folder as this script ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(ca_crt).read()) # The last parameter is the password for your CA key file ca_key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(ca_key).read()) key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(key_path).read()) #key.generate_key(crypto.TYPE_RSA, 2048) cert = crypto.X509() cert.set_version(3 - 1) # version 3, starts at 0 cert.get_subject().C = "IN" cert.get_subject().ST = "AP" cert.get_subject().L = "127.0.0.1" cert.get_subject().O = "TProxy" cert.get_subject().OU = domain cert.gmtime_adj_notBefore(-3 * 24 * 60 * 60) cert.gmtime_adj_notAfter(365 * 24 * 60 * 60) cert.set_serial_number(serial) cert.set_issuer(ca_cert.get_subject()) cert.add_extensions([ crypto.X509Extension(b"subjectAltName", True, b"DNS: " + domain.encode()) ]) cert.set_pubkey(key) cert.sign(ca_key, "sha256") # The key and cert files are dumped and their paths are returned domain_cert = open(cert_path, "wb") domain_cert.write( crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) print(("[*] Generated signed certificate for %s" % (domain))) return key_path, cert_path
def beacon(config): ''' Monitor the certificate files on the minion. Specify a notification threshold in days and only emit a beacon if any certificates are expiring within that timeframe or if `notify_days` equals `-1` (always report information). The default notification threshold is 45 days and can be overridden at the beacon level and at an individual certificate level. .. code-block:: yaml beacons: cert_info: - files: - /etc/pki/tls/certs/mycert.pem - /etc/pki/tls/certs/yourcert.pem: notify_days: 15 - /etc/pki/tls/certs/ourcert.pem - notify_days: 45 - interval: 86400 ''' ret = [] certificates = [] CryptoError = crypto.Error # pylint: disable=invalid-name _config = {} list(_map(_config.update, config)) global_notify_days = _config.get('notify_days', DEFAULT_NOTIFY_DAYS) for cert_path in _config.get('files', []): notify_days = global_notify_days if isinstance(cert_path, dict): try: notify_days = cert_path[cert_path.keys()[0]].get( 'notify_days', global_notify_days) cert_path = cert_path.keys()[0] except IndexError as exc: log.error('Unable to load certificate %s (%s)', cert_path, exc) continue try: with salt.utils.files.fopen(cert_path) as fp_: cert = crypto.load_certificate(crypto.FILETYPE_PEM, fp_.read()) except (IOError, CryptoError) as exc: log.error('Unable to load certificate %s (%s)', cert_path, exc) continue cert_date = datetime.strptime( cert.get_notAfter().decode(encoding='UTF-8'), "%Y%m%d%H%M%SZ") date_diff = (cert_date - datetime.today()).days log.debug('Certificate %s expires in %s days.', cert_path, date_diff) if notify_days < 0 or date_diff <= notify_days: log.debug( 'Certificate %s triggered beacon due to %s day notification threshold.', cert_path, notify_days) extensions = [] for ext in _range(0, cert.get_extension_count()): extensions.append({ 'ext_name': cert.get_extension(ext).get_short_name().decode( encoding='UTF-8'), 'ext_data': str(cert.get_extension(ext)) }) certificates.append({ 'cert_path': cert_path, 'issuer': ','.join([ '{0}="{1}"'.format(t[0].decode(encoding='UTF-8'), t[1].decode(encoding='UTF-8')) for t in cert.get_issuer().get_components() ]), 'issuer_dict': { k.decode('UTF-8'): v.decode('UTF-8') for k, v in cert.get_issuer().get_components() }, 'notAfter_raw': cert.get_notAfter().decode(encoding='UTF-8'), 'notAfter': cert_date.strftime("%Y-%m-%d %H:%M:%SZ"), 'notBefore_raw': cert.get_notBefore().decode(encoding='UTF-8'), 'notBefore': datetime.strptime( cert.get_notBefore().decode(encoding='UTF-8'), "%Y%m%d%H%M%SZ").strftime("%Y-%m-%d %H:%M:%SZ"), 'serial_number': cert.get_serial_number(), 'signature_algorithm': cert.get_signature_algorithm().decode(encoding='UTF-8'), 'subject': ','.join([ '{0}="{1}"'.format(t[0].decode(encoding='UTF-8'), t[1].decode(encoding='UTF-8')) for t in cert.get_subject().get_components() ]), 'subject_dict': { k.decode('UTF-8'): v.decode('UTF-8') for k, v in cert.get_subject().get_components() }, 'version': cert.get_version(), 'extensions': extensions, 'has_expired': cert.has_expired() }) if certificates: ret.append({'certificates': certificates}) return ret
def loadCertificate(self, certificate): try: cert = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) except crypto.Error as e: raise Exception(e.message[0][2]) return cert
def _convert_pyasn1_to_openssl_certificate(self, cert): cert_der = der_encoder.encode(cert) cert_openssl = load_certificate(FILETYPE_ASN1, cert_der) return cert_openssl
def signReqCA(CA_path, CSR_path, password, csr_type='usr'): ''' Signs the CSR. Returns bytes of (Chain of trust, Issued Certificate) if csr_type == 'ca' Returns bytes of (Issued Certificate) if csr_type == 'usr' or 'svr' CA_path : path of the directory of CA which will sign the request. * DIRECTORY IN CA PATH MUST BE THE ONE GENERATED USING OpenCA * ''' if not is_serial_consistent(CA_path): raise SerialException( 'Serial sequence mismatched, Serial is corrupted') engine = getDB(CA_path) Session = sessionmaker(bind=engine) session = Session() CA_name = path.split(CA_path)[1] # load certifiate of the CA CAcert_bytes = open( path.join(path.abspath(CA_path), 'certs', (CA_name + '.cert.pem')), 'rb').read() CAcert = load_certificate(FILETYPE_PEM, CAcert_bytes) password = bytes(password, 'utf-8') if isinstance(password, str) else password # load privatekey of the CA. CAkey_bytes = open( path.join(path.abspath(CA_path), 'private', (CA_name + '.private.pem')), 'rb').read() CAkey = load_privatekey(FILETYPE_PEM, CAkey_bytes, passphrase=password) # determine if the request is for a CA if csr_type == 'ca': SUBCA_name = path.split(CSR_path)[1] SUBCA_dir = CSR_path[:] CSR_path = path.join(path.abspath(CSR_path), 'csr', (SUBCA_name + '.csr.pem')) # load the CSR. CSR_bytes = open(CSR_path, 'rb').read() CSR = load_certificate_request(FILETYPE_PEM, CSR_bytes) if CAcert.get_subject().CN == CSR.get_subject().CN: raise CNException('CN can not be same as parent') cert = X509() cert.set_subject(CSR.get_subject()) # Get the last serial number and dump it in serial.old # Increment the serial number and save it in serial # give the incremented serial number here serial = open(path.join(CA_path, 'serial'), 'rb').read() cert.set_serial_number(int(serial)) open(path.join(CA_path, 'serial.old'), 'wb').write(serial) open(path.join(CA_path, 'serial'), 'wb').write(bytes(str(int(serial) + 1), 'utf-8')) cert.gmtime_adj_notBefore(0) if csr_type == 'ca': cert.gmtime_adj_notAfter(5 * 365 * 24 * 60 * 60) cert.add_extensions([ X509Extension(b"basicConstraints", True,b"CA:TRUE, pathlen:0"),\ X509Extension(b"keyUsage", True,b"keyCertSign, cRLSign"),\ X509Extension(b"authorityKeyIdentifier", False, b"keyid:always",issuer= CAcert),\ X509Extension(b"subjectKeyIdentifier", False, b"hash",subject=cert)]) elif csr_type == 'usr': cert.gmtime_adj_notAfter(1 * 365 * 24 * 60 * 60) cert.add_extensions([ X509Extension(b"basicConstraints",True,b"CA:FALSE"),\ X509Extension(b"nsCertType",False,b"client, email"),\ X509Extension(b"nsComment",False, b"Certified Using OpenSSL based OpenCA"),\ X509Extension(b"subjectKeyIdentifier",False,b"hash",subject=cert),\ X509Extension(b"authorityKeyIdentifier",False, b"keyid", issuer= CAcert),\ X509Extension(b"keyUsage",True,b"nonRepudiation, digitalSignature, keyEncipherment"),\ X509Extension(b"extendedKeyUsage", False, b"clientAuth, emailProtection")]) elif csr_type == 'svr': cert.gmtime_adj_notAfter(2 * 365 * 24 * 60 * 30) cert.add_extensions([ X509Extension(b"basicConstraints",True,b"CA:FALSE"),\ X509Extension(b"nsCertType",False,b"server"),\ X509Extension(b"nsComment",False, b"Certified Using OpenSSL based OpenCA"),\ X509Extension(b"subjectKeyIdentifier",False,b"hash",subject=cert),\ X509Extension(b"authorityKeyIdentifier",False, b"keyid", issuer=CAcert),\ X509Extension(b"keyUsage",True,b"nonRepudiation, digitalSignature, keyEncipherment"),\ X509Extension(b"extendedKeyUsage", False, b"serverAuth")]) cert.set_issuer(CAcert.get_subject()) cert.set_pubkey(CSR.get_pubkey()) cert.sign(CAkey, "sha256") # Save the signed certificate's information in the index.db clist = [] for i in cert.get_subject().get_components(): clist.append(i[0] + b'=' + i[1]) cstring = b'/'.join(clist) cstring = b'/' + cstring + b'/' IndexObj = Index(expiration_date=cert.get_notAfter(), serial_number_in_hex=str(serial), cert_filename=serial.decode('utf-8') + '.cert.pem', cert_subject=cstring) session.add(IndexObj) session.commit() # save the certificates in newcerts directory of the CA cert_bytes = dump_certificate(FILETYPE_PEM, cert) open( path.join(path.abspath(CA_path), 'newcerts', (serial.decode('utf-8') + '.cert.pem')), 'wb').write(cert_bytes) if csr_type == 'ca': # If csr_type is 'ca' then save the chain of trust and it's certificate if path.exists( path.join(path.abspath(CA_path), 'certs', (CA_name + '.chain.pem'))): # If CA has a chain then forward that chain further CAcert_bytes = open( path.join(path.abspath(CA_path), 'certs', (CA_name + '.chain.pem')), 'rb').read() open( path.join(path.abspath(SUBCA_dir), 'certs', (SUBCA_name + '.cert.pem')), 'wb').write(cert_bytes) open( path.join(path.abspath(SUBCA_dir), 'certs', (SUBCA_name + '.chain.pem')), 'wb').write(cert_bytes + CAcert_bytes) return (cert_bytes + CAcert_bytes), cert_bytes else: print( 'Certificate Produced @ ', path.join(path.abspath(path.split(CSR_path)[0]), 'USER.cert.pem')) if csr_type == 'usr': open( path.join(path.abspath(path.split(CSR_path)[0]), 'USER.cert.pem'), 'wb').write(cert_bytes) elif csr_type == 'svr': open( path.join(path.abspath(path.split(CSR_path)[0]), 'SERVER.cert.pem'), 'wb').write(cert_bytes) return cert_bytes
def cacheContext(self): if self._context is None: ctx = self._contextFactory(self.sslmethod) # SSL hardening # ctx.set_options(SSL_DEFAULT_OPTIONS) if self._ciphers: ctx.set_cipher_list(self._ciphers) log.msg("Using explicit cipher list.") else: ctx.set_cipher_list(SSL_DEFAULT_CIPHERS) log.msg("Using default cipher list.") # Activate DH(E) # # http://linux.die.net/man/3/ssl_ctx_set_tmp_dh # http://linux.die.net/man/1/dhparam # if self._dhParamFilename: try: ctx.load_tmp_dh(self._dhParamFilename) except Exception as e: log.msg( "Error: OpenSSL DH modes not active - failed to load DH parameter file [{}]" .format(e)) else: log.msg( "Ok, OpenSSL Diffie-Hellman ciphers parameter file loaded." ) else: log.msg( "Warning: OpenSSL DH modes not active - missing DH param file" ) # Activate ECDH(E) # # This needs pyOpenSSL 0.15 # try: # without setting a curve, ECDH won't be available even if listed # in SSL_DEFAULT_CIPHERS! # curve must be one of OpenSSL.crypto.get_elliptic_curves() # curve = crypto.get_elliptic_curve(ECDH_DEFAULT_CURVE_NAME) ctx.set_tmp_ecdh(curve) except Exception as e: log.msg( "Warning: OpenSSL failed to set ECDH default curve [{}]". format(e)) else: log.msg("Ok, OpenSSL is using ECDH elliptic curve {}".format( ECDH_DEFAULT_CURVE_NAME)) # load certificate (chain) into context # if not self._chainedCertificate: cert = crypto.load_certificate(crypto.FILETYPE_PEM, self._certificateString) ctx.use_certificate(cert) else: # http://pyopenssl.sourceforge.net/pyOpenSSL.html/openssl-context.html # there is no "use_certificate_chain" function, so we need to create # a temporary file writing the certificate chain file f = tempfile.NamedTemporaryFile(delete=False) f.write(self._certificateString) f.close() ctx.use_certificate_chain_file(f.name) # load private key into context # key = crypto.load_privatekey(crypto.FILETYPE_PEM, self._privateKeyString) ctx.use_privatekey(key) ctx.check_privatekey() # set cached context # self._context = ctx
def get_certificates(self, options, **kwargs): certs = [] issuer_dn = self.get_option("issuerdn", options) source_const = self.get_option("source_const", options) if source_const is not None: source_const = source_const.upper() # print("SOURCE**** " +str(source_const)) session = requests.Session() session.mount('https://', HttpsAdapter()) session.cert = current_app.config.get( "EJBCA_PEM_PATH_{0}".format(source_const), current_app.config.get("EJBCA_PEM_PATH")) session.verify = current_app.config.get("EJBCA_TRUSTSTORE") session.hooks = dict(response=log_status_code) source_expire_days = current_app.config.get("EJBCA_SOURCE_EXPIRE_DAYS", 7300) source_max_results = current_app.config.get("EJBCA_SOURCE_MAX_RESULTS", 100000) request_data = { 'arg0': source_expire_days, 'arg1': issuer_dn, 'arg2': source_max_results, } transport = Transport(session=session) url = current_app.config.get( "EJBCA_URL") + "/ejbca/ejbcaws/ejbcaws?wsdl" client = Client(url, transport=transport) response = client.service.getCertificatesByExpirationTimeAndIssuer( **request_data) num_certs = len(response) for x in range(num_certs): encoded_cert = response[x].certificateData decoded_cert = encoded_cert.decode('utf-8') pem = "-----BEGIN CERTIFICATE-----\n" pem += decoded_cert pem += "\n-----END CERTIFICATE-----" x509 = load_certificate(FILETYPE_PEM, pem) # get SubjectDN string from CSR serial = x509.get_serial_number() # External ID required for revocation # Generate a random ID rand_external_id = random.randrange(10**11, 10**12) external_id = str(rand_external_id) chain = '{}\n{}'.format( current_app.config.get('EJBCA_INTERMEDIATE', '').strip(), current_app.config.get('EJBCA_ROOT', '').strip()) cert = { "body": "\n".join(str(pem).splitlines()), "serial": serial, "external_id": external_id, "chain": chain, } certs.append(cert) return certs
def verify(self, datas, datau): signed_data = cms.ContentInfo.load(datas)['content'] # signed_data.debug() signature = signed_data['signer_infos'][0].native['signature'] algo = signed_data['digest_algorithms'][0]['algorithm'].native attrs = signed_data['signer_infos'][0]['signed_attrs'] mdData = getattr(hashlib, algo)(datau).digest() if attrs is not None and not isinstance(attrs, core.Void): mdSigned = None for attr in attrs: if attr['type'].native == 'message_digest': mdSigned = attr['values'].native[0] signedData = attrs.dump() signedData = b'\x31' + signedData[1:] else: mdSigned = mdData signedData = datau hashok = mdData == mdSigned serial = signed_data['signer_infos'][0]['sid'].native['serial_number'] public_key = None for cert in signed_data['certificates']: if serial == cert.native['tbs_certificate']['serial_number']: cert = cert.dump() cert = pem.armor(u'CERTIFICATE', cert) public_key = crypto.load_certificate( crypto.FILETYPE_PEM, cert).get_pubkey().to_cryptography_key() break sigalgo = signed_data['signer_infos'][0]['signature_algorithm'] # sigalgo.debug() if sigalgo['algorithm'].native == 'rsassa_pss': parameters = sigalgo['parameters'] #parameters.debug() #print(parameters.native) salgo = parameters['hash_algorithm'].native['algorithm'].upper() mgf = getattr( padding, parameters['mask_gen_algorithm'].native['algorithm'].upper())( getattr(hashes, salgo)()) salt_length = parameters['salt_length'].native try: public_key.verify(signature, signedData, padding.PSS(mgf, salt_length), getattr(hashes, salgo)()) signatureok = True except: signatureok = False elif sigalgo['algorithm'].native == 'rsassa_pkcs1v15': try: public_key.verify(signature, signedData, padding.PKCS1v15(), getattr(hashes, algo.upper())()) signatureok = True except: signatureok = False else: raise ValueError('Unknown signature algorithm') # TODO verify certificates certok = True for cert in signed_data['certificates']: scert = pem.armor(u'CERTIFICATE', cert.dump()).decode() if not self.verify_cert(scert): print('*' * 10, 'failed certificate verification') print('cert.issuer:', cert.native['tbs_certificate']['issuer']) print('cert.subject:', cert.native['tbs_certificate']['subject']) certok = False return (hashok, signatureok, certok)
def load_certfile(self): with file(self.cert_file, 'rb') as keyfile: self.cert = crypto.load_certificate(crypto.FILETYPE_PEM, keyfile.read())
sys.exit(-1) input_cert_path = sys.argv[1] ca_cert_path = sys.argv[2] out_cert_path = sys.argv[3] n_outcert = int(sys.argv[4]) if (len(sys.argv)>5): configfile = sys.argv[5] else: configfile = "" fconf = franken_conf_parse.parse_config(configfile) certs = franken_util.load_dir(input_cert_path) with open(ca_cert_path, 'rt') as ca_cert_file: ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, ca_cert_file.read()) with open(ca_cert_path, 'rt') as ca_key_file: ca_private_key = crypto.load_privatekey(crypto.FILETYPE_PEM, \ ca_key_file.read()) sys.stdout.write("Generating frankencerts") max_certs_in_mem = 200 nc = n_outcert/max_certs_in_mem remaining_cnt = n_outcert for i in range(nc+1): if (remaining_cnt > max_certs_in_mem): franken_certs = franken_core.generate(certs, ca_cert, ca_private_key, \ fconf, count=max_certs_in_mem) remaining_cnt = remaining_cnt - max_certs_in_mem else: franken_certs = franken_core.generate(certs, ca_cert, ca_private_key, \
def _certificate(self) -> crypto.X509: return crypto.load_certificate(crypto.FILETYPE_ASN1, self.asn1_content)
def parse(data, format): cert = crypto.load_certificate(TypeMap[format], data) return SSLCertificate(cert)
def test_x509_property(self): cert = self._create_cert() x509 = crypto.load_certificate(crypto.FILETYPE_PEM, cert.certificate) self.assertEqual(cert.x509.get_subject(), x509.get_subject()) self.assertEqual(cert.x509.get_issuer(), x509.get_issuer())
def cert_extend(self, cert): """Extend certificate with some useful attributes.""" if cert['cert_type'] in (CA_TYPE_EXISTING, CA_TYPE_INTERNAL, CA_TYPE_INTERMEDIATE): root_path = CERT_CA_ROOT_PATH else: root_path = CERT_ROOT_PATH cert['cert_root_path'] = root_path cert['cert_certificate_path'] = os.path.join( root_path, '{0}.crt'.format(cert['cert_name'])) cert['cert_privatekey_path'] = os.path.join( root_path, '{0}.key'.format(cert['cert_name'])) cert['cert_csr_path'] = os.path.join( root_path, '{0}.csr'.format(cert['cert_name'])) def cert_issuer(cert): issuer = None if cert['cert_type'] in (CA_TYPE_EXISTING, CERT_TYPE_EXISTING): issuer = "external" elif cert['cert_type'] == CA_TYPE_INTERNAL: issuer = "self-signed" elif cert['cert_type'] in (CERT_TYPE_INTERNAL, CA_TYPE_INTERMEDIATE): issuer = cert['cert_signedby'] elif cert['cert_type'] == CERT_TYPE_CSR: issuer = "external - signature pending" return issuer cert['cert_issuer'] = cert_issuer(cert) cert['cert_chain_list'] = [] if cert['cert_chain']: certs = RE_CERTIFICATE.findall(cert['cert_certificate']) else: certs = [cert['cert_certificate']] signing_CA = cert['cert_issuer'] # Recursively get all internal/intermediate certificates while signing_CA not in [ "external", "self-signed", "external - signature pending" ]: certs.append(signing_CA['cert_certificate']) signing_CA['cert_issuer'] = cert_issuer(signing_CA) signing_CA = signing_CA['cert_issuer'] cert_obj = None try: for c in certs: # XXX Why load certificate if we are going to dump it right after? # Maybe just to verify its integrity? # Logic copied from freenasUI cert_obj = crypto.load_certificate(crypto.FILETYPE_PEM, c) cert['cert_chain_list'].append( crypto.dump_certificate(crypto.FILETYPE_PEM, cert_obj)) except: logger.debug('Failed to load certificate {0}'.format( cert['cert_name']), exc_info=True) try: if cert['cert_privatekey']: key_obj = crypto.load_privatekey(crypto.FILETYPE_PEM, cert['cert_privatekey']) cert['cert_privatekey'] = crypto.dump_privatekey( crypto.FILETYPE_PEM, key_obj) except: logger.debug('Failed to load privatekey {0}'.format( cert['cert_name']), exc_info=True) try: if cert['cert_CSR']: csr_obj = crypto.load_certificate_request( crypto.FILETYPE_PEM, cert['cert_CSR']) cert['cert_CSR'] = crypto.dump_certificate_request( crypto.FILETYPE_PEM, csr_obj) except: logger.debug('Failed to load csr {0}'.format(cert['cert_name']), exc_info=True) cert['cert_internal'] = 'NO' if cert['cert_type'] in ( CA_TYPE_EXISTING, CERT_TYPE_EXISTING) else 'YES' obj = None # date not applicable for CSR cert['cert_from'] = None cert['cert_until'] = None if cert['cert_type'] == CERT_TYPE_CSR: obj = csr_obj elif cert_obj: obj = cert_obj notBefore = obj.get_notBefore() t1 = dateutil.parser.parse(notBefore) t2 = t1.astimezone(dateutil.tz.tzutc()) cert['cert_from'] = t2.ctime() notAfter = obj.get_notAfter() t1 = dateutil.parser.parse(notAfter) t2 = t1.astimezone(dateutil.tz.tzutc()) cert['cert_until'] = t2.ctime() if obj: cert['cert_DN'] = '/' + '/'.join([ '%s=%s' % (c[0], c[1]) for c in obj.get_subject().get_components() ]) return cert
def load_cert(cert_str, filetype=FILETYPE_PEM): """Loads obj cert object from string.""" return crypto.load_certificate(filetype, cert_str)
def process_worker(result_info): logging.debug("Worker {} starting...".format(os.getpid())) if not result_info: return try: csv_storage = result_info['log_dir'] csv_file = "{}/{}-{}.csv".format(csv_storage, result_info['start'], result_info['end']) lines = [] print("[{}] Parsing...".format(os.getpid())) for entry in result_info['entries']: mtl = certlib.MerkleTreeHeader.parse( base64.b64decode(entry['leaf_input'])) cert_data = {} if mtl.LogEntryType == "X509LogEntryType": cert_data['type'] = "X509LogEntry" chain = [ crypto.load_certificate( crypto.FILETYPE_ASN1, certlib.Certificate.parse(mtl.Entry).CertData) ] extra_data = certlib.CertificateChain.parse( base64.b64decode(entry['extra_data'])) for cert in extra_data.Chain: chain.append( crypto.load_certificate(crypto.FILETYPE_ASN1, cert.CertData)) else: cert_data['type'] = "PreCertEntry" extra_data = certlib.PreCertEntry.parse( base64.b64decode(entry['extra_data'])) chain = [ crypto.load_certificate(crypto.FILETYPE_ASN1, extra_data.LeafCert.CertData) ] for cert in extra_data.Chain: chain.append( crypto.load_certificate(crypto.FILETYPE_ASN1, cert.CertData)) cert_data.update({ "leaf_cert": certlib.dump_cert(chain[0]), "chain": [certlib.dump_cert(x) for x in chain[1:]] }) certlib.add_all_domains(cert_data) cert_data['source'] = { "url": result_info['log_info']['url'], } chain_hash = hashlib.sha256("".join([ x['as_der'] for x in cert_data['chain'] ]).encode('ascii')).hexdigest() # header = "url, cert_index, chain_hash, cert_der, all_domains, not_before, not_after" lines.append(",".join([ result_info['log_info']['url'], str(entry['cert_index']), chain_hash, cert_data['leaf_cert'] ['as_der'], ' '.join(cert_data['leaf_cert']['all_domains']), str(cert_data['leaf_cert']['not_before']), str(cert_data['leaf_cert']['not_after']) ]) + "\n") print("[{}] Finished, writing CSV...".format(os.getpid())) with open(csv_file, 'w', encoding='utf8') as f: f.write("".join(lines)) print("[{}] CSV {} written!".format(os.getpid(), csv_file)) except Exception as e: print("========= EXCEPTION =========") traceback.print_exc() print(e) print("=============================") return True
def generate_keypair(expiration=10 * 365 * 24 * 60 * 60): """ Generate a new private key and certificate and save it to path specified by user in config YAML passed to `set_config()` Parameters ---------- expiration : int Number of seconds from now after which the generated certificate should expire """ if _CONF.get("general_config") is None: raise MC2ClientConfigError("Configuration not set") user_config = yaml.safe_load(open(_CONF["general_config"]).read())["user"] username = user_config["username"] private_key_path = user_config["private_key"] cert_path = user_config["certificate"] print(cert_path) root_cert_path = user_config["root_certificate"] root_private_key_path = user_config["root_private_key"] if os.path.exists(private_key_path): print("Skipping keypair generation - private key already exists at {}". format(private_key_path)) return if os.path.exists(cert_path): print("Skipping keypair generation - certificate already exists at {}". format(cert_path)) return # Generate the key key = crypto.PKey() key.generate_key(crypto.TYPE_RSA, 3072) with open(private_key_path, "wb") as priv_key_file: priv_key_file.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key)) # Generate the certificate signing request ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(root_cert_path).read()) ca_key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(root_private_key_path).read()) req = crypto.X509Req() req.get_subject().CN = username req.set_pubkey(key) req.sign(ca_key, "sha256") # Generate the certificate cert = crypto.X509() cert.gmtime_adj_notBefore(0) cert.gmtime_adj_notAfter(expiration) # Certificate expiration cert.set_issuer(ca_cert.get_subject()) cert.set_subject(req.get_subject()) cert.set_pubkey(req.get_pubkey()) cert.sign(ca_key, "sha256") with open(cert_path, "wb") as cert_file: cert_file.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
def x509(self): """ returns an instance of OpenSSL.crypto.X509 """ if self.certificate: return crypto.load_certificate(crypto.FILETYPE_PEM, self.certificate)
def import_certificate(client, vault_base_url, certificate_name, certificate_data, disabled=False, password=None, certificate_policy=None, tags=None): import binascii x509 = None content_type = None try: x509 = crypto.load_certificate(crypto.FILETYPE_PEM, certificate_data) # if we get here, we know it was a PEM file content_type = 'application/x-pem-file' try: # for PEM files (including automatic endline conversion for Windows) certificate_data = certificate_data.decode('utf-8').replace( '\r\n', '\n') except UnicodeDecodeError: certificate_data = binascii.b2a_base64(certificate_data).decode( 'utf-8') except (ValueError, crypto.Error): pass if not x509: try: if password: x509 = crypto.load_pkcs12(certificate_data, password).get_certificate() else: x509 = crypto.load_pkcs12(certificate_data).get_certificate() content_type = 'application/x-pkcs12' certificate_data = binascii.b2a_base64(certificate_data).decode( 'utf-8') except crypto.Error: raise CLIError( 'We could not parse the provided certificate as .pem or .pfx. Please verify the certificate with OpenSSL.') # pylint: disable=line-too-long not_before, not_after = None, None if x509.get_notBefore(): not_before = _asn1_to_iso8601(x509.get_notBefore()) if x509.get_notAfter(): not_after = _asn1_to_iso8601(x509.get_notAfter()) cert_attrs = CertificateAttributes(enabled=not disabled, not_before=not_before, expires=not_after) if certificate_policy: secret_props = certificate_policy.get('secret_properties') if secret_props: secret_props['content_type'] = content_type elif certificate_policy and not secret_props: certificate_policy['secret_properties'] = SecretProperties( content_type=content_type) else: certificate_policy = CertificatePolicy( secret_properties=SecretProperties(content_type=content_type)) logger.info("Starting 'keyvault certificate import'") result = client.import_certificate( vault_base_url=vault_base_url, certificate_name=certificate_name, base64_encoded_certificate=certificate_data, certificate_attributes=cert_attrs, certificate_policy=certificate_policy, tags=tags, password=password) logger.info("Finished 'keyvault certificate import'") return result
def _read_ca(self, file): self.cert = load_certificate(FILETYPE_PEM, open(file, 'rb').read()) self.key = load_privatekey(FILETYPE_PEM, open(file, 'rb').read())
def parse_registration_data(reg_data): """ returns the parsed registration data in a tuple attestation_cert, user_pub_key, key_handle, signature, description * attestation_cert is a x509 object * user_pub_key is a hex string * key_handle is a hex string * signature is a hex string * description is a basestring see https://fidoalliance.org/specs/fido-u2f-v1.0-nfc-bt-amendment -20150514/fido-u2f-raw-message-formats.html#registration-messages :param reg_data: base64 encoded registration data :return: tuple """ reg_data_bin = url_decode(reg_data) reserved_byte = reg_data_bin[0] # must be '\x05' if reserved_byte != '\x05': raise Exception("The registration data is in a wrong format. It must" "start with 0x05") user_pub_key = reg_data_bin[1:66] key_handle_len = ord(reg_data_bin[66]) # We need to save the key handle key_handle = reg_data_bin[67:67 + key_handle_len] certificate = reg_data_bin[67 + key_handle_len:] attestation_cert = crypto.load_certificate(crypto.FILETYPE_ASN1, certificate) cert_len = len( crypto.dump_certificate(crypto.FILETYPE_ASN1, attestation_cert)) # TODO: Check the issuer of the certificate issuer = attestation_cert.get_issuer() log.debug("The attestation certificate is signed by %s" % issuer) not_after = attestation_cert.get_notAfter() not_before = attestation_cert.get_notBefore() log.debug("The attestation certificate " "is valid from %s to %s" % (not_before, not_after)) start_time = time.strptime(not_before, "%Y%m%d%H%M%SZ") end_time = time.strptime(not_after, "%Y%m%d%H%M%SZ") # check the validity period of the certificate if start_time > time.localtime() or \ end_time < time.localtime(): #pragma no cover log.error("The certificate is not valid. %s -> %s" % (not_before, not_after)) raise Exception("The time of the attestation certificate is not " "valid.") # Get the subject as description subj_x509name = attestation_cert.get_subject() subj_list = subj_x509name.get_components() description = "" for component in subj_list: # each component is a tuple. We are looking for CN if component[0].upper() == "CN": description = component[1] break signature = reg_data_bin[67 + key_handle_len + cert_len:] return (attestation_cert, binascii.hexlify(user_pub_key), binascii.hexlify(key_handle), binascii.hexlify(signature), description)
#!/usr/bin/env python import json import sys from OpenSSL import crypto # $ pip install pyopenssl with open(sys.argv[1], 'rb') as der_file: x509 = crypto.load_certificate(crypto.FILETYPE_PEM, der_file.read()) print(x509.get_subject().get_components())
def validateCertificate(self, certificate_pem, cidadao_name, autent_name): cert_obj = crypto.load_certificate(crypto.FILETYPE_PEM, certificate_pem) chain = [] try: autent_id = int(autent_name[-1]) cidadao_id = int(cidadao_name[-1]) if cidadao_id < 1 or cidadao_id > 3 or autent_id < 1 or autent_id > 9: raise ValueError except ValueError: return False autent_filename = "EC-de-Autenticacao-do-Cartao-de-Cidadao-000" + str(autent_id) + ".pem" cidadao_filename = "Cartao-de-Cidadao-00" + str(cidadao_id) + ".pem" trusted_certs = [autent_filename, cidadao_filename, "Baltimore_CyberTrust_Root.pem","ECRaizEstado.pem"] for fn in trusted_certs: f = open(os.path.join(os.getcwd(), "certificates","pteidcc",fn), 'r') chain.append(crypto.load_certificate(crypto.FILETYPE_PEM, f.read())) f.close() try: store = crypto.X509Store() for cert in chain: store.add_cert(cert) store_ctx = crypto.X509StoreContext(store, cert_obj) if store_ctx.verify_certificate() == None: return True except Exception: return False return False