aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/ocsp
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2001-02-26 14:17:58 +0000
committerDr. Stephen Henson <steve@openssl.org>2001-02-26 14:17:58 +0000
commitfafc7f987563ee2ea199ef27608f5a25a7cbe253 (patch)
tree9cd72b61d3b19287753753274f8b4fb64fd8ca2e /crypto/ocsp
parentd88a26c4892152c326d8b4ca80a0cc59fe8c8d51 (diff)
downloadopenssl-fafc7f987563ee2ea199ef27608f5a25a7cbe253.tar.gz
Enhance OCSP_request_verify() so it finds the signers certificate
properly and supports several flags.
Diffstat (limited to 'crypto/ocsp')
-rw-r--r--crypto/ocsp/ocsp.h6
-rw-r--r--crypto/ocsp/ocsp_err.c3
-rw-r--r--crypto/ocsp/ocsp_lib.c18
-rw-r--r--crypto/ocsp/ocsp_srv.c6
-rw-r--r--crypto/ocsp/ocsp_vfy.c89
5 files changed, 103 insertions, 19 deletions
diff --git a/crypto/ocsp/ocsp.h b/crypto/ocsp/ocsp.h
index bccdf77b4f..02b0a72ae6 100644
--- a/crypto/ocsp/ocsp.h
+++ b/crypto/ocsp/ocsp.h
@@ -448,7 +448,7 @@ int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
ASN1_GENERALIZEDTIME *nextupd,
long sec, long maxsec);
-int OCSP_request_verify(OCSP_REQUEST *req, EVP_PKEY *pkey);
+int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags);
int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl);
@@ -461,6 +461,7 @@ OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one);
int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
ASN1_OCTET_STRING **pikeyHash,
ASN1_INTEGER **pserial, OCSP_CERTID *cid);
+int OCSP_request_is_signed(OCSP_REQUEST *req);
OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs);
OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp,
OCSP_CERTID *cid,
@@ -576,6 +577,7 @@ void ERR_load_OCSP_strings(void);
#define OCSP_F_OCSP_MATCH_ISSUERID 109
#define OCSP_F_OCSP_PARSE_URL 114
#define OCSP_F_OCSP_REQUEST_SIGN 110
+#define OCSP_F_OCSP_REQUEST_VERIFY 116
#define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111
#define OCSP_F_OCSP_SENDREQ_BIO 112
#define OCSP_F_REQUEST_VERIFY 113
@@ -596,6 +598,7 @@ void ERR_load_OCSP_strings(void);
#define OCSP_R_NO_RESPONSE_DATA 108
#define OCSP_R_NO_REVOKED_TIME 109
#define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 110
+#define OCSP_R_REQUEST_NOT_SIGNED 128
#define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA 111
#define OCSP_R_ROOT_CA_NOT_TRUSTED 112
#define OCSP_R_SERVER_READ_ERROR 113
@@ -609,6 +612,7 @@ void ERR_load_OCSP_strings(void);
#define OCSP_R_STATUS_TOO_OLD 127
#define OCSP_R_UNKNOWN_MESSAGE_DIGEST 119
#define OCSP_R_UNKNOWN_NID 120
+#define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE 129
#ifdef __cplusplus
}
diff --git a/crypto/ocsp/ocsp_err.c b/crypto/ocsp/ocsp_err.c
index 1cbf9cab30..4c4d8306f8 100644
--- a/crypto/ocsp/ocsp_err.c
+++ b/crypto/ocsp/ocsp_err.c
@@ -79,6 +79,7 @@ static ERR_STRING_DATA OCSP_str_functs[]=
{ERR_PACK(0,OCSP_F_OCSP_MATCH_ISSUERID,0), "OCSP_MATCH_ISSUERID"},
{ERR_PACK(0,OCSP_F_OCSP_PARSE_URL,0), "OCSP_parse_url"},
{ERR_PACK(0,OCSP_F_OCSP_REQUEST_SIGN,0), "OCSP_request_sign"},
+{ERR_PACK(0,OCSP_F_OCSP_REQUEST_VERIFY,0), "OCSP_request_verify"},
{ERR_PACK(0,OCSP_F_OCSP_RESPONSE_GET1_BASIC,0), "OCSP_response_get1_basic"},
{ERR_PACK(0,OCSP_F_OCSP_SENDREQ_BIO,0), "OCSP_sendreq_bio"},
{ERR_PACK(0,OCSP_F_REQUEST_VERIFY,0), "REQUEST_VERIFY"},
@@ -102,6 +103,7 @@ static ERR_STRING_DATA OCSP_str_reasons[]=
{OCSP_R_NO_RESPONSE_DATA ,"no response data"},
{OCSP_R_NO_REVOKED_TIME ,"no revoked time"},
{OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE,"private key does not match certificate"},
+{OCSP_R_REQUEST_NOT_SIGNED ,"request not signed"},
{OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA,"response contains no revocation data"},
{OCSP_R_ROOT_CA_NOT_TRUSTED ,"root ca not trusted"},
{OCSP_R_SERVER_READ_ERROR ,"server read error"},
@@ -115,6 +117,7 @@ static ERR_STRING_DATA OCSP_str_reasons[]=
{OCSP_R_STATUS_TOO_OLD ,"status too old"},
{OCSP_R_UNKNOWN_MESSAGE_DIGEST ,"unknown message digest"},
{OCSP_R_UNKNOWN_NID ,"unknown nid"},
+{OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE ,"unsupported requestorname type"},
{0,NULL}
};
diff --git a/crypto/ocsp/ocsp_lib.c b/crypto/ocsp/ocsp_lib.c
index 0ddf1b2906..1ff8f4f423 100644
--- a/crypto/ocsp/ocsp_lib.c
+++ b/crypto/ocsp/ocsp_lib.c
@@ -158,24 +158,6 @@ int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber);
}
-/* XXX assumes certs in signature are sorted root to leaf XXX */
-int OCSP_request_verify(OCSP_REQUEST *req, EVP_PKEY *pkey)
- {
- STACK_OF(X509) *sk;
-
- if (!req->optionalSignature) return 0;
- if (pkey == NULL)
- {
- if (!(sk = req->optionalSignature->certs)) return 0;
- if (!(pkey=X509_get_pubkey(sk_X509_value(sk, sk_X509_num(sk)-1))))
- {
- OCSPerr(OCSP_F_REQUEST_VERIFY,OCSP_R_NO_PUBLIC_KEY);
- return 0;
- }
- }
- return OCSP_REQUEST_verify(req, pkey);
- }
-
/* Parse a URL and split it up into host, port and path components and whether
* it is SSL.
diff --git a/crypto/ocsp/ocsp_srv.c b/crypto/ocsp/ocsp_srv.c
index 3ecbfc8d1e..fffa134e75 100644
--- a/crypto/ocsp/ocsp_srv.c
+++ b/crypto/ocsp/ocsp_srv.c
@@ -96,6 +96,12 @@ int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
return 1;
}
+int OCSP_request_is_signed(OCSP_REQUEST *req)
+ {
+ if(req->optionalSignature) return 1;
+ return 0;
+ }
+
/* Create an OCSP response and encode an optional basic response */
OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs)
{
diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c
index c4f513a3b6..da4c5b20a5 100644
--- a/crypto/ocsp/ocsp_vfy.c
+++ b/crypto/ocsp/ocsp_vfy.c
@@ -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 */
@@ -340,3 +342,90 @@ 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
+ * request 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->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))
+ {
+ if(flags & OCSP_NOCHAIN)
+ X509_STORE_CTX_init(&ctx, store, signer, NULL);
+ else
+ X509_STORE_CTX_init(&ctx, store, signer, req->optionalSignature->certs);
+
+ 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;
+ }