def cert_subj_key_id_offset_length(cert): cert_der = encoder.encode(cert) cert_mod = decoder.decode(cert_der, asn1Spec=rfc2459.Certificate())[0] for ext in cert_mod['tbsCertificate']['extensions']: if ext['extnID'] == rfc2459.id_ce_subjectKeyIdentifier: extn_value = decoder.decode(ext['extnValue'])[0] key_id = bytearray(decoder.decode(extn_value, asn1Spec=rfc2459.SubjectKeyIdentifier())[0]) key_id[0] ^= 0xFF # Change first byte extn_value = rfc2459.SubjectKeyIdentifier(key_id) ext['extnValue'] = univ.OctetString(encoder.encode(extn_value)) return {'offset':diff_offset(cert_der, encoder.encode(cert_mod)), 'length':len(key_id)} return None
def addSubjectKeyId(self, critical): if critical: raise UnknownSubjectKeyIdError(critical) hasher = hashlib.sha1() hasher.update(self.subjectKey.toDER()) digest = hasher.digest() ski = rfc2459.SubjectKeyIdentifier(univ.OctetString(digest)) self.addExtension(rfc2459.id_ce_subjectKeyIdentifier, ski, critical)
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)