def extract_dates(raw_cert): if not HAVE_PYASN1: log.warning("Could not find pyasn1 and pyasn1_modules. " + \ "SSL certificate expiration COULD NOT BE VERIFIED.") return None, None cert = decoder.decode(raw_cert, asn1Spec=Certificate())[0] tbs = cert.getComponentByName('tbsCertificate') validity = tbs.getComponentByName('validity') not_before = validity.getComponentByName('notBefore') not_before = str(not_before.getComponent()) not_after = validity.getComponentByName('notAfter') not_after = str(not_after.getComponent()) if isinstance(not_before, GeneralizedTime): not_before = datetime.strptime(not_before, '%Y%m%d%H%M%SZ') else: not_before = datetime.strptime(not_before, '%y%m%d%H%M%SZ') if isinstance(not_after, GeneralizedTime): not_after = datetime.strptime(not_after, '%Y%m%d%H%M%SZ') else: not_after = datetime.strptime(not_after, '%y%m%d%H%M%SZ') return not_before, not_after
def from_string(cls, key_pem, is_x509_cert): """Construct an RsaVerifier instance from a string. Args: key_pem: string, public key in PEM format. is_x509_cert: bool, True if key_pem is an X509 cert, otherwise it is expected to be an RSA key in PEM format. Returns: RsaVerifier instance. Raises: ValueError: if the key_pem can't be parsed. In either case, error will begin with 'No PEM start marker'. If ``is_x509_cert`` is True, will fail to find the "-----BEGIN CERTIFICATE-----" error, otherwise fails to find "-----BEGIN RSA PUBLIC KEY-----". """ key_pem = _helpers._to_bytes(key_pem) if is_x509_cert: der = rsa.pem.load_pem(key_pem, 'CERTIFICATE') asn1_cert, remaining = decoder.decode(der, asn1Spec=Certificate()) if remaining != b'': raise ValueError('Unused bytes', remaining) cert_info = asn1_cert['tbsCertificate']['subjectPublicKeyInfo'] key_bytes = _bit_list_to_bytes(cert_info['subjectPublicKey']) pubkey = rsa.PublicKey.load_pkcs1(key_bytes, 'DER') else: pubkey = rsa.PublicKey.load_pkcs1(key_pem, 'PEM') return cls(pubkey)
def api_sign_certificate(): if request.headers['Content-Type'] == 'application/json': certificate = b64decode(str(request.json.get("certificate"))) bitcoin_address = str(request.json.get("bitcoin_address")) # Get the ACA secret key f = open(ACA_KEY, "r") sk_string = f.read() f.close() sk = RSA.importKey(sk_string) # Get the certificate hash and the asn1 representation of the certificate certificate_hash = certificate_hashing(certificate) signature = sk.sign(certificate_hash, 1)[0] asn1_cert = decoder.decode(certificate, asn1Spec=Certificate())[0] # Attach the signature to the certificate bin_signature = Signature("'%s'H" % ''.join("%02X" % ord(c) for c in long_to_bytes(signature))) asn1_cert.setComponentByName("signatureValue", bin_signature) # Store the certificate der_cert = encoder.encode(asn1_cert) store_certificate(encoder.encode(asn1_cert), bitcoin_address) return b64encode(der_cert)
def from_string(cls, public_key): """Construct an Verifier instance from a public key or public certificate string. Args: public_key (Union[str, bytes]): The public key in PEM format or the x509 public key certificate. Returns: Verifier: The constructed verifier. Raises: ValueError: If the public_key can't be parsed. """ public_key = _helpers.to_bytes(public_key) is_x509_cert = _CERTIFICATE_MARKER in public_key # If this is a certificate, extract the public key info. if is_x509_cert: der = rsa.pem.load_pem(public_key, "CERTIFICATE") asn1_cert, remaining = decoder.decode(der, asn1Spec=Certificate()) if remaining != b"": raise ValueError("Unused bytes", remaining) cert_info = asn1_cert["tbsCertificate"]["subjectPublicKeyInfo"] key_bytes = _bit_list_to_bytes(cert_info["subjectPublicKey"]) pubkey = rsa.PublicKey.load_pkcs1(key_bytes, "DER") else: pubkey = rsa.PublicKey.load_pkcs1(public_key, "PEM") return cls(pubkey)
def store_certificate(certificate, bitcoin_address): # Load ACA cert and public key aca_cert = X509.load_cert(ACA_CERT) pk = RSA.importKey(aca_cert.get_pubkey().as_der()) # Obtain the TBS certificate cert_hash = certificate_hashing(certificate) asn1_cert = decoder.decode(certificate, asn1Spec=Certificate())[0] # Extract the certificate signature signature_bin = asn1_cert.getComponentByName("signatureValue") # Parse the signature signature_str = "" for i in signature_bin: signature_str += str(i) signature = long(signature_str, 2) # Check the parsed signature matches with the signature of the obtained hash if pk.verify(cert_hash, [signature, 0]): utils_store_certificate(certificate, CS_CERTS_PATH + bitcoin_address, '.pem') response = "Certificate correctly stored" else: response = json.dumps({'data': "Bad certificate\n"}), 500 return response
def generate_certificate( self, aca_cert, btc_address=None, pkey=None, ): if pkey is None and btc_address is None: pkey, btc_address = self.generate_keys() self.btc_address = btc_address issuer = aca_cert.get_issuer() # Creating a certificate cert = X509.X509() # Set issuer cert.set_issuer(issuer) # Generate CS information cert_name = X509.X509_Name() cert_name.C = 'CT' cert_name.ST = 'Barcelona' cert_name.L = 'Bellaterra' cert_name.O = 'UAB' cert_name.OU = 'DEIC' cert_name.CN = btc_address cert.set_subject_name(cert_name) # Set public_key cert.set_pubkey(pkey) # Time for certificate to stay valid cur_time = ASN1.ASN1_UTCTIME() cur_time.set_time(int(time())) # Expire certs in 1 year. expire_time = ASN1.ASN1_UTCTIME() expire_time.set_time(int(time()) + 60 * 60 * 24 * 365) # Set the validity cert.set_not_before(cur_time) cert.set_not_after(expire_time) # Sign the certificate using the same key type the CA is going to use later # The resulting signature will not be used, it is only for setting the corresponding field into the certificate rsa_keys = RSA.gen_key(2046, 65537, callback=lambda x, y, z: None) rsa_pkey = EVP.PKey() rsa_pkey.assign_rsa(rsa_keys) cert.sign(rsa_pkey, md='sha256') # Load the Certificate as a ASN.1 object and extract the TBS Certificate (special thanks to Alex <*****@*****.**>) asn1_cert = decoder.decode(cert.as_der(), asn1Spec=Certificate())[0] tbs = asn1_cert.getComponentByName("tbsCertificate") # Compute the sha256 of the TBS Certificate tbs_der = encoder.encode(tbs) digest = sha256() digest.update(tbs_der) cert_hash = digest.digest() return asn1_cert, cert_hash
def extract_names(raw_cert): results = { 'CN': set(), 'DNS': set(), 'SRV': set(), 'URI': set(), 'XMPPAddr': set() } cert = decoder.decode(raw_cert, asn1Spec=Certificate())[0] tbs = cert.getComponentByName('tbsCertificate') subject = tbs.getComponentByName('subject') extensions = tbs.getComponentByName('extensions') or [] # Extract the CommonName(s) from the cert. for rdnss in subject: for rdns in rdnss: for name in rdns: oid = name.getComponentByName('type') value = name.getComponentByName('value') if oid != COMMON_NAME: continue value = decoder.decode(value, asn1Spec=DirectoryString())[0] value = decode_str(value.getComponent()) results['CN'].add(value) # Extract the Subject Alternate Names (DNS, SRV, URI, XMPPAddr) for extension in extensions: oid = extension.getComponentByName('extnID') if oid != SUBJECT_ALT_NAME: continue value = decoder.decode(extension.getComponentByName('extnValue'), asn1Spec=OctetString())[0] sa_names = decoder.decode(value, asn1Spec=SubjectAltName())[0] for name in sa_names: name_type = name.getName() if name_type == 'dNSName': results['DNS'].add(decode_str(name.getComponent())) if name_type == 'uniformResourceIdentifier': value = decode_str(name.getComponent()) if value.startswith('xmpp:'): results['URI'].add(value[5:]) elif name_type == 'otherName': name = name.getComponent() oid = name.getComponentByName('type-id') value = name.getComponentByName('value') if oid == XMPP_ADDR: value = decoder.decode(value, asn1Spec=UTF8String())[0] results['XMPPAddr'].add(decode_str(value)) elif oid == SRV_NAME: value = decoder.decode(value, asn1Spec=IA5String())[0] results['SRV'].add(decode_str(value)) return results
def _PopulateX509(self): with self._x509_init_lock: if self._x509 is None: url = ( 'https://www.googleapis.com/service_accounts/v1/metadata/x509/%s' % six.moves.urllib.parse.unquote_plus( self._credentials.service_account_email)) response = urlfetch.fetch(url=url, validate_certificate=True, method=urlfetch.GET) if response.status_code != 200: raise apiproxy_errors.ApplicationError( app_identity_service_pb.AppIdentityServiceError. UNKNOWN_ERROR, 'Unable to load X509 cert: %s Response code: %i, Content: %s' % (url, response.status_code, response.content)) message = 'dummy' _, signature = self._credentials.sign_blob(message) for signing_key, x509 in list( json.loads(response.content).items()): der = rsa.pem.load_pem(x509, 'CERTIFICATE') asn1_cert, _ = decoder.decode(der, asn1Spec=Certificate()) key_bitstring = ( asn1_cert['tbsCertificate']['subjectPublicKeyInfo'] ['subjectPublicKey']) key_bytearray = BitStringToByteString(key_bitstring) public_key = rsa.PublicKey.load_pkcs1(key_bytearray, 'DER') try: if rsa.pkcs1.verify(message, signature, public_key): self._x509 = x509 self._signing_key = signing_key return except rsa.pkcs1.VerificationError: pass raise apiproxy_errors.ApplicationError( app_identity_service_pb.AppIdentityServiceError. UNKNOWN_ERROR, 'Unable to find matching X509 cert for private key: %s' % url)
def _PopulateX509(self): with self.__x509_init_lock: if not self.__x509: url = ('https://www.googleapis.com/service_accounts/v1/metadata/x509/%s' % urllib.unquote_plus(self.__email_address)) resp = urlfetch.fetch( url=url, validate_certificate=True, method=urlfetch.GET) if resp.status_code != 200: raise apiproxy_errors.ApplicationError( app_identity_service_pb.AppIdentityServiceError.UNKNOWN_ERROR, 'Unable to load X509 cert: %s Response code: %i, Content: %s' % ( url, resp.status_code, resp.content)) msg = 'test' sig = rsa.pkcs1.sign(msg, self.__private_key, 'SHA-256') for signing_key, x509 in json.loads(resp.content).items(): der = rsa.pem.load_pem(x509, 'CERTIFICATE') asn1_cert, _ = decoder.decode(der, asn1Spec=Certificate()) key_bitstring = ( asn1_cert['tbsCertificate'] ['subjectPublicKeyInfo'] ['subjectPublicKey']) key_bytearray = BitStringToByteString(key_bitstring) pub = rsa.PublicKey.load_pkcs1(key_bytearray, 'DER') try: if rsa.pkcs1.verify(msg, sig, pub): self.__x509 = x509 self.__signing_key = signing_key return except rsa.pkcs1.VerificationError: pass raise apiproxy_errors.ApplicationError( app_identity_service_pb.AppIdentityServiceError.UNKNOWN_ERROR, 'Unable to find matching X509 cert for private key: %s' % url)
def from_der_data(cls, data): """Decode DER-encoded certificate. :Parameters: - `data`: the encoded certificate :Types: - `data`: `bytes` :Return: decoded certificate data :Returntype: ASN1CertificateData """ # pylint: disable=W0212 logger.debug("Decoding DER certificate: {0!r}".format(data)) if cls._cert_asn1_type is None: cls._cert_asn1_type = Certificate() cert = der_decoder.decode(data, asn1Spec=cls._cert_asn1_type)[0] result = cls() tbs_cert = cert.getComponentByName('tbsCertificate') subject = tbs_cert.getComponentByName('subject') logger.debug("Subject: {0!r}".format(subject)) result._decode_subject(subject) validity = tbs_cert.getComponentByName('validity') result._decode_validity(validity) extensions = tbs_cert.getComponentByName('extensions') if extensions: for extension in extensions: logger.debug("Extension: {0!r}".format(extension)) oid = extension.getComponentByName('extnID') logger.debug("OID: {0!r}".format(oid)) if oid != SUBJECT_ALT_NAME_OID: continue value = extension.getComponentByName('extnValue') logger.debug("Value: {0!r}".format(value)) if isinstance(value, Any): # should be OctetString, but is Any # in pyasn1_modules-0.0.1a value = der_decoder.decode(value, asn1Spec=OctetString())[0] alt_names = der_decoder.decode(value, asn1Spec=GeneralNames())[0] logger.debug("SubjectAltName: {0!r}".format(alt_names)) result._decode_alt_names(alt_names) return result
def extract_dates(raw_cert): cert = decoder.decode(raw_cert, asn1Spec=Certificate())[0] tbs = cert.getComponentByName('tbsCertificate') validity = tbs.getComponentByName('validity') not_before = validity.getComponentByName('notBefore') not_before = str(not_before.getComponent()) not_after = validity.getComponentByName('notAfter') not_after = str(not_after.getComponent()) if isinstance(not_before, GeneralizedTime): not_before = datetime.strptime(not_before, '%Y%m%d%H%M%SZ') else: not_before = datetime.strptime(not_before, '%y%m%d%H%M%SZ') if isinstance(not_after, GeneralizedTime): not_after = datetime.strptime(not_after, '%Y%m%d%H%M%SZ') else: not_after = datetime.strptime(not_after, '%y%m%d%H%M%SZ') return not_before, not_after
def slow_parse(self): self.cert = decoder.decode(str(self.bytes), asn1Spec=Certificate())[0] self.tbs = self.cert.getComponentByName('tbsCertificate') self.subject = self.tbs.getComponentByName('subject') self.extensions = self.tbs.getComponentByName('extensions') or []
''' \x30\x82\x01\xe1\xa0\x03\x02\x01\x02\x02\x14\x65\x09\x56\xd9\xc8\xd4\x04\xcd\x4c\x3f\xca\xd5\xff\x70\x46\x0b\xe4\x61\x64\x68\x30\x0a\x06\x08\x2a\x86\x48\xce\x3d\x04\x03\x02\x30\x68\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x17\x30\x15\x06\x03\x55\x04\x08\x13\x0e\x4e\x6f\x72\x74\x68\x20\x43\x61\x72\x6f\x6c\x69\x6e\x61\x31\x14\x30\x12\x06\x03\x55\x04\x0a\x13\x0b\x48\x79\x70\x65\x72\x6c\x65\x64\x67\x65\x72\x31\x0f\x30\x0d\x06\x03\x55\x04\x0b\x13\x06\x46\x61\x62\x72\x69\x63\x31\x19\x30\x17\x06\x03\x55\x04\x03\x13\x10\x66\x61\x62\x72\x69\x63\x2d\x63\x61\x2d\x73\x65\x72\x76\x65\x72\x30\x1e\x17\x0d\x32\x30\x30\x35\x31\x33\x31\x31\x32\x39\x30\x30\x5a\x17\x0d\x32\x31\x30\x35\x31\x33\x31\x31\x33\x34\x30\x30\x5a\x30\x5d\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x17\x30\x15\x06\x03\x55\x04\x08\x13\x0e\x4e\x6f\x72\x74\x68\x20\x43\x61\x72\x6f\x6c\x69\x6e\x61\x31\x14\x30\x12\x06\x03\x55\x04\x0a\x13\x0b\x48\x79\x70\x65\x72\x6c\x65\x64\x67\x65\x72\x31\x0f\x30\x0d\x06\x03\x55\x04\x0b\x13\x06\x63\x6c\x69\x65\x6e\x74\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x61\x64\x6d\x69\x6e\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x11\x63\x01\x77\x06\xce\x3f\x89\x12\x21\x2d\x59\x8c\x06\xe5\xd8\x98\x0f\x71\xc8\xef\x4b\xc2\xdb\x3e\xad\xcb\xd4\x1b\xd9\x90\xac\x47\x50\x90\xf4\x25\x8f\x7c\x59\x8b\x21\x81\xcf\xf7\xe1\x00\x92\x4f\x6a\xde\x60\x28\xb2\x66\xc1\xe5\x26\x33\x54\x6a\x5d\x0b\x1f\xa3\x74\x30\x72\x30\x0e\x06\x03\x55\x1d\x0f\x01\x01\xff\x04\x04\x03\x02\x07\x80\x30\x0c\x06\x03\x55\x1d\x13\x01\x01\xff\x04\x02\x30\x00\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x79\xb1\xa9\xd8\xc0\x7d\x4e\x64\xc2\xa1\x29\x81\x31\x8c\x88\xa3\xc5\x33\x25\x57\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\xf7\xc9\x1f\x77\xa6\x4a\x66\x90\xba\xa7\x01\x9a\x19\x95\x56\xcb\x24\xee\x16\x7b\x30\x12\x06\x03\x55\x1d\x11\x04\x0b\x30\x09\x82\x07\x6f\x6c\x79\x6d\x70\x75\x73 ''' from M2Crypto import X509, EC, EVP from hashlib import sha256 from pyasn1_modules.rfc2314 import Signature from pyasn1_modules.rfc2459 import Certificate from pyasn1.codec.der import encoder, decoder from base64 import * import binascii cert = X509.load_cert('cert.pem') #ca_pkey = EVP.load_key('rsa.private') asn1_cert = decoder.decode(cert.as_der(), asn1Spec=Certificate())[0] #tbs = asn1_cert.getComponentByName("tbsCertificate") #print(tbs) #tbs_der = encoder.encode(tbs) #print(cert.as_text()) #digest = sha256() #digest.update(tbs_der) #signature = ca_pkey.get_rsa().sign(digest.digest(), "sha256") #print(bin(signature)) #print(asn1_cert.getComponentByName("signatureValue"),'\n\n\n\n') #print(signature) #print(cert.as_text())