Commit 0770c882 authored by Todd Short's avatar Todd Short Committed by Matt Caswell
Browse files

Modify OCSP to use alt MD for cert IDs in responses



Modify openssl OCSP utility to produce certIDs in responses using other
hash algorithms (e.g. SHA256).

Added option -rcid for this purpose.

Reviewed-by: default avatarBen Kaduk <kaduk@mit.edu>
Reviewed-by: default avatarMatt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/5274)
parent 64f4fff7
Loading
Loading
Loading
Loading
+27 −7
Original line number Diff line number Diff line
@@ -99,7 +99,8 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req
                              EVP_PKEY *rkey, const EVP_MD *md,
                              STACK_OF(OPENSSL_STRING) *sigopts,
                              STACK_OF(X509) *rother, unsigned long flags,
                              int nmin, int ndays, int badsig);
                              int nmin, int ndays, int badsig,
                              const EVP_MD *resp_md);

static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
static BIO *init_responder(const char *port);
@@ -138,6 +139,7 @@ typedef enum OPTION_choice {
    OPT_RESPOUT, OPT_PATH, OPT_ISSUER, OPT_CERT, OPT_SERIAL,
    OPT_INDEX, OPT_CA, OPT_NMIN, OPT_REQUEST, OPT_NDAYS, OPT_RSIGNER,
    OPT_RKEY, OPT_ROTHER, OPT_RMD, OPT_RSIGOPT, OPT_HEADER,
    OPT_RCID,
    OPT_V_ENUM,
    OPT_MD,
    OPT_MULTI
@@ -220,6 +222,7 @@ const OPTIONS ocsp_options[] = {
    {"rmd", OPT_RMD, 's', "Digest Algorithm to use in signature of OCSP response"},
    {"rsigopt", OPT_RSIGOPT, 's', "OCSP response signature parameter in n:v form"},
    {"header", OPT_HEADER, 's', "key=value header to add"},
    {"rcid", OPT_RCID, 's', "Use specified algorithm for cert id in response"},
    {"", OPT_MD, '-', "Any supported digest algorithm (sha1,sha256, ... )"},
    OPT_V_OPTIONS,
    {NULL}
@@ -243,6 +246,7 @@ int ocsp_main(int argc, char **argv)
    STACK_OF(X509) *issuers = NULL;
    X509 *issuer = NULL, *cert = NULL;
    STACK_OF(X509) *rca_cert = NULL;
    const EVP_MD *resp_certid_md = NULL;
    X509 *signer = NULL, *rsigner = NULL;
    X509_STORE *store = NULL;
    X509_VERIFY_PARAM *vpm = NULL;
@@ -499,6 +503,11 @@ int ocsp_main(int argc, char **argv)
            if (!X509V3_add_value(header, value, &headers))
                goto end;
            break;
        case OPT_RCID:
            resp_certid_md = EVP_get_digestbyname(opt_arg());
            if (resp_certid_md == NULL)
                goto opthelp;
            break;
        case OPT_MD:
            if (trailing_md) {
                BIO_printf(bio_err,
@@ -684,7 +693,8 @@ redo_accept:

    if (rdb != NULL) {
        make_ocsp_response(bio_err, &resp, req, rdb, rca_cert, rsigner, rkey,
                               rsign_md, rsign_sigopts, rother, rflags, nmin, ndays, badsig);
                           rsign_md, rsign_sigopts, rother, rflags, nmin, ndays, badsig,
                           resp_certid_md);
        if (cbio != NULL)
            send_ocsp_response(cbio, resp);
    } else if (host != NULL) {
@@ -1138,7 +1148,8 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req
                              EVP_PKEY *rkey, const EVP_MD *rmd,
                              STACK_OF(OPENSSL_STRING) *sigopts,
                              STACK_OF(X509) *rother, unsigned long flags,
                              int nmin, int ndays, int badsig)
                              int nmin, int ndays, int badsig,
                              const EVP_MD *resp_md)
{
    ASN1_TIME *thisupd = NULL, *nextupd = NULL;
    OCSP_CERTID *cid;
@@ -1169,6 +1180,8 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req
        int found = 0;
        ASN1_OBJECT *cert_id_md_oid;
        const EVP_MD *cert_id_md;
        OCSP_CERTID *cid_resp_md = NULL;

        one = OCSP_request_onereq_get0(req, i);
        cid = OCSP_onereq_get0_id(one);

@@ -1184,11 +1197,18 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req
            X509 *ca_cert = sk_X509_value(ca, jj);
            OCSP_CERTID *ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca_cert);

            if (OCSP_id_issuer_cmp(ca_id, cid) == 0)
            if (OCSP_id_issuer_cmp(ca_id, cid) == 0) {
                found = 1;

                if (resp_md != NULL)
                    cid_resp_md = OCSP_cert_to_id(resp_md, NULL, ca_cert);
            }
            OCSP_CERTID_free(ca_id);
        }
        OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
        inf = lookup_serial(db, serial);

        /* at this point, we can have cid be an alias of cid_resp_md */
        cid = (cid_resp_md != NULL) ? cid_resp_md : cid;

        if (!found) {
            OCSP_basic_add1_status(bs, cid,
@@ -1196,8 +1216,6 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req
                                   0, NULL, thisupd, nextupd);
            continue;
        }
        OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
        inf = lookup_serial(db, serial);
        if (inf == NULL) {
            OCSP_basic_add1_status(bs, cid,
                                   V_OCSP_CERTSTATUS_UNKNOWN,
@@ -1212,6 +1230,7 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req
            ASN1_GENERALIZEDTIME *invtm = NULL;
            OCSP_SINGLERESP *single;
            int reason = -1;

            unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
            single = OCSP_basic_add1_status(bs, cid,
                                            V_OCSP_CERTSTATUS_REVOKED,
@@ -1227,6 +1246,7 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req
            ASN1_TIME_free(revtm);
            ASN1_GENERALIZEDTIME_free(invtm);
        }
        OCSP_CERTID_free(cid_resp_md);
    }

    OCSP_copy_nonce(bs, req);
+7 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ B<openssl> B<ocsp>
[B<-ndays n>]
[B<-resp_key_id>]
[B<-nrequest n>]
[B<-rcid I<digest>>]
[B<-I<digest>>]

=head1 DESCRIPTION
@@ -304,6 +305,12 @@ status information is immediately available. In this case the age of the
B<notBefore> field is checked to see it is not older than B<age> seconds old.
By default this additional check is not performed.

=item B<-rcid I<digest>>

This option sets the digest algorithm to use for certificate identification
in the OCSP response. Any digest supported by the OpenSSL B<dgst> command can
be used. The default is the same digest algorithm used in the request.

=item B<-I<digest>>

This option sets digest algorithm to use for certificate identification in the