def toDER(self): tbsCertificate = rfc2459.TBSCertificate() tbsCertificate.setComponentByName('version', self.getVersion()) tbsCertificate.setComponentByName('serialNumber', self.getSerialNumber()) tbsCertificate.setComponentByName('signature', self.getSignature()) tbsCertificate.setComponentByName('issuer', self.getIssuer()) tbsCertificate.setComponentByName('validity', self.getValidity()) tbsCertificate.setComponentByName('subject', self.getSubject()) tbsCertificate.setComponentByName( 'subjectPublicKeyInfo', self.subjectKey.asSubjectPublicKeyInfo()) if self.extensions: extensions = rfc2459.Extensions().subtype(explicitTag=tag.Tag( tag.tagClassContext, tag.tagFormatSimple, 3)) count = 0 for extension in self.extensions: extensions.setComponentByPosition(count, extension) count += 1 tbsCertificate.setComponentByName('extensions', extensions) certificate = rfc2459.Certificate() certificate.setComponentByName('tbsCertificate', tbsCertificate) certificate.setComponentByName('signatureAlgorithm', self.getSignatureAlgorithm()) tbsDER = encoder.encode(tbsCertificate) certificate.setComponentByName('signatureValue', self.issuerKey.sign(tbsDER)) return encoder.encode(certificate)
def toDER(self): tbsCertificate = rfc2459.TBSCertificate() tbsCertificate.setComponentByName('version', self.getVersion()) tbsCertificate.setComponentByName('serialNumber', self.getSerialNumber()) tbsCertificate.setComponentByName('signature', self.getSignature()) tbsCertificate.setComponentByName('issuer', self.getIssuer()) tbsCertificate.setComponentByName('validity', self.getValidity()) tbsCertificate.setComponentByName('subject', self.getSubject()) tbsCertificate.setComponentByName('subjectPublicKeyInfo', self.getSubjectPublicKeyInfo()) if self.extensions: extensions = rfc2459.Extensions().subtype(explicitTag=tag.Tag( tag.tagClassContext, tag.tagFormatSimple, 3)) count = 0 for extension in self.extensions: extensions.setComponentByPosition(count, extension) count += 1 tbsCertificate.setComponentByName('extensions', extensions) tbsDER = encoder.encode(tbsCertificate) rsaPrivateKey = rsa.PrivateKey(self.sharedRSA_N, self.sharedRSA_E, self.sharedRSA_D, self.sharedRSA_P, self.sharedRSA_Q) signature = rsa.sign(tbsDER, rsaPrivateKey, 'SHA-256') certificate = rfc2459.Certificate() certificate.setComponentByName('tbsCertificate', tbsCertificate) certificate.setComponentByName('signatureAlgorithm', self.getSignatureAlgorithm()) certificate.setComponentByName( 'signatureValue', byteStringToHexifiedBitString(signature)) return encoder.encode(certificate)
def __get_pyasn1_field(self, field): """ :returns: a field of the certificate in pyasn1 representation """ cert_bytes = self.tbs_certificate_bytes cert = decoder.decode(cert_bytes, rfc2459.TBSCertificate())[0] field = cert[field] return field
def get_san_general_names(cert): """ Return SAN general names from a python-cryptography certificate object. If the SAN extension is not present, return an empty sequence. Because python-cryptography does not yet provide a way to handle unrecognised critical extensions (which may occur), we must parse the certificate and extract the General Names. For uniformity with other code, we manually construct values of python-crytography GeneralName subtypes. python-cryptography does not yet provide types for ediPartyName or x400Address, so we drop these name types. otherNames are NOT instantiated to more specific types where the type is known. Use ``process_othernames`` to do that. When python-cryptography can handle certs with unrecognised critical extensions and implements ediPartyName and x400Address, this function (and helpers) will be redundant and should go away. """ tbs = decoder.decode( cert.tbs_certificate_bytes, asn1Spec=rfc2459.TBSCertificate() )[0] OID_SAN = univ.ObjectIdentifier('2.5.29.17') gns = [] for ext in tbs['extensions']: if ext['extnID'] == OID_SAN: der = decoder.decode( ext['extnValue'], asn1Spec=univ.OctetString())[0] gns = decoder.decode(der, asn1Spec=rfc2459.SubjectAltName())[0] break GENERAL_NAME_CONSTRUCTORS = { 'rfc822Name': lambda x: cryptography.x509.RFC822Name(unicode(x)), 'dNSName': lambda x: cryptography.x509.DNSName(unicode(x)), 'directoryName': _pyasn1_to_cryptography_directoryname, 'registeredID': _pyasn1_to_cryptography_registeredid, 'iPAddress': _pyasn1_to_cryptography_ipaddress, 'uniformResourceIdentifier': lambda x: cryptography.x509.UniformResourceIdentifier(unicode(x)), 'otherName': _pyasn1_to_cryptography_othername, } result = [] for gn in gns: gn_type = gn.getName() if gn_type in GENERAL_NAME_CONSTRUCTORS: result.append( GENERAL_NAME_CONSTRUCTORS[gn_type](gn.getComponent())) return result
def _pyasn1_get_san_general_names(cert): tbs = decoder.decode(cert.tbs_certificate_bytes, asn1Spec=rfc2459.TBSCertificate())[0] OID_SAN = univ.ObjectIdentifier('2.5.29.17') # One would expect KeyError or empty iterable when the key ('extensions' # in this particular case) is not pressent in the certificate but pyasn1 # returns None here extensions = tbs['extensions'] or [] gns = [] for ext in extensions: if ext['extnID'] == OID_SAN: der = decoder.decode(ext['extnValue'], asn1Spec=univ.OctetString())[0] gns = decoder.decode(der, asn1Spec=rfc2459.SubjectAltName())[0] break return gns
def verify(buffer: bytes, verification_key: object) -> bool: if buffer.startswith(b'----'): buffer = pem_decode(buffer) # Decode the full cert and get the encoded TBSCertificate cert, _left_over = decoder.decode(buffer, asn1Spec=rfc2459.Certificate()) sig_value = cert['signatureValue'] signature_alg = INVERSE_SIGNING_ALG_OIDS[str( cert['signatureAlgorithm']['algorithm'])].replace('-', '_') tbs_cert = cert['tbsCertificate'] encoded_tbs = encoder.encode(tbs_cert, asn1Spec=rfc2459.TBSCertificate()) alg = verification_key.X509_SIGNING_ALGORITHMS[signature_alg].value return alg.verify(verification_key, encoded_tbs, sig_value)
def getTBSCertificate(self): (signatureOID, _) = stringToAlgorithmIdentifiers(self.signature) tbsCertificate = rfc2459.TBSCertificate() tbsCertificate['version'] = self.getVersion() tbsCertificate['serialNumber'] = self.getSerialNumber() tbsCertificate['signature'] = signatureOID tbsCertificate['issuer'] = self.getIssuer() tbsCertificate['validity'] = self.getValidity() tbsCertificate['subject'] = self.getSubject() tbsCertificate['subjectPublicKeyInfo'] = self.subjectKey.asSubjectPublicKeyInfo() if self.extensions: extensions = rfc2459.Extensions().subtype( explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)) for count, extension in enumerate(self.extensions): extensions.setComponentByPosition(count, extension) tbsCertificate['extensions'] = extensions return tbsCertificate
def _build_tbs(csr, days, network): cri = csr.getComponentByName('certificationRequestInfo') subject = cri.getComponentByName('subject') subjectPublicKeyInfo = cri.getComponentByName('subjectPublicKeyInfo') dt_now = datetime.datetime.utcnow() later = datetime.timedelta(days=days) dt_now_str = dt_now.strftime("%y%m%d%H%M%S") + "Z" later_str = (dt_now + later).strftime("%y%m%d%H%M%S") + "Z" notbefore = useful.UTCTime(dt_now_str) notafter = useful.UTCTime(later_str) validity = rfc2459.Validity() validity.setComponentByName('notBefore', notbefore) validity.setComponentByName('notAfter', notafter) tbs = rfc2459.TBSCertificate() tbs.setComponentByName( 'version', rfc2459.Version('v3').subtype( explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) rndfile = Random.new() serial = encoding.to_long(256, encoding.byte_to_int, rndfile.read(32))[0] tbs.setComponentByName( 'serialNumber', rfc2459.CertificateSerialNumber(univ.Integer(serial))) tbs.setComponentByName('signature', csr.getComponentByName('signatureAlgorithm')) tbs.setComponentByName('issuer', subject) tbs.setComponentByName('validity', validity) tbs.setComponentByName('subject', subject) tbs.setComponentByName('subjectPublicKeyInfo', subjectPublicKeyInfo) extensionstoadd = "" attributes = cri.getComponentByName('attributes') for attribute in attributes: if (attribute.getComponentByName('type') == utility.OID_PKCShash9ExtensionRequest): value = attribute[1] ## careful with decoder, it returns an implicit type in a tuple extensionstoadd = decoder.decode(value[0])[0] spk = subjectPublicKeyInfo.getComponentByName('subjectPublicKey') ## self siiiigned extensions = _build_extensionsForTbs(extensionstoadd, akipubkeybitstring=spk, skipubkeybitstring=spk) if extensions: tbs.setComponentByName('extensions', extensions) return tbs
def encode(cls, pki_key: object, **kwargs): # Algorithm ID alg_oid = cls.ALG_OID if type( cls.ALG_OID) is str else cls.ALG_OID(pki_key) alg_id = rfc2459.AlgorithmIdentifier() alg_id['algorithm'] = ObjectIdentifier(alg_oid) if cls.PARAM_ENCODER: alg_id['parameters'] = Any( encoder.encode(cls.PARAM_ENCODER.encode(pki_key))) # Serial number serial_num = rfc2459.CertificateSerialNumber( kwargs.get('serial_number') or 0) # Validity (time valid) not_before = kwargs.get('not_before') or datetime.now() not_after = kwargs.get('not_after') or not_before.replace( year=not_before.year + 1) validity = rfc2459.Validity() validity['notBefore'] = rfc2459.Time() validity['notBefore']['utcTime'] = UTCTime.fromDateTime(not_before) validity['notAfter'] = rfc2459.Time() validity['notAfter']['utcTime'] = UTCTime.fromDateTime(not_after) # Public key serialization pub_info = rfc2459.SubjectPublicKeyInfo() pub_info['algorithm'] = alg_id pub_info['subjectPublicKey'] = cls.PUB_KEY_ENCODER.encode(pki_key) # Issuer RDN issuer = rfc2459.Name() issuer.setComponentByPosition( 0, parse_rdn(kwargs.get('issuer') or 'CN=ca')) # Subject RDN subject = rfc2459.Name() subject.setComponentByPosition( 0, parse_rdn(kwargs.get('subject') or 'CN=ca')) # Signature algorithm signing_key = kwargs.get('signing_key') or pki_key if not (kwargs.get('signing_alg') or hasattr(signing_key, "X509_SIGNING_DEFAULT")): raise ValueError( "'signing_alg' not specified and 'signing_key' has no default algorithm" ) signing_alg = (kwargs.get('signing_alg') or signing_key.X509_SIGNING_DEFAULT).value signature_alg = rfc2459.AlgorithmIdentifier() signature_alg['algorithm'] = SIGNING_ALG_OIDS[signing_alg.name] if cls.PARAM_ENCODER: signature_alg['parameters'] = Any( encoder.encode(cls.PARAM_ENCODER.encode(pki_key))) # Extensions extensions = rfc2459.Extensions().subtype( explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)) if kwargs.get('ca') and kwargs.get('ca') == True: # SKI pkey_bytes = Bytes(int(pub_info['subjectPublicKey'])) ski_ext = rfc2459.Extension() ski_ext['extnID'] = ObjectIdentifier([2, 5, 29, 14]) ski_ext['extnValue'] = OctetString( encoder.encode( rfc2459.SubjectKeyIdentifier(SHA1().hash(pkey_bytes)))) # CA basic constraint ca_value = rfc2459.BasicConstraints() ca_value.setComponentByName('cA', True) ca_ext = rfc2459.Extension() ca_ext.setComponentByName('extnID', '2.5.29.19') ca_ext.setComponentByName('critical', True) ca_ext.setComponentByName('extnValue', OctetString(encoder.encode(ca_value))) extensions.setComponentByPosition(0, ski_ext) extensions.setComponentByPosition(1, ca_ext) # Put together the TBSCert tbs_cert = rfc2459.TBSCertificate() tbs_cert['version'] = 2 tbs_cert['serialNumber'] = serial_num tbs_cert['signature'] = signature_alg tbs_cert['issuer'] = issuer tbs_cert['validity'] = validity tbs_cert['subject'] = subject tbs_cert['subjectPublicKeyInfo'] = pub_info tbs_cert['issuerUniqueID'] = kwargs.get('issuer_unique_id') or 10 tbs_cert['subjectUniqueID'] = kwargs.get('subject_unique_id') or 11 if len(extensions): tbs_cert['extensions'] = extensions # Inject or compute the TBSCert signature if kwargs.get('signature_value') is not None: sig_value = Bytes.wrap(kwargs.get('signature_value')).int() else: encoded_tbs = encoder.encode(tbs_cert, asn1Spec=rfc2459.TBSCertificate()) sig_value = signing_alg.sign(signing_key, encoded_tbs) # Build the Cert object cert = rfc2459.Certificate() cert['tbsCertificate'] = tbs_cert cert['signatureAlgorithm'] = signature_alg cert['signatureValue'] = sig_value encoded = encoder.encode(cert, asn1Spec=rfc2459.Certificate()) return X509Certificate.transport_encode(encoded, **kwargs)
def __init__(self, certificate=None): if certificate is None: self._cert = rfc2459.Certificate() self._cert['tbsCertificate'] = rfc2459.TBSCertificate() else: self._cert = certificate
def to_asn1(self): extension_list = [extension.to_asn1() for extension in self] extensions_asn1 = rfc2459.TBSCertificate()["extensions"] extensions_asn1.setComponents(*extension_list) return extensions_asn1