Пример #1
0
class CertID(univ.Sequence):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('hashAlgorithm', rfc2459.AlgorithmIdentifier()),
        namedtype.NamedType('issuerNameHash', univ.OctetString()),
        namedtype.NamedType('issuerKeyHash', univ.OctetString()),
        namedtype.NamedType('serialNumber', rfc2459.CertificateSerialNumber())
    )
Пример #2
0
class TBSCertificate(univ.Sequence):
    componentType = namedtype.NamedTypes(
        namedtype.DefaultedNamedType('version', rfc2459.Version('v1', tagSet=rfc2459.Version.tagSet.tagExplicitly(tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)))),
        namedtype.NamedType('serialNumber', rfc2459.CertificateSerialNumber()),
        namedtype.NamedType('signature', AlgorithmIdentifier()),
        namedtype.NamedType('issuer', rfc2459.Name()),
        namedtype.NamedType('validity', rfc2459.Validity()),
        namedtype.NamedType('subject', rfc2459.Name()),
        namedtype.NamedType('subjectPublicKeyInfo', SubjectPublicKeyInfo()),
        namedtype.OptionalNamedType('issuerUniqueID', rfc2459.UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
        namedtype.OptionalNamedType('subjectUniqueID', rfc2459.UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))),
        namedtype.OptionalNamedType('extensions', rfc2459.Extensions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)))
        )
Пример #3
0
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 is_cert_id_in_cache(ocsp_issuer, ocsp_subject, use_cache=True):
    u"""
    checks if cert_id is in the cache
    """
    logger = getLogger(__name__)
    cert_id = CertID()
    cert_id['hashAlgorithm'] = rfc2459.AlgorithmIdentifier(
    ).setComponentByName('algorithm',
                         ocsp_issuer[u'algorithm']).setComponentByName(
                             'parameters', ocsp_issuer[u'algorithm_parameter'])
    cert_id['issuerNameHash'] = univ.OctetString(
        hexValue=ocsp_issuer[u'name_hash'])
    cert_id['issuerKeyHash'] = univ.OctetString(
        hexValue=ocsp_issuer[u'key_hash'])
    cert_id['serialNumber'] = rfc2459.CertificateSerialNumber(
        ocsp_subject[u'serial_number'])

    cert_id_der = der_encoder.encode(cert_id)

    if logger.getEffectiveLevel() == logging.DEBUG:
        base64_issuer_name_hash = base64.b64encode(
            octet_string_to_bytearray(cert_id['issuerNameHash']))
    else:
        base64_issuer_name_hash = None

    with OCSP_VALIDATION_CACHE_LOCK:
        if use_cache and cert_id_der in OCSP_VALIDATION_CACHE:
            current_time = int(time.time())
            ts, cache = OCSP_VALIDATION_CACHE[cert_id_der]
            if ts - CACHE_EXPIRATION <= current_time <= ts + CACHE_EXPIRATION:
                # cache value is OCSP response
                logger.debug(u'hit cache: %s', base64_issuer_name_hash)
                return True, cert_id, cache
            else:
                # more than 24 hours difference
                del OCSP_VALIDATION_CACHE[cert_id_der]

    logger.debug(u'not hit cache: %s', base64_issuer_name_hash)
    return False, cert_id, None
Пример #5
0
    def addAuthorityKeyId(self, akiTypes, critical):
        types = [st.strip() for st in akiTypes.split(',')]

        noneSpecified = 0 == len(akiTypes.strip())

        if critical:
            raise UnknownAuthorityKeyIdError(critical)
        hasher = hashlib.sha1()
        hasher.update(self.issuerKey.toDER())
        akiKi = rfc2459.KeyIdentifier().subtype(implicitTag=tag.Tag(
            tag.tagClassContext, tag.tagFormatSimple, 0),
                                                value=hasher.digest())
        aki = rfc2459.AuthorityKeyIdentifier()

        # If the issuerSerialNumber is set, we can add AKI data for Issuer principal and the issuer serial number
        if None != self.issuerSerialNumber:
            issuerName = rfc2459.GeneralNames().subtype(implicitTag=tag.Tag(
                tag.tagClassContext, tag.tagFormatSimple, 1))
            generalName = stringToDN(
                self.issuer,
                tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
            issuerName.setComponentByPosition(0, generalName)
            csn = rfc2459.CertificateSerialNumber().subtype(
                implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple,
                                    2),
                value=decoder.decode(self.issuerSerialNumber)[0])
            if noneSpecified or 'ki' in types:
                aki.setComponentByPosition(0, akiKi)
            if noneSpecified or 'issuer' in types:
                aki.setComponentByPosition(1, issuerName)
            if noneSpecified or 'serialNumber' in types:
                aki.setComponentByPosition(2, csn)
        else:
            if noneSpecified or 'ki' in types:
                aki.setComponentByPosition(0, akiKi)
        self.addExtension(rfc2459.id_ce_authorityKeyIdentifier, aki, critical)
Пример #6
0
    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)
Пример #7
0
            explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))
        request = Request()
        certid = CertID()
        request['reqCert'] = certid
        certid['hashAlgorithm'] = rfc2459.AlgorithmIdentifier()\
                .setComponentByName('algorithm', rfc2437.id_sha1)\
                # .setComponentByName('parameters', univ.Any(hexValue='0500'))

        # certid['issuerNameHash'] = univ.OctetString(hexValue='01cb3044531fa8618a68d3c60596ab0555866b09')
        certid['issuerNameHash'] = univ.OctetString(
            hexValue='54e857e287d993fb6c0001fa3739b6e35c0e2c21')
        # certid['issuerKeyHash'] = univ.OctetString(hexValue='31c3791bbaf553d717e0897a2d176c0ab32b9d33')
        certid['issuerKeyHash'] = univ.OctetString(
            hexValue='1819c3646d8a358624911ee83dd5a78e509d555d')

        certid['serialNumber'] = rfc2459.CertificateSerialNumber(10000616)
        encoder.encode(certid['serialNumber'])
        req['tbsRequest']['requestList'] = univ.SequenceOf(
            componentType=Request()).setComponentByPosition(0, request)
        # reqExts = rfc2459.Extensions().subtype(
        #         explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))
        # reqExt = rfc2459.Extension()
        # reqExt['extnID'] = univ.ObjectIdentifier('1.3.6.1.5.5.7.48.1.2')
        # reqExt['critical'] = univ.Boolean('False')
        # reqExt['extnValue'] = univ.Any(hexValue='04120410236e5193af7958f49edcc756ed6c6dd3')
        # reqExts[0] = reqExt
        # req['tbsRequest']['requestExtensions'] = reqExts
        print(req.prettyPrint())

        print(encoder.encode(req))
    else:
Пример #8
0
def is_cert_id_in_cache(ocsp_issuer, ocsp_subject, use_cache=True):
    u"""
    checks if cert_id is in the cache
    """
    global SF_OCSP_RESPONSE_CACHE_SERVER_ENABLED
    global SF_OCSP_RESPONSE_CACHE_SERVER_URL
    global OCSP_VALIDATION_CACHE_UPDATED

    logger = getLogger(__name__)
    cert_id = CertID()
    cert_id['hashAlgorithm'] = rfc2459.AlgorithmIdentifier(
    ).setComponentByName('algorithm',
                         ocsp_issuer[u'algorithm']).setComponentByName(
                             'parameters', ocsp_issuer[u'algorithm_parameter'])
    cert_id['issuerNameHash'] = univ.OctetString(
        hexValue=ocsp_issuer[u'name_hash'])
    cert_id['issuerKeyHash'] = univ.OctetString(
        hexValue=ocsp_issuer[u'key_hash'])
    cert_id['serialNumber'] = rfc2459.CertificateSerialNumber(
        ocsp_subject[u'serial_number'])

    if logger.getEffectiveLevel() == logging.DEBUG:
        base64_name_hash = b64encode(
            octet_string_to_bytearray(cert_id['issuerNameHash']))
    else:
        base64_name_hash = None

    with OCSP_VALIDATION_CACHE_LOCK:
        current_time = int(time.time())
        for idx in range(2):
            hkey = _decode_cert_id_key(cert_id)
            if use_cache and hkey in OCSP_VALIDATION_CACHE:
                ts, cache = OCSP_VALIDATION_CACHE[hkey]
                if ts - CACHE_EXPIRATION <= current_time <= ts + CACHE_EXPIRATION:
                    # cache value is OCSP response
                    logger.debug(
                        u'hit cache. issuer name: %s, is '
                        u'subject root: %s', ocsp_issuer['name'],
                        ocsp_issuer[u'is_root_ca'])
                    return True, cert_id, cache
                else:
                    # more than 24 hours difference
                    del OCSP_VALIDATION_CACHE[hkey]
                    OCSP_VALIDATION_CACHE_UPDATED = True

            if idx == 1:
                # No second attempt to download the OCSP response cache.
                break
            # download OCSP response cache once
            if SF_OCSP_RESPONSE_CACHE_SERVER_ENABLED:
                downloaded_cache = download_ocsp_response_cache(
                    SF_OCSP_RESPONSE_CACHE_SERVER_URL)
                logger.debug('downloaded OCSP response cache file from %s',
                             SF_OCSP_RESPONSE_CACHE_SERVER_URL)
                for hkey, (ts, cache) in downloaded_cache.items():
                    if ts - CACHE_EXPIRATION <= current_time <= ts + CACHE_EXPIRATION:
                        OCSP_VALIDATION_CACHE[hkey] = ts, cache
                        OCSP_VALIDATION_CACHE_UPDATED = True
            else:
                logger.debug("OCSP response cache service is not enabled. Set "
                             "the environment variable "
                             "SF_OCSP_RESPONSE_CACHE_SERVER_ENABLED=true to "
                             "enable it.")

    if logger.getEffectiveLevel() == logging.DEBUG:
        logger.debug(
            u'not hit cache. issuer name hash: %s, issuer name: %s, is subject '
            u'root: %s, issuer name hash algorithm: %s, '
            u'issuer key hash: %s, subject serial number: %s',
            base64_name_hash, ocsp_issuer['name'], ocsp_issuer[u'is_root_ca'],
            cert_id['hashAlgorithm'],
            b64encode(octet_string_to_bytearray(cert_id['issuerKeyHash'])),
            cert_id['serialNumber'])

    return False, cert_id, None
Пример #9
0
def build_payload():
    # initializations
    tbsReq = TBSRequest()
    certid = CertID()
    request = Request()
    requestList = univ.SequenceOf(componentType=Request())
    req = OCSPRequest()
    reqExts = rfc2459.Extensions().subtype(
            explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))
    reqExt = rfc2459.Extension()
    signature = Signature()
    certs = univ.SequenceOf(componentType=rfc2459.Certificate()).subtype(
                    explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)
                    )
    cert = rfc2459.Certificate()
    name = rfc2459.GeneralName()


    # assignments
    certid['hashAlgorithm'] = rfc2459.AlgorithmIdentifier()\
            .setComponentByName('algorithm', ALGORITHM)\
            .setComponentByName('parameters', univ.Any(hexValue=ALGO_PARAMS_HEX))

    certid['issuerNameHash'] = univ.OctetString(hexValue=ISSUER_NAME_HASH)
    certid['issuerKeyHash'] = univ.OctetString(hexValue=ISSUER_KEY_HASH)
    certid['serialNumber'] = rfc2459.CertificateSerialNumber(SERIAL_NUMBER)

    request['reqCert'] = certid

    # optional field
    #request['singleRequestExtension'] = reqExt

    reqExt['extnID'] = univ.ObjectIdentifier('1.3.6.1.5.5.7.48.1.2')
    reqExt['critical'] = univ.Boolean('False')
    reqExt['extnValue'] = univ.Any(hexValue='04120410236e5193af7958f49edcc756ed6c6dd3')

    reqExts[0] = reqExt
    requestList[0] = request

    # optional
    # TODO: fill name?
    #tbsReq['requestorName'] = name
    tbsReq['requestList'] = requestList

    # optional 
    tbsReq['requestExtensions'] = reqExts
    tbsReq['version'] = Version(0).subtype(
            explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))

    # optional
    # TODO fill cert?
    signature['signatureAlgorithm'] = rfc2459.AlgorithmIdentifier()\
            .setComponentByName('algorithm', rfc2437.sha1WithRSAEncryption)
    signature['signature'] = univ.BitString("'010101010101'B")
    certs[0] = cert
    signature['certs'] = certs

    req['tbsRequest'] = tbsReq
    # optional signature
    #req['optionalSignature'] = signature

    return req