def create_crlsets(): """ Create test CRLs """ print("creating crl set") revoked = crypto.Revoked() chainrev = crypto.Revoked() future_revoked = crypto.Revoked() revoked.set_rev_date(dates['OK_NOW'].encode('utf-8')) chainrev.set_rev_date(dates['OK_NOW'].encode('utf-8')) future_revoked.set_rev_date(dates['FUTURE'].encode('utf-8')) # the get_serial_number method results in a hex str like '0x17' # but set_serial needs a hex str like '17' ser = hex(end_certs['revoked'][0].get_serial_number())[2:] revoked.set_serial(ser.encode('utf-8')) ser = hex(end_certs['west_chain_revoked'][0].get_serial_number())[2:] chainrev.set_serial(ser.encode('utf-8')) ser = hex(end_certs['revoked'][0].get_serial_number())[2:] future_revoked.set_serial(ser.encode('utf-8')) needupdate = crypto.CRL() needupdate.add_revoked(revoked) needupdate.add_revoked(chainrev) with open(dirbase + "crls/needupdate.crl", "wb") as f: f.write(needupdate.export(ca_certs['mainca'][0], ca_certs['mainca'][1], type=crypto.FILETYPE_ASN1, days=0, digest='sha256'.encode('utf-8'))) print("sleeping for needupdate/valid crl time difference") time.sleep(5) validcrl = crypto.CRL() validcrl.add_revoked(revoked) validcrl.add_revoked(chainrev) with open(dirbase + "crls/cacrlvalid.crl", "wb") as f: f.write(validcrl.export(ca_certs['mainca'][0], ca_certs['mainca'][1], type=crypto.FILETYPE_ASN1, days=15, digest='sha256'.encode('utf-8'))) othercrl = crypto.CRL() othercrl.add_revoked(revoked) othercrl.add_revoked(chainrev) with open(dirbase + "crls/othercacrl.crl", "wb") as f: f.write(othercrl.export(ca_certs['otherca'][0], ca_certs['otherca'][1], type=crypto.FILETYPE_ASN1, days=15, digest='sha256'.encode('utf-8'))) notyet = crypto.CRL() notyet.add_revoked(future_revoked) with open(dirbase + "crls/futurerevoke.crl", "wb") as f: f.write(notyet.export(ca_certs['mainca'][0], ca_certs['mainca'][1], type=crypto.FILETYPE_ASN1, days=15, digest='sha256'.encode('utf-8')))
def save_revocation_list(cls): """ Saves the certificate revocation list used by ser2sock. """ ser2sock_config_path = Setting.get_by_name( 'ser2sock_config_path').value if not ser2sock_config_path: raise ValueError('ser2sock_config_path is not set.') path = os.path.join(ser2sock_config_path, 'ser2sock.crl') ca_cert = cls.query.filter_by(type=CA).first() with open(path, 'w') as crl_file: crl = crypto.CRL() for cert in cls.query.all(): if cert.type != CA: if cert.status == REVOKED: revoked = crypto.Revoked() revoked.set_reason(None) # NOTE: crypto.Revoked() expects YYYY instead of YY as needed by the cert index above. revoked.set_rev_date( time.strftime('%Y%m%d%H%M%SZ', cert.revoked_on.utctimetuple())) revoked.set_serial(str(cert.serial_number)) crl.add_revoked(revoked) crl_data = crl.export(ca_cert.certificate_obj, ca_cert.key_obj) crl_file.write(crl_data)
def main(): pkey = crypto.PKey() pkey.generate_key(crypto.TYPE_RSA, 2048) ca = crypto.X509() ca.set_version(2) ca.set_serial_number(1) ca.get_subject().CN = 'snakeoil' ca.set_notBefore(b'19700101000000Z') ca.set_notAfter(b'20991231235959Z') ca.set_issuer(ca.get_subject()) ca.set_pubkey(pkey) ca.sign(pkey, 'sha256') revoked = crypto.Revoked() revoked.set_serial(b'2a') revoked.set_rev_date(b'19700101000000Z') revoked.set_reason(None) crl = crypto.CRL() crl.set_lastUpdate(b'19700101000000Z') crl.set_nextUpdate(b'20990101000000Z') crl.add_revoked(revoked) crl.sign(issuer_cert=ca, issuer_key=pkey, digest=b'sha256') with open(osp.join(osp.dirname(__file__), 'minimal.crl'), 'wb') as f_crl: f_crl.write(crypto.dump_crl(crypto.FILETYPE_ASN1, crl))
def generate_crl(): # Getting a list of certificates result = Certificate.query.with_entities(Certificate.serial).all() crl = crypto.CRL() # Getting the CA information key = Key.query.filter_by(ca=1).first() private_key = crypto.load_privatekey(crypto.FILETYPE_PEM, key.private, passphrase="testtest") public_key = crypto.load_certificate(crypto.FILETYPE_PEM, key.public) for cert in result: now = datetime.datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii") revoked = crypto.Revoked() revoked.set_rev_date(now) revoked.set_reason(revoked.all_reasons()[1]) revoked.set_serial(str(cert.serial[:-1])) crl.add_revoked(revoked) with open("test.crl", "wb") as f: f.write( crl.export(public_key, private_key, crypto.FILETYPE_PEM, days=30, digest=b'sha256')) return ""
def revoke_sn(self, sn): revoke = crypto.Revoked() revoke.set_serial(format(sn, 'x').encode('UTF-8')) revoke.set_rev_date(Utils.asn1_date().encode('UTF-8')) self.crl.add_revoked(revoke) self.crl.set_lastUpdate(Utils.asn1_date().encode('UTF-8'))
def __init__(self): """ Get plugins for use in other class methods. Set unique keys. """ super(OMemberAuthorityResourceManager, self).__init__() self._resource_manager_tools = pm.getService('resourcemanagertools') self._set_unique_keys() #<UT> config = pm.getService("config") cert_path = expand_amsoil_path( config.get("delegatetools.trusted_cert_path")) cert_key_path = expand_amsoil_path( config.get("delegatetools.trusted_cert_keys_path")) hostname = config.get('flask.cbas_hostname') self._ma_crl_path = expand_amsoil_path(config.get("delegatetools.trusted_crl_path")) + '/' \ + hostname + '.authority.ma' self._ma_cert_str = self._resource_manager_tools.read_file( cert_path + '/' + OMemberAuthorityResourceManager.MA_CERT_FILE) self._ma_cert_key_str = self._resource_manager_tools.read_file( cert_key_path + '/' + OMemberAuthorityResourceManager.MA_KEY_FILE) self.gfed_ex = pm.getService('apiexceptionsv2') self._urn = self.urn() self._cert_revoke_reasons = crypto.Revoked().all_reasons() self._ma_cert = crypto.load_certificate(crypto.FILETYPE_PEM, self._ma_cert_str) self._ma_cert_key = crypto.load_privatekey(crypto.FILETYPE_PEM, self._ma_cert_key_str)
def generate_crl(self): """ Generates Certificate Revocation List :return: CRL in PEM format """ lookup_results = self._resource_manager_tools.object_lookup( self.AUTHORITY_NAME, 'crl', {}, []) crl = crypto.CRL() now = dt.datetime.utcnow() for entry in lookup_results: cert_expiration_date = dt.datetime.strptime( entry['CERT_VALID_UNTIL'], '%Y%m%d%H%M%SZ') if cert_expiration_date > now: revoked_entry = crypto.Revoked() revoked_entry.set_serial(hex(entry['CERT_SERIAL_NUMBER'])[2:]) revoked_entry.set_reason(str(entry['REVOKE_REASON'])) revoked_entry.set_rev_date(str(entry['REVOKE_DATE'])) crl.add_revoked(revoked_entry) else: self._resource_manager_tools.object_delete( self.AUTHORITY_NAME, 'crl', {'CERT_SERIAL_NUMBER': entry['CERT_SERIAL_NUMBER']}) return crl.export(self._ma_cert, self._ma_cert_key, days=self.CRL_VALIDITY_PERIOD)
def generate_full_crl(caid): ''' This route is used to generate the full CRL. The procedure works like the following: 1. App connects to database 2. App queries a list of certificates bound to this CA with status "Revoked" (2) 3. App generates CRL and puts this CRL into database ''' # Import section from OpenSSL import crypto, SSL # Getting data data = request.get_json() # Getting CA ca = CertificateAuthority.query.get(caid) if not ca: abort(config.http_notfound, {"message": config.error_ca_notfound}) # Getting the CA Key, that will be used to sign certificates key = ca.keys[0] if not key: abort(config.http_notfound, {"message": config.error_pkey_notfound}) try: private_key = crypto.load_privatekey(crypto.FILETYPE_PEM, key.private, passphrase=str(data['pass'])) public_key = crypto.load_certificate(crypto.FILETYPE_PEM, key.public) except Exception as e: abort(config.http_notauthorized, {"message": config.error_pass_incorrect}) # Getting a list of certificates with Revoked status result = Certificate.query.with_entities( Certificate.serial, Certificate.code_revoke).filter( (Certificate.status == config.STATUS_REVOKED) | (Certificate.status == config.STATUS_PAUSED)).all() # Starting the generate CRL crl = crypto.CRL() for cert in result: revoked = crypto.Revoked() revoked.set_rev_date( datetime.datetime.now().strftime("%Y%m%d%H%M%SZ").encode("ascii")) revoked.set_reason(revoked.all_reasons()[cert.code_revoke]) revoked.set_serial(str(cert.serial[:-1])) crl.add_revoked(revoked) # Creating new CRL crlObject = CRL() crlObject.created = datetime.datetime.utcnow() crlObject.crl = crl.export(public_key,private_key,crypto.FILETYPE_ASN1,\ days=config.CRL_VALID_DAYS,digest=b'sha256') ca.crls.append(crlObject) db.session.add(crlObject) db.session.commit() return jsonify(message=config.msg_crl_generated), config.http_created
def revoke(client_certificate): revoked = crypto.Revoked() revoked.set_serial( str(client_certificate.get_serial_number()).encode("utf-8")) revoked.set_rev_date( b"20191217100354Z") # TODO: adjust with the real revocation date revoked.set_reason(b'keyCompromise') return revoked
def parse_command(self, cmd, body=""): if cmd == "export-crl": """ Generate CRL object based on certificate serial number and revocation timestamp """ crl = crypto.CRL() if body: for line in body.split("\n"): serial_number, timestamp = line.split(":") # TODO: Assert serial against regex revocation = crypto.Revoked() revocation.set_rev_date( datetime.fromtimestamp(int(timestamp)).strftime( "%Y%m%d%H%M%SZ").encode("ascii")) revocation.set_reason(b"keyCompromise") revocation.set_serial(serial_number.encode("ascii")) crl.add_revoked(revocation) self.send( crl.export(self.server.certificate, self.server.private_key, crypto.FILETYPE_PEM, self.server.revocation_list_lifetime)) elif cmd == "ocsp-request": NotImplemented # TODO: Implement OCSP elif cmd == "sign-request": request = crypto.load_certificate_request(crypto.FILETYPE_PEM, body) for e in request.get_extensions(): key = e.get_short_name().decode("ascii") if key not in EXTENSION_WHITELIST: raise ValueError( "Certificte Signing Request contains extension '%s' which is not whitelisted" % key) # TODO: Potential exploits during PEM parsing? cert = raw_sign(self.server.private_key, self.server.certificate, request, basic_constraints=self.server.basic_constraints, key_usage=self.server.key_usage, extended_key_usage=self.server.extended_key_usage, lifetime=self.server.lifetime) self.send(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) else: raise NotImplementedError("Unknown command: %s" % cmd) self.close_when_done()
def get_revocation(self): """Get a crypto.Revoked object or None if the cert is not revoked.""" if self.revoked is False: raise ValueError('Certificate is not revoked.') r = crypto.Revoked() # set_serial expects a str without the ':' r.set_serial(force_bytes(self.serial.replace(':', ''))) if self.revoked_reason: r.set_reason(force_bytes(self.revoked_reason)) r.set_rev_date(force_bytes(format_date(self.revoked_date))) return r
def revoke_cert(self, cert_name): # Load CA certificate ca_cert = self._load_cert_from_file(self.key_dir + '/ca.crt') # Load CA Key ca_key = self._load_key_from_file(self.key_dir + '/ca.key') # Load Certificate cert = self._load_cert_from_file(self.key_dir + '/' + cert_name + '.crt') # Load Private Key key = self._load_key_from_file(self.key_dir + '/' + cert_name + '.key') # Load CRL File crl = self._load_crl_from_file(self.key_dir + '/crl.pem') print('Revoking ' + cert_name + ' (Serial: ' + str(cert.get_serial_number()) + ')') # Revoke certificate revoked = crypto.Revoked() revoked.set_serial( hex(int(cert.get_serial_number()))[2:].encode("utf-8")) revoked.set_reason(b'unspecified') revoked.set_rev_date( datetime.utcnow().strftime('%Y%m%d%H%M%SZ').encode("utf-8")) crl.add_revoked(revoked) # Write CRL file self._write_crl_to_file(crl, ca_cert, ca_key, key_dir + '/crl.pem') # Update index file index_file = open(key_dir + '/index.txt', 'r') index_file_new = open(key_dir + '/index.txt.new', 'w') for line in index_file.readlines(): line_split = re.split('\t', line) if int(line_split[3], 16) == cert.get_serial_number(): new_line = 'R\t' + line_split[1] + '\t' + revoked.get_rev_date( ).decode("utf-8") + '\t' + line_split[3] + '\t' + line_split[ 4] + '\t' + line_split[5] index_file_new.write(new_line) else: index_file_new.write(line) index_file.close() index_file_new.close() copy('keys/index.txt.new', 'keys/index.txt') remove('keys/index.txt.new')
def crl(self): """ Returns up to date CRL of this CA """ revoked_certs = self.get_revoked_certs() crl = crypto.CRL() now_str = timezone.now().strftime(generalized_time) for cert in revoked_certs: revoked = crypto.Revoked() revoked.set_serial(bytes_compat(cert.serial_number)) revoked.set_reason(b'unspecified') revoked.set_rev_date(bytes_compat(now_str)) crl.add_revoked(revoked) return crl.export(self.x509, self.pkey, days=1, digest=b'sha256')
def crl(self): """ Returns up to date CRL of this CA """ revoked_certs = self.get_revoked_certs() crl = crypto.CRL() now_str = datetime_to_string(timezone.now()) for cert in revoked_certs: revoked = crypto.Revoked() revoked.set_serial(bytes(str(cert.serial_number), 'utf8')) revoked.set_reason(b'unspecified') revoked.set_rev_date(bytes(str(now_str), 'utf8')) crl.add_revoked(revoked) return crl.export(self.x509, self.pkey, days=1, digest=b'sha256')
def create_crl(revokedcert, cakey, cacert, crlfile, next_crl_days=VALID_DAYS): crl = crypto.CRL() revoked = crypto.Revoked() serial_number = "%x" % revokedcert.get_serial_number() now = datetime.utcnow() now_str = now.strftime('%Y%m%d%H%M%SZ') revoked.set_serial(serial_number) revoked.set_reason('unspecified') revoked.set_rev_date(now_str) # revoked as of now crl.add_revoked(revoked) open(crlfile, "wt").write(crl.export(cacert, cakey, days=next_crl_days))
def gen_crl(cert, key, format_crl, serials=[]): crl = crypto.CRL() for s in serials: r = crypto.Revoked() r.set_reason('keyCompromise') r.set_rev_date('19700101000000Z') r.set_serial(s) crl.add_revoked(r) if format_crl == 'pem': format_crl = crypto.FILETYPE_PEM else: format_crl = crypto.FILETYPE_ASN1 crl.set_version(1) crl.sign(cert, key, 'sha256') return crl.export(cert, key, format_crl, 18250, b'sha256')
def create_revoke_list(ca_cert: bytes, ca_key: bytes, serials: List[Tuple[int, datetime]]) -> bytes: crl = crypto.CRL() crl.set_lastUpdate(datetime.utcnow().strftime('%Y%m%d%H%M%SZ').encode()) crl.set_nextUpdate( (datetime.utcnow() + timedelta(days=365)).strftime('%Y%m%d%H%M%SZ').encode()) for serial, revoked_at in serials: revoked = crypto.Revoked() revoked.set_serial(hex(serial)[2:].encode()) revoked.set_reason(b'keyCompromise') revoked.set_rev_date(revoked_at.strftime('%Y%m%d%H%M%SZ').encode()) crl.add_revoked(revoked) key = crypto.load_privatekey(crypto.FILETYPE_PEM, ca_key) cert = crypto.load_certificate(crypto.FILETYPE_PEM, ca_cert) crl.sign(cert, key, digest.encode()) return crypto.dump_crl(crypto.FILETYPE_PEM, crl)
def revoke_certificate(ca_cert_path, ca_key_path, clr_path, cert_path): # load files try: with open(ca_cert_path) as ca_file: ca = crypto.load_certificate(crypto.FILETYPE_PEM, ca_file.read()) with open(ca_key_ath) as ca_key_file: ca_key = crypto.load_privatekey(crypto.FILETYPE_PEM, ca_key_file.read()) except IOError as e: log.error(e) raise with open(clr_path, 'r') as f: crl = crypto.load_crl(crypto.FILETYPE_PEM, f.read()) x509 = crypto.load_certificate(crypto.FILETYPE_PEM, cert) revoked = crypto.Revoked() revoked.set_serial((hex(x509.get_serial_number())[2:])) crl.add_revoked(revoked) crl_text = crl.export(ca, ca_key) with open(clr_path, 'a') as f: f.write(crl_text)
def revoke_certificate(ca_pem, ca_key, revoked_file, crl_file, user_cert_dir, username, crl_path=None): """ Function to create/update a CRL with revoked user certificates :param ca_pem: The path to your CA PEM file :param ca_key: The Path to your CA key file :param revoked_file: Path to JSON file to be used as a DB for revocation :param crl_file: Path to CRL file :param user_cert_dir: Path to director containing all issued user PEM files :param username: the username to Revoke :param crl_path: The path to your previous CRL file to be loaded and updated :return: bool """ import os import json from OpenSSL import crypto from datetime import datetime data = {} certificate = crypto.load_certificate(crypto.FILETYPE_PEM, open(ca_pem, mode="rb").read()) private_key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(ca_key, mode="r").read()) if crl_path: crl = crypto.load_crl(crypto.FILETYPE_PEM, open(crl_path, mode="rb").read()) else: crl = crypto.CRL() if os.path.exists(revoked_file): with open(revoked_file, 'r') as json_file: data = json.load(json_file) for cert in os.listdir(user_cert_dir): if cert.lower() == f"{username.lower()}.pem": with open(cert, 'rb') as cert: revoked_cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert.read()) data[str(revoked_cert.get_serial_number())] = username break for key in data: revoked_time = _utc_time_from_datetime(datetime.utcnow()) revoked = crypto.Revoked() revoked.set_serial(format(int(key), "02x").encode()) revoked.set_rev_date(bytes(revoked_time, encoding='utf8')) crl.add_revoked(revoked) crl.sign(certificate, private_key, b"sha256") with open(revoked_file, 'w+') as json_file: json.dump(data, json_file) with open(crl_file, 'wb') as f: f.write(crl.export(cert=certificate, key=private_key, digest=b"sha256")) delete = 0 with open(ca_pem, "r") as f: lines = f.readlines() with open(ca_pem, "w") as f: for line in lines: if delete: continue elif line.strip("\n") != "-----BEGIN X509 CRL-----": f.write(line) else: delete = 1 with open(ca_pem, "ab") as f: f.write(crl.export(cert=certificate, key=private_key, digest=b"sha256"))
def revoke(self, cert, rev_reason='unspecified', rev_date=None): """ revoke certificate """ self.logger.debug('CAhandler.revoke({0}: {1})'.format(rev_reason, rev_date)) code = None message = None detail = None # overwrite revocation date - we ignore what has been submitted rev_date = uts_to_date_utc(uts_now(), '%y%m%d%H%M%SZ') if 'issuing_ca_crl' in self.issuer_dict and self.issuer_dict['issuing_ca_crl']: # load ca cert and key (ca_key, ca_cert) = self._ca_load() # turn of chain_check due to issues in pyopenssl (check is not working if key-usage is set) # result = self._certificate_chain_verify(cert, ca_cert) result = None # proceed if the cert and ca-cert belong together # if not result: serial = cert_serial_get(self.logger, cert) # serial = serial.replace('0x', '') if ca_key and ca_cert and serial: serial = hex(serial).replace('0x', '') if os.path.exists(self.issuer_dict['issuing_ca_crl']): # existing CRL with open(self.issuer_dict['issuing_ca_crl'], 'r') as fso: crl = crypto.load_crl(crypto.FILETYPE_PEM, fso.read()) # check CRL already contains serial sn_match = self._crl_check(crl, serial) else: # new CRL crl = crypto.CRL() sn_match = None # this is the revocation operation if not sn_match: revoked = crypto.Revoked() revoked.set_reason(convert_string_to_byte(rev_reason)) revoked.set_serial(convert_string_to_byte(serial)) revoked.set_rev_date(convert_string_to_byte(rev_date)) crl.add_revoked(revoked) # save CRL crl_text = crl.export(ca_cert, ca_key, crypto.FILETYPE_PEM, 7, convert_string_to_byte('sha256')) with open(self.issuer_dict['issuing_ca_crl'], 'wb') as fso: fso.write(crl_text) code = 200 else: code = 400 message = 'urn:ietf:params:acme:error:alreadyRevoked' detail = 'Certificate has already been revoked' else: code = 400 message = 'urn:ietf:params:acme:error:serverInternal' detail = 'configuration error' #else: # code = 400 # message = 'urn:ietf:params:acme:error:serverInternal' # detail = result else: code = 400 message = 'urn:ietf:params:acme:error:serverInternal' detail = 'Unsupported operation' self.logger.debug('CAhandler.revoke() ended') return(code, message, detail)
def update_crl(): # Load root key and cert root_cert, root_key = load_root() # Load CRL if one is found in current directory root_crl = load_crl() if root_crl: print 'Found %s.crl' % (config.root, ) # Identify revoked certs print print 'Revoked serial numbers:' print 'serial' for rev in root_crl.get_revoked(): print rev.get_serial().lower() else: root_crl = crypto.CRL() # List certificates in current directory print print 'Certificates in current directory:' known_certs = glob.glob('*.crt') # Remove root cert from list, cannot revoke itself known_certs.remove(config.root + '.crt') if len(known_certs) < 1: print 'none found' return name2serial = {} print '%-16s %-20s %-15s %-15s' % ('serial', 'name', 'from', 'to') for certname in known_certs: f = open(certname, 'rt') pem = f.read() f.close() cert = crypto.load_certificate(crypto.FILETYPE_PEM, pem) serial = hex(cert.get_serial_number())[2:-1] name2serial[certname[:-4]] = serial print '%-16s %-20s %-15s %-15s' % (serial, certname[:-4], nice_date(cert.get_notBefore()), nice_date(cert.get_notAfter())) while 1: print req = raw_input('Certificate to revoke by name (return to exit): ') if len(req) < 1: return if not req in name2serial.keys(): print 'cannot find:', req else: break rev = crypto.Revoked() rev.set_serial(name2serial[req]) rev.set_reason('unspecified') rev.set_rev_date(now()) # Update CRL root_crl.add_revoked(rev) # Sign CRL crl_text = root_crl.export(root_cert, root_key, crypto.FILETYPE_PEM, days=365) # Publish CRL f = open(config.root + '.crl', 'w') f.write(crl_text) f.close() return