X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Focsp%2Focsp_vfy.c;h=415d67e61cfdfa62c2f19c68654cf96e9d4c7737;hb=7427379e9b73da4c15c91a6faad3c916210b0755;hp=c4f513a3b61a6b3756477a5b2d63a6f73102bd0a;hpb=3ebac273f5794b9f13f0c736d56c6106d5f8b2af;p=oweals%2Fopenssl.git diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c index c4f513a3b6..415d67e61c 100644 --- a/crypto/ocsp/ocsp_vfy.c +++ b/crypto/ocsp/ocsp_vfy.c @@ -1,9 +1,9 @@ /* ocsp_vfy.c */ -/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ /* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -67,6 +67,8 @@ static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, unsigned static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret); static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, STACK_OF(OCSP_SINGLERESP) *sresp); static int ocsp_check_delegated(X509 *x, int flags); +static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags); /* Verify a basic response message */ @@ -99,10 +101,16 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, } if (!(flags & OCSP_NOVERIFY)) { + int init_res; if(flags & OCSP_NOCHAIN) - X509_STORE_CTX_init(&ctx, st, signer, NULL); + init_res = X509_STORE_CTX_init(&ctx, st, signer, NULL); else - X509_STORE_CTX_init(&ctx, st, signer, bs->certs); + init_res = X509_STORE_CTX_init(&ctx, st, signer, bs->certs); + if(!init_res) + { + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,ERR_R_X509_LIB); + goto end; + } X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); ret = X509_verify_cert(&ctx); @@ -142,7 +150,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, } ret = 1; } - + end: @@ -264,7 +272,7 @@ static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) for (i = 1; i < idcount; i++) { - tmpid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId; + tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; /* Check to see if IDs match */ if (OCSP_id_issuer_cmp(cid, tmpid)) { @@ -300,15 +308,17 @@ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, } mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + return -1; if ((cid->issuerNameHash->length != mdlen) || (cid->issuerKeyHash->length != mdlen)) return 0; - iname = X509_get_issuer_name(cert); + iname = X509_get_subject_name(cert); if (!X509_NAME_digest(iname, dgst, md, NULL)) return -1; if (memcmp(md, cid->issuerNameHash->data, mdlen)) return 0; - X509_pubkey_digest(cert, EVP_sha1(), md, NULL); + X509_pubkey_digest(cert, dgst, md, NULL); if (memcmp(md, cid->issuerKeyHash->data, mdlen)) return 0; @@ -322,7 +332,7 @@ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, OCSP_CERTID *tmpid; for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) { - tmpid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId; + tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; ret = ocsp_match_issuerid(cert, tmpid, NULL); if (ret <= 0) return ret; } @@ -340,3 +350,97 @@ static int ocsp_check_delegated(X509 *x, int flags) OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE); return 0; } + +/* Verify an OCSP request. This is fortunately much easier than OCSP + * response verify. Just find the signers certificate and verify it + * against a given trust value. + */ + +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags) + { + X509 *signer; + X509_NAME *nm; + GENERAL_NAME *gen; + int ret; + X509_STORE_CTX ctx; + if (!req->optionalSignature) + { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED); + return 0; + } + gen = req->tbsRequest->requestorName; + if (!gen || gen->type != GEN_DIRNAME) + { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE); + return 0; + } + nm = gen->d.directoryName; + ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags); + if (ret <= 0) + { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); + return 0; + } + if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) + flags |= OCSP_NOVERIFY; + if (!(flags & OCSP_NOSIGS)) + { + EVP_PKEY *skey; + skey = X509_get_pubkey(signer); + ret = OCSP_REQUEST_verify(req, skey); + EVP_PKEY_free(skey); + if(ret <= 0) + { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE); + return 0; + } + } + if (!(flags & OCSP_NOVERIFY)) + { + int init_res; + if(flags & OCSP_NOCHAIN) + init_res = X509_STORE_CTX_init(&ctx, store, signer, NULL); + else + init_res = X509_STORE_CTX_init(&ctx, store, signer, + req->optionalSignature->certs); + if(!init_res) + { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,ERR_R_X509_LIB); + return 0; + } + + X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); + X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST); + ret = X509_verify_cert(&ctx); + X509_STORE_CTX_cleanup(&ctx); + if (ret <= 0) + { + ret = X509_STORE_CTX_get_error(&ctx); + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,OCSP_R_CERTIFICATE_VERIFY_ERROR); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(ret)); + return 0; + } + } + return 1; + } + +static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags) + { + X509 *signer; + if(!(flags & OCSP_NOINTERN)) + { + signer = X509_find_by_subject(req->optionalSignature->certs, nm); + *psigner = signer; + return 1; + } + + signer = X509_find_by_subject(certs, nm); + if (signer) + { + *psigner = signer; + return 2; + } + return 0; + }