Esempio n. 1
0
def MakeOCSPResponse(issuer_cn, issuer_key, serial, revoked):
    # https://tools.ietf.org/html/rfc2560
    issuer_name_hash = asn1.OCTETSTRING(
        hashlib.sha1(asn1.ToDER(Name(cn=issuer_cn))).digest())

    issuer_key_hash = asn1.OCTETSTRING(
        hashlib.sha1(asn1.ToDER(issuer_key)).digest())

    cert_status = None
    if revoked:
        cert_status = asn1.Explicit(1, asn1.GeneralizedTime("20100101060000Z"))
    else:
        cert_status = asn1.Raw(asn1.TagAndLength(0x80 | 0, 0))

    basic_resp_data_der = asn1.ToDER(
        asn1.SEQUENCE([
            asn1.Explicit(2, issuer_key_hash),
            asn1.GeneralizedTime("20100101060000Z"),  # producedAt
            asn1.SEQUENCE([
                asn1.SEQUENCE([  # SingleResponse
                    asn1.SEQUENCE([  # CertID
                        asn1.SEQUENCE([  # hashAlgorithm
                            HASH_SHA1,
                            None,
                        ]),
                        issuer_name_hash,
                        issuer_key_hash,
                        serial,
                    ]),
                    cert_status,
                    asn1.GeneralizedTime("20100101060000Z"),  # thisUpdate
                    asn1.Explicit(
                        0,
                        asn1.GeneralizedTime("20300101060000Z")),  # nextUpdate
                ]),
            ]),
        ]))

    basic_resp = asn1.SEQUENCE([
        asn1.Raw(basic_resp_data_der),
        asn1.SEQUENCE([
            SHA1_WITH_RSA_ENCRYPTION,
            None,
        ]),
        asn1.BitString(issuer_key.Sign(basic_resp_data_der)),
    ])

    resp = asn1.SEQUENCE([
        asn1.ENUMERATED(0),
        asn1.Explicit(
            0,
            asn1.SEQUENCE([
                OCSP_TYPE_BASIC,
                asn1.OCTETSTRING(asn1.ToDER(basic_resp)),
            ]))
    ])

    return asn1.ToDER(resp)
Esempio n. 2
0
def MakeOCSPSingleResponse(issuer_name_hash, issuer_key_hash, serial,
                           ocsp_state, ocsp_date):
    cert_status = None
    if ocsp_state == OCSP_STATE_REVOKED:
        cert_status = asn1.Explicit(1, asn1.GeneralizedTime("20100101060000Z"))
    elif ocsp_state == OCSP_STATE_UNKNOWN:
        cert_status = asn1.Raw(asn1.TagAndLength(0x80 | 2, 0))
    elif ocsp_state == OCSP_STATE_GOOD:
        cert_status = asn1.Raw(asn1.TagAndLength(0x80 | 0, 0))
    elif ocsp_state == OCSP_STATE_MISMATCHED_SERIAL:
        cert_status = asn1.Raw(asn1.TagAndLength(0x80 | 0, 0))
        serial -= 1
    else:
        raise ValueError('Bad OCSP state: ' + str(ocsp_state))

    now = datetime.datetime.fromtimestamp(time.mktime(time.gmtime()))
    if ocsp_date == OCSP_DATE_VALID:
        thisUpdate = now - datetime.timedelta(days=1)
        nextUpdate = thisUpdate + datetime.timedelta(weeks=1)
    elif ocsp_date == OCSP_DATE_OLD:
        thisUpdate = now - datetime.timedelta(days=1, weeks=1)
        nextUpdate = thisUpdate + datetime.timedelta(weeks=1)
    elif ocsp_date == OCSP_DATE_EARLY:
        thisUpdate = now + datetime.timedelta(days=1)
        nextUpdate = thisUpdate + datetime.timedelta(weeks=1)
    elif ocsp_date == OCSP_DATE_LONG:
        thisUpdate = now - datetime.timedelta(days=365)
        nextUpdate = thisUpdate + datetime.timedelta(days=366)
    elif ocsp_date == OCSP_DATE_LONGER:
        thisUpdate = now - datetime.timedelta(days=367)
        nextUpdate = thisUpdate + datetime.timedelta(days=368)
    else:
        raise ValueError('Bad OCSP date: ' + str(ocsp_date))

    return asn1.SEQUENCE([  # SingleResponse
        asn1.SEQUENCE([  # CertID
            asn1.SEQUENCE([  # hashAlgorithm
                HASH_SHA1,
                None,
            ]),
            issuer_name_hash,
            issuer_key_hash,
            serial,
        ]),
        cert_status,
        asn1.GeneralizedTime(  # thisUpdate
            thisUpdate.strftime(GENERALIZED_TIME_FORMAT)),
        asn1.Explicit(  # nextUpdate
            0,
            asn1.GeneralizedTime(
                nextUpdate.strftime(GENERALIZED_TIME_FORMAT))),
    ])
Esempio n. 3
0
def MakeOCSPResponse(issuer_cn, issuer_key, serial, ocsp_states, ocsp_dates,
                     ocsp_produced):
    # https://tools.ietf.org/html/rfc2560
    issuer_name_hash = asn1.OCTETSTRING(
        hashlib.sha1(asn1.ToDER(Name(cn=issuer_cn))).digest())

    issuer_key_hash = asn1.OCTETSTRING(
        hashlib.sha1(asn1.ToDER(issuer_key)).digest())

    now = datetime.datetime.fromtimestamp(time.mktime(time.gmtime()))
    if ocsp_produced == OCSP_PRODUCED_VALID:
        producedAt = now - datetime.timedelta(days=1)
    elif ocsp_produced == OCSP_PRODUCED_BEFORE_CERT:
        producedAt = datetime.datetime.strptime("19100101050000Z",
                                                GENERALIZED_TIME_FORMAT)
    elif ocsp_produced == OCSP_PRODUCED_AFTER_CERT:
        producedAt = datetime.datetime.strptime("20321201070000Z",
                                                GENERALIZED_TIME_FORMAT)
    else:
        raise ValueError('Bad OCSP produced: ' + str(ocsp_produced))

    single_responses = [
        MakeOCSPSingleResponse(issuer_name_hash, issuer_key_hash, serial,
                               ocsp_state, ocsp_date)
        for ocsp_state, ocsp_date in itertools.izip(ocsp_states, ocsp_dates)
    ]

    basic_resp_data_der = asn1.ToDER(
        asn1.SEQUENCE([
            asn1.Explicit(2, issuer_key_hash),
            asn1.GeneralizedTime(producedAt.strftime(GENERALIZED_TIME_FORMAT)),
            asn1.SEQUENCE(single_responses),
        ]))

    basic_resp = asn1.SEQUENCE([
        asn1.Raw(basic_resp_data_der),
        asn1.SEQUENCE([
            SHA256_WITH_RSA_ENCRYPTION,
            None,
        ]),
        asn1.BitString(issuer_key.Sign(basic_resp_data_der)),
    ])

    resp = asn1.SEQUENCE([
        asn1.ENUMERATED(0),
        asn1.Explicit(
            0,
            asn1.SEQUENCE([
                OCSP_TYPE_BASIC,
                asn1.OCTETSTRING(asn1.ToDER(basic_resp)),
            ]))
    ])

    return asn1.ToDER(resp)