def decode_obj(data, expected_type): der = asn1.DerObject() der.decode(data) if der.typeTag != expected_type: raise InvalidReceipt('Expected tag type {}; got {}'.format( expected_type, der.typeTag)) return der.payload
def verifyCertificateSignature(certificate, ca_certificate): # Get the signature algorithm algorithm = certificate.get_signature_algorithm() cert_asn1 = crypto.dump_certificate(crypto.FILETYPE_ASN1, certificate) # Decode the certificate der = asn1.DerSequence() der.decode(cert_asn1) # Der is [certificate, signature algorithm, signature] der_cert = der[0] der_algo = der[1] der_sig = der[2] # Decode signature der_sigTemp = asn1.DerObject() der_sigTemp.decode(der_sig) # Get the signature sig = der_sigTemp.payload[1:] # Verify the certificate try: crypto.verify(ca_certificate, sig, der_cert, bytesToString(algorithm)) return True except crypto.Error as e: return False
def validate_cert(self, cacert_pem): #print cacert_pem # Create an X509 object for cacert_pem (CA Certificate). cacert = X509.load_certificate_from_PEM( cacert_pem).get_certificate()[0] # Get the X509 object of this certifcate. cert = self.get_certificate()[0] sig_algo = cert.get_signature_algorithm() # Let's start with the ASN1 format of this certificate ASN1_cert = crypto.dump_certificate(crypto.FILETYPE_ASN1, cert) # We need everything in DER format der_seq = asn1.DerSequence() der_seq.decode(ASN1_cert) der_cert = der_seq[0] der_algo = der_seq[1] der_sig = asn1.DerObject() der_sig.decode(der_seq[2]) cert_sig_payload = der_sig.payload if cert_sig_payload[0] != '\x00': raise Exception('Unused bits found!') cert_sig = cert_sig_payload[1:] # Verify this cert with cacert try: crypto.verify(cacert, cert_sig, der_cert, sig_algo) #print "Certifcate Valid!" return True except crypto.Error as e: #print "Certrifcate Invalid: \n"+str(e) return False
def verify_sig(self, encoded_cert): der = asn1.DerSequence() der.decode(encoded_cert) der_sig = asn1.DerObject() der_sig.decode(der[2]) sig = der_sig.payload self.assertEqual(b'\x00', sig[:1]) crypto.verify(self.ca.cert, sig[1:], der[0], 'sha256')
def crl_dates(crl_der): crl_seq = asn1.DerSequence() crl_seq.decode(crl_der) if len(crl_seq) != 3: raise ValueError("unknown crl format") tbsCertList = asn1.DerSequence() tbsCertList.decode(crl_seq[0]) thisUpdate = asn1.DerObject() nextUpdate = asn1.DerObject() if isinstance(tbsCertList[0], types.StringTypes): # CRL v1 thisUpdate.decode(tbsCertList[2]) nextUpdate.decode(tbsCertList[3]) else: if tbsCertList[0] > 1: raise ValueError("unsupported CRL profile version: %d" % tbsCertList[0]) thisUpdate.decode(tbsCertList[3]) nextUpdate.decode(tbsCertList[4]) if thisUpdate.typeTag not in time_formats or \ nextUpdate.typeTag not in time_formats: raise ValueError("invalid CRL date/time fields") return time_formats[nextUpdate.typeTag](nextUpdate)
def getURLSFromCertificate(self, certificate): urls = [] for i in range(0, certificate.get_extension_count()): # Get the crl lists if (certificate.get_extension(i).get_short_name() == b'crlDistributionPoints'): data = asn1.DerObject() data.decode(certificate.get_extension(i).get_data()) if len(data.payload.split(b'http://')) > 1: content = data.payload.split(b'http://')[-1] urls += ["http://" + bytesToString(content)] # Get the delta crl lists if (certificate.get_extension(i).get_short_name() == b'freshestCRL' ): data = asn1.DerObject() data.decode(certificate.get_extension(i).get_data()) if len(data.payload.split(b'http://')) > 1: content = data.payload.split(b'http://')[-1] urls += ["http://" + bytesToString(content)] return urls
def extract_cert_signature(self, cert): # TODO: Can this be done from M2Crypto's certificate object? der_cert = cert.as_der() der = asn1.DerSequence() der.decode(der_cert) der_sig_raw = der[2] der_sig_dec = asn1.DerObject() der_sig_dec.decode(der_sig_raw) sig0 = der_sig_dec.payload sig = sig0[1:] return sig
def __init__(self, crt_fname, ca_fname): self.crt_fname = crt_fname self.ca_fname = ca_fname with open(ca_fname, 'r') as fh: self.ca_raw = fh.read() with open(crt_fname, 'r') as fh: self.crt_raw = fh.read() self.ca = ossl.load_certificate(ossl.FILETYPE_PEM, self.ca_raw) ossl_crt = ossl.load_certificate(ossl.FILETYPE_PEM, self.crt_raw) self.pdat = self.PEMData(*PEM.decode(self.crt_raw)) self.cdat = self.CrtData(*asn1.DerSequence().decode(self.pdat.cert)) _sig = asn1.DerObject().decode(self.cdat.sig).payload self.sig = self.SigData(_sig[0], _sig[1:], ossl_crt.get_signature_algorithm().decode()) self.crt = RSA.importKey(self.pdat.cert) self.verifier = PKCS1_v1_5.new(self.crt)
def _extract_plain_cert(nvhttp, text): cert_text = nvhttp.get_xml_string(text, "plaincert") cert = X509.load_cert_string(cert_text.decode('hex')) der_cert = cert.as_der() der = asn1.DerSequence() der.decode(der_cert) der_sig_raw = der[2] der_sig_dec = asn1.DerObject() der_sig_dec.decode(der_sig_raw) sig0 = der_sig_dec.payload sig = sig0[1:] return cert, sig.encode('hex')
def verifyCertSig(id_cert, cert_to_verify, algo='sha1'): '''Verify that the SSL certificate *id_cert* has signed the TLS cert *cert_to_verify*. :param id_cert: Identification Certificate :type id_cert: OpenSSL.crypto.X509 :param cert_to_verify: certificate to verify signature on :type cert_to_verify: OpenSSL.crypto.X509 :param algo: algorithm to use for certificate verification :type algo: str :returns: **bool** **True** if the signature of *cert_to_verify* can be verified from *id_cert*, **False** otherwise ''' cert_to_verify_ASN1 = OpenSSL.crypto.dump_certificate( OpenSSL.crypto.FILETYPE_ASN1, cert_to_verify) der = asn1.DerSequence() der.decode(cert_to_verify_ASN1) cert_to_verify_DER = der[0] cert_to_verify_ALGO = der[1] cert_to_verify_SIG = der[2] sig_DER = asn1.DerObject() sig_DER.decode(cert_to_verify_SIG) sig = sig_DER.payload # first byte is number of unused bytes. should be zero if sig[0] != '\x00': return False sig = sig[1:] try: OpenSSL.crypto.verify(id_cert, sig, cert_to_verify_DER, algo) return True except OpenSSL.crypto.Error: return False
def is_signed_by(self, other): if self.get_issuer().hash() != other.get_subject().hash(): return False signature_algorithm = self.get_signature_algorithm() self_asn1 = crypto.dump_certificate( crypto.FILETYPE_ASN1, self ) self_der = asn1.DerSequence() self_der.decode(self_asn1) der_cert, der_algo, der_sig = self_der der_sig_in = asn1.DerObject() der_sig_in.decode(der_sig) sig0 = der_sig_in.payload if sig0[0] != '\x00': raise Exception('Number of unused bits is strange') sig = sig0[1:] try: crypto.verify(other, sig, der_cert, signature_algorithm) return True except crypto.Error: return False return False
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_asn1 = crypto.dump_certificate(crypto.FILETYPE_ASN1, cert) der_seq = asn1.DerSequence() der_seq.decode(cert_asn1) cert_certificate = der_seq[0] #cert_signature_algorithm=der_seq[1] cert_signature = der_seq[2] cert_signature_decoded = asn1.DerObject() cert_signature_decoded.decode(cert_signature) signature_payload = cert_signature_decoded.payload sig_pay0 = signature_payload[0] if ((isinstance(sig_pay0, int) and sig_pay0 != 0) or (isinstance(sig_pay0, str) and sig_pay0 != '\x00')): return (False, "The certificate should not contain any unused bits.") signature = signature_payload[1:] try: crypto.verify(ca_cert, signature, cert_certificate, 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 parse_certs_from_connecs(dir_path, L, top): # Open database connection db = MySQLdb.connect("localhost","root","","CRL", charset='utf8' ) # prepare a cursor object using cursor() method cursor = db.cursor() for index, file_name in enumerate(L): if (index % 1000) == 0: print ("(%d) connection blobs have been processed" % (index)) matchObj = re.search( r'^(.*).txt$', file_name, re.I|re.M) if matchObj: uri = matchObj.group(1) file = open(os.path.join(dir_path,file_name), "r") ssl_session = 0 protocol = "" cipher = "" verify_code = -1 verify_msg = "" certFound = 0 certs = list() for line in file.readlines(): if (certFound == 1): cert += line matchObj = re.search( r'BEGIN CERTIFICATE', line, re.I|re.M) if matchObj: certFound = 1 cert = line; matchObj = re.search( r'END CERTIFICATE', line, re.I|re.M) if matchObj: certFound = 0; certs.append(cert) matchObj = re.search( r'^.*SSL-Session:.*$', line, re.I|re.M) if matchObj: ssl_session = 1 matchObj = re.search( r'^.*[Pp]rotocol\s*:\s*(.*)$', line, re.I|re.M) if ssl_session == 1 and matchObj: protocol = matchObj.group(1) matchObj = re.search( r'^.*[Cc]ipher\s*:\s*(.*)$', line, re.I|re.M) if ssl_session == 1 and matchObj: cipher = matchObj.group(1) matchObj = re.search( r'^.*[Vv]erify return code\s*:\s*(\d+)\s*\((.*)\).*$', line, re.I|re.M) if matchObj: verify_code = matchObj.group(1) verify_code = int(verify_code) verify_msg = matchObj.group(2) file.close() certs.reverse() num_of_certs = len(certs) prev_cert_id = -1 iden_cert_id = -1 for j, cert in enumerate(certs): cert_name = "%s_%d.pem" % (uri, (num_of_certs - j)) x509 = "" try: x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert) except: continue ######################################### ##### Insert the issuer information ##### issuer = x509.get_issuer() if issuer.organizationName is not None: matchObj = re.search( r'^.*"(.*)".*$', issuer.organizationName, re.I|re.M) if matchObj: issuer.organizationName = matchObj.group(1) if issuer.organizationalUnitName is not None: matchObj = re.search( r'^.*"(.*)".*$', issuer.organizationalUnitName, re.I|re.M) if matchObj: issuer.organizationalUnitName = matchObj.group(1) if issuer.commonName is not None: matchObj = re.search( r'^.*"(.*)".*$', issuer.commonName, re.I|re.M) if matchObj: issuer.commonName = matchObj.group(1) if issuer.countryName is not None: matchObj = re.search( r'^.*"(.*)".*$', issuer.countryName, re.I|re.M) if matchObj: issuer.countryName = matchObj.group(1) else: matchObj = re.search( r'^(.*)".*$', issuer.countryName, re.I|re.M) if matchObj: issuer.countryName = matchObj.group(1) sql = '''INSERT INTO names(country, org, org_unit, com_name, top) VALUES ("%s", "%s", "%s", "%s", %d) ON DUPLICATE KEY UPDATE name_id=LAST_INSERT_ID(name_id);''' % (issuer.countryName, issuer.organizationName, issuer.organizationalUnitName, issuer.commonName, top) Issuer_id = -1 try: cursor.execute(sql) issuer_id = db.insert_id() except MySQLdb.Error, e: print ("\tError2 %d: %s SQL STMT [%s]" % (e.args[0], e.args[1], sql)) print ("\tError2 saving the issuer information in the DB in [%s]" % file_name) sys.exit() ########################################## ##### Insert the subject information ##### subject = x509.get_subject() if subject.organizationName is not None: matchObj = re.search( r'^.*"(.*)".*$', subject.organizationName, re.I|re.M) if matchObj: subject.organizationName = matchObj.group(1) if subject.organizationalUnitName is not None: matchObj = re.search( r'^.*"(.*)".*$', subject.organizationalUnitName, re.I|re.M) if matchObj: subject.organizationalUnitName = matchObj.group(1) if subject.commonName is not None: matchObj = re.search( r'^.*"(.*)".*$', subject.commonName, re.I|re.M) if matchObj: subject.commonName = matchObj.group(1) if subject.countryName is not None: matchObj = re.search( r'^.*"(.*)".*$', subject.countryName, re.I|re.M) if matchObj: subject.countryName = matchObj.group(1) else: matchObj = re.search( r'^(.*)".*$', subject.countryName, re.I|re.M) if matchObj: subject.countryName = matchObj.group(1) sql = '''INSERT INTO names(country, org, org_unit, com_name, top) VALUES ("%s", "%s", "%s", "%s", %d) ON DUPLICATE KEY UPDATE name_id=LAST_INSERT_ID(name_id);''' % (subject.countryName, subject.organizationName, subject.organizationalUnitName, subject.commonName, top) subject_id = -1 try: cursor.execute(sql) subject_id = db.insert_id() except MySQLdb.Error, e: print ("\tError3 %d: %s" % (e.args[0], e.args[1])) print ("\tError3 saving the subject information in the DB in [%s] with SQL [%s]" % (file_name, sql)) sys.exit() ################################ ##### Check if self signed ##### is_self_signed = 0 if (subject.get_components()) == (issuer.get_components()): is_self_signed = 1 ############################## ##### Get the Extensions ##### crl_points = list() auth_points = list() ext_count = x509.get_extension_count() for i in range (0, ext_count): x509_ext = x509.get_extension(i) ext_name = x509_ext.get_short_name() matchObj = re.search( r'^.*crlDistributionPoints.*$', ext_name, re.I|re.M) if matchObj: ext_data_der = x509_ext.get_data() der_seq = asn1.DerSequence() der_seq.decode(ext_data_der) for u in range(len(der_seq)): der_obj = asn1.DerObject() der_obj.decode(der_seq[u]) matchObj = re.search( r'^.*(http[s]?:[\w\d=/\.%-_!]+).*$', der_obj.payload, re.I|re.M) if matchObj: try: crl_uri = matchObj.group(1) crl_points.append(crl_uri) except: print ("\tError3_1 error getting the CRL URI [%s] when connecting to [%s]" % (ext_data, file_name)) sys.exit() else: if (re.search( r'^.*(http.*).*$', der_obj.payload, re.I|re.M)): print ("\tError3_3 extracting the URI from [%s]" % der_obj.payload) else: pass matchObj = re.search( r'^.*authorityInfoAccess.*$', ext_name, re.I|re.M) if matchObj: ext_data_der = x509_ext.get_data() der_seq = asn1.DerSequence() der_seq.decode(ext_data_der) for u in range(len(der_seq)): der_obj = asn1.DerObject() der_obj.decode(der_seq[u]) matchObj = re.search( r'^.*(http:.*)$', der_obj.payload, re.I|re.M) if matchObj: try: auth_uri = matchObj.group(1) auth_points.append(auth_uri) except: print ("\tError3_2 error getting the Auth URI [%s] when connecting to [%s]" % (ext_data, file_name)) sys.exit() ############################################## ##### Insert the Authority URI in the DB ##### auth_ids = list() if len(auth_points) > 0: for auth_uri in auth_points: sql = '''INSERT INTO authority(auth_uri, top) VALUES ("%s", %d) ON DUPLICATE KEY UPDATE auth_id=LAST_INSERT_ID(auth_id);''' % (auth_uri, top) try: cursor.execute(sql) auth_id = db.insert_id() auth_ids.append(auth_id) except MySQLdb.Error, e: print ("\tError4 %d: %s" % (e.args[0], e.args[1])) print ("\tError4 saving the Authority information in the DB in [%s]", file_name) sys.exit()
############################## ##### Get the Extensions ##### crl_points = list() auth_points = list() ext_count = x509.get_extension_count() for i in range (0, ext_count): x509_ext = x509.get_extension(i) ext_name = x509_ext.get_short_name() matchObj = re.search( r'^.*crlDistributionPoints.*$', ext_name, re.I|re.M) if matchObj: ext_data_der = x509_ext.get_data() der_seq = asn1.DerSequence() der_seq.decode(ext_data_der) for u in range(len(der_seq)): der_obj = asn1.DerObject() der_obj.decode(der_seq[u]) matchObj = re.search( r'^.*(http[s]?:[\w\d=/\.%-_!]+).*$', der_obj.payload, re.I|re.M) if matchObj: try: crl_uri = matchObj.group(1) crl_points.append(crl_uri) except: print ("\tError3_1 error getting the CRL URI [%s] when connecting to [%s]" % (ext_data, file_name)) sys.exit() else: if (re.search( r'^.*(http.*).*$', der_obj.payload, re.I|re.M)): print ("\tError3_3 extracting the URI from [%s]" % der_obj.payload) else: pass matchObj = re.search( r'^.*authorityInfoAccess.*$', ext_name, re.I|re.M)
def auth(username, password, **kwargs): ''' Returns True if the given user cert (password is the cert contents) was issued by the CA and if cert's Common Name is equal to username. Returns False otherwise. ``username``: we need it to run the auth function from CLI/API; it should be in master config auth/acl ``password``: contents of user certificate (pem-encoded user public key); why "password"? For CLI, it's the only available name Configure the CA cert in the master config file: .. code-block:: yaml external_auth: pki: ca_file: /etc/pki/tls/ca_certs/trusted-ca.crt your_user: - .* ''' c = OpenSSL.crypto pem = password cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, pem) cacert_file = __salt__['config.get']('external_auth:pki:ca_file') with salt.utils.fopen(cacert_file) as f: cacert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, f.read()) log.debug('Attempting to authenticate via pki.') log.debug('Using CA file: {0}'.format(cacert_file)) log.debug('Certificate contents: {0}'.format(pem)) # Get the signing algorithm algo = cert.get_signature_algorithm() # Get the ASN1 format of the certificate cert_asn1 = c.dump_certificate(c.FILETYPE_ASN1, cert) # Decode the certificate der = asn1.DerSequence() der.decode(cert_asn1) # The certificate has three parts: # - certificate # - signature algorithm # - signature # http://usefulfor.com/nothing/2009/06/10/x509-certificate-basics/ der_cert = der[0] #der_algo = der[1] der_sig = der[2] # The signature is a BIT STRING (Type 3) # Decode that as well der_sig_in = asn1.DerObject() der_sig_in.decode(der_sig) # Get the payload sig0 = der_sig_in.payload # Do the following to see a validation error for tests # der_cert=der_cert[:20]+'1'+der_cert[21:] # First byte is the number of unused bits. This should be 0 # http://msdn.microsoft.com/en-us/library/windows/desktop/bb540792(v=vs.85).aspx if sig0[0] != '\x00': raise Exception('Number of unused bits is strange') # Now get the signature itself sig = sig0[1:] # And verify the certificate try: c.verify(cacert, sig, der_cert, algo) assert dict(cert.get_subject().get_components( ))['CN'] == username, "Certificate's CN should match the username" log.info('Successfully authenticated certificate: {0}'.format(pem)) return True except (OpenSSL.crypto.Error, AssertionError): log.info('Failed to authenticate certificate: {0}'.format(pem)) return False
# Decode the certificate der = asn1.DerSequence() der.decode(cert_asn1) # The certificate has three parts: # - certificate # - signature algorithm # - signature # http://usefulfor.com/nothing/2009/06/10/x509-certificate-basics/ der_cert = der[0] der_algo = der[1] der_sig = der[2] # The signature is a BIT STRING (Type 3) # Decode that as well der_sig_in = asn1.DerObject() der_sig_in.decode(der_sig) # Get the payload sig0 = der_sig_in.payload # Do the following to see a validation error for tests # der_cert=der_cert[:20]+'1'+der_cert[21:] # First byte is the number of unused bits. This should be 0 # http://msdn.microsoft.com/en-us/library/windows/desktop/bb540792(v=vs.85).aspx if sig0[0] != '\x00': raise Exception('Number of unused bits is strange') # Now get the signature itself sig = sig0[1:]