X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Focsp%2Focsp_vfy.c;h=8a5e788d960fb4cadff36c352ad9c12cdf30dddb;hb=5c8d41be859b95f34d044d0e06b1b0d7187cc5b2;hp=7470f1c04816df9a6f89bcb241b772c3db85c675;hpb=50d5199120d2d669039e75c17499483aa7607430;p=oweals%2Fopenssl.git diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c index 7470f1c048..8a5e788d96 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 @@ -58,6 +58,7 @@ #include #include +#include static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags); @@ -66,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 */ @@ -98,10 +101,17 @@ 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) + { + ret = -1; + 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); @@ -141,7 +151,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, } ret = 1; } - + end: @@ -177,8 +187,6 @@ static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) { int i; unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; - ASN1_BIT_STRING *key; - EVP_MD_CTX ctx; X509 *x; /* Easy if lookup by name */ @@ -194,10 +202,7 @@ static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) for (i = 0; i < sk_X509_num(certs); i++) { x = sk_X509_value(certs, i); - key = x->cert_info->key->public_key; - EVP_DigestInit(&ctx,EVP_sha1()); - EVP_DigestUpdate(&ctx,key->data, key->length); - EVP_DigestFinal(&ctx,tmphash,NULL); + X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); if(!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) return x; } @@ -268,7 +273,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)) { @@ -294,9 +299,7 @@ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, if(cid) { const EVP_MD *dgst; - EVP_MD_CTX ctx; X509_NAME *iname; - ASN1_BIT_STRING *ikey; int mdlen; unsigned char md[EVP_MAX_MD_SIZE]; if (!(dgst = EVP_get_digestbyobj(cid->hashAlgorithm->algorithm))) @@ -306,19 +309,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; - ikey = cert->cert_info->key->public_key; - - EVP_DigestInit(&ctx,dgst); - EVP_DigestUpdate(&ctx,ikey->data, ikey->length); - EVP_DigestFinal(&ctx,md,NULL); + X509_pubkey_digest(cert, dgst, md, NULL); if (memcmp(md, cid->issuerKeyHash->data, mdlen)) return 0; @@ -332,7 +333,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; } @@ -350,3 +351,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; + }