aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/ocsp
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2001-01-08 01:21:55 +0000
committerDr. Stephen Henson <steve@openssl.org>2001-01-08 01:21:55 +0000
commit0b33bc65cd1bde346eae5b25d6f2d693c115b901 (patch)
tree2864dc1fce704a66c19f8c0cf6db8b1768b8a1c8 /crypto/ocsp
parent0f5fa24a7c0ced77eabb2d2c2f749c928a62be57 (diff)
downloadopenssl-0b33bc65cd1bde346eae5b25d6f2d693c115b901.tar.gz
Add set of OCSP client functions. All experimental
and subject to addition, modifcation or deletion. Add two OCSP nonce utility functions. Fix typo in status code name.
Diffstat (limited to 'crypto/ocsp')
-rw-r--r--crypto/ocsp/Makefile.ssl4
-rw-r--r--crypto/ocsp/ocsp.h41
-rw-r--r--crypto/ocsp/ocsp_cl.c291
-rw-r--r--crypto/ocsp/ocsp_err.c6
-rw-r--r--crypto/ocsp/ocsp_ext.c71
-rw-r--r--crypto/ocsp/ocsp_lib.c56
-rw-r--r--crypto/ocsp/ocsp_prn.c4
7 files changed, 414 insertions, 59 deletions
diff --git a/crypto/ocsp/Makefile.ssl b/crypto/ocsp/Makefile.ssl
index ef76c81271..1fce558b85 100644
--- a/crypto/ocsp/Makefile.ssl
+++ b/crypto/ocsp/Makefile.ssl
@@ -23,10 +23,10 @@ APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC= ocsp_asn.c ocsp_ext.c ocsp_ht.c \
- ocsp_lib.c ocsp_prn.c ocsp_err.c
+ ocsp_lib.c ocsp_cl.c ocsp_prn.c ocsp_err.c
LIBOBJ= ocsp_asn.o ocsp_ext.o ocsp_ht.o \
- ocsp_lib.o ocsp_prn.o ocsp_err.o
+ ocsp_lib.o ocsp_cl.o ocsp_prn.o ocsp_err.o
SRC= $(LIBSRC)
diff --git a/crypto/ocsp/ocsp.h b/crypto/ocsp/ocsp.h
index 7bc23ba4cf..7d45e9fb10 100644
--- a/crypto/ocsp/ocsp.h
+++ b/crypto/ocsp/ocsp.h
@@ -72,6 +72,12 @@
extern "C" {
#endif
+/* Various flags and values */
+
+#define OCSP_DEFAULT_NONCE_LENGTH 16
+
+#define OCSP_NOCERTS 0x1
+
/* CertID ::= SEQUENCE {
* hashAlgorithm AlgorithmIdentifier,
* issuerNameHash OCTET STRING, -- Hash of Issuer's DN
@@ -146,7 +152,7 @@ typedef struct ocsp_request_st
* unauthorized (6) --Request unauthorized
* }
*/
-#define OCSP_RESPONSE_STATUS_SUCCESSFULL 0
+#define OCSP_RESPONSE_STATUS_SUCCESSFUL 0
#define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 1
#define OCSP_RESPONSE_STATUS_INTERNALERROR 2
#define OCSP_RESPONSE_STATUS_TRYLATER 3
@@ -361,21 +367,21 @@ typedef struct ocsp_service_locator_st
#define OCSP_REQUEST_sign(o,pkey,md) \
ASN1_item_sign(&OCSP_REQINFO_it,\
o->optionalSignature->signatureAlgorithm,NULL,\
- o->optionalSignature->signature,(char *)o->tbsRequest,pkey,md)
+ o->optionalSignature->signature,o->tbsRequest,pkey,md)
#define OCSP_BASICRESP_sign(o,pkey,md,d) \
ASN1_item_sign(&OCSP_RESPDATA_it,o->signatureAlgorithm,NULL,\
- o->signature,(char *)o->tbsResponseData,pkey,md)
+ o->signature,o->tbsResponseData,pkey,md)
#define OCSP_REQUEST_verify(a,r) ASN1_item_verify(&OCSP_REQINFO_it,\
a->optionalSignature->signatureAlgorithm,\
- a->optionalSignature->signature,(char *)a->tbsRequest,r)
+ a->optionalSignature->signature,a->tbsRequest,r)
#define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(&OCSP_RESPDATA_it,\
- a->signatureAlgorithm,a->signature,(char *)a->tbsResponseData,r)
+ a->signatureAlgorithm,a->signature,a->tbsResponseData,r)
#define ASN1_BIT_STRING_digest(data,type,md,len) \
- ASN1_item_digest(&ASN1_BIT_STRING_it,type,(char *)data,md,len)
+ ASN1_item_digest(&ASN1_BIT_STRING_it,type,data,md,len)
#define OCSP_CERTID_dup(cid) (OCSP_CERTID*)ASN1_dup((int(*)())i2d_OCSP_CERTID,\
(char *(*)())d2i_OCSP_CERTID,(char *)(cid))
@@ -395,15 +401,26 @@ OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
OCSP_CERTSTATUS *OCSP_cert_status_new(int status, int reason, char *tim);
-OCSP_ONEREQ *OCSP_request_add0(OCSP_REQUEST *req, OCSP_CERTID *cid);
+OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid);
+int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len);
+int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs);
+int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm);
+int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert);
int OCSP_request_sign(OCSP_REQUEST *req,
+ X509 *signer,
EVP_PKEY *key,
const EVP_MD *dgst,
- STACK_OF(X509) *certs);
+ STACK_OF(X509) *certs,
+ unsigned long flags);
+
+int OCSP_response_status(OCSP_RESPONSE *resp);
+OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp);
int OCSP_request_verify(OCSP_REQUEST *req, EVP_PKEY *pkey);
+int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
+
OCSP_BASICRESP *OCSP_basic_response_new(int tag,
X509* cert);
@@ -431,8 +448,6 @@ OCSP_RESPONSE *OCSP_response_new(int status,
ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, int (*i2d)(),
char *data, STACK_OF(ASN1_OBJECT) *sk);
-X509_EXTENSION *OCSP_nonce_new(void *p, unsigned int len);
-
X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim);
X509_EXTENSION *OCSP_accept_responses_new(char **oids);
@@ -520,6 +535,8 @@ void ERR_load_OCSP_strings(void);
#define OCSP_F_CERT_ID_NEW 102
#define OCSP_F_CERT_STATUS_NEW 103
#define OCSP_F_D2I_OCSP_NONCE 109
+#define OCSP_F_OCSP_CHECK_NONCE 112
+#define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111
#define OCSP_F_OCSP_SENDREQ_BIO 110
#define OCSP_F_REQUEST_VERIFY 104
#define OCSP_F_RESPONSE_VERIFY 105
@@ -534,6 +551,9 @@ void ERR_load_OCSP_strings(void);
#define OCSP_R_FAILED_TO_READ 110
#define OCSP_R_FAILED_TO_STAT 111
#define OCSP_R_MISSING_VALUE 112
+#define OCSP_R_NONCE_MISSING_IN_RESPONSE 121
+#define OCSP_R_NONCE_VALUE_MISMATCH 122
+#define OCSP_R_NOT_BASIC_RESPONSE 120
#define OCSP_R_NO_CERTIFICATE 102
#define OCSP_R_NO_CONTENT 115
#define OCSP_R_NO_PUBLIC_KEY 103
@@ -544,6 +564,7 @@ void ERR_load_OCSP_strings(void);
#define OCSP_R_SERVER_RESPONSE_ERROR 117
#define OCSP_R_SERVER_RESPONSE_PARSE_ERROR 118
#define OCSP_R_SERVER_WRITE_ERROR 119
+#define OCSP_R_UNEXPECTED_NONCE_IN_RESPONSE 123
#define OCSP_R_UNKNOWN_NID 107
#define OCSP_R_UNSUPPORTED_OPTION 113
#define OCSP_R_VALUE_ALREADY 114
diff --git a/crypto/ocsp/ocsp_cl.c b/crypto/ocsp/ocsp_cl.c
new file mode 100644
index 0000000000..3e73e3bb17
--- /dev/null
+++ b/crypto/ocsp/ocsp_cl.c
@@ -0,0 +1,291 @@
+/* ocsp_cl.c */
+/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
+ * project. */
+
+/* History:
+ This file was transfered to Richard Levitte from CertCo by Kathy
+ Weinhold in mid-spring 2000 to be included in OpenSSL or released
+ as a patch kit. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 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
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <cryptlib.h>
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/ocsp.h>
+
+/* Utility functions related to sending OCSP requests and extracting
+ * relevant information from the response.
+ */
+
+/* Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ
+ * pointer: useful if we want to add extensions.
+ */
+
+OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid)
+ {
+ OCSP_ONEREQ *one = NULL;
+
+ if (!(one = OCSP_ONEREQ_new())) goto err;
+ if (one->reqCert) OCSP_CERTID_free(one->reqCert);
+ one->reqCert = cid;
+ if (req &&
+ !sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one))
+ goto err;
+ return one;
+err:
+ OCSP_ONEREQ_free(one);
+ return NULL;
+ }
+
+/* Set requestorName from an X509_NAME structure */
+
+int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm)
+ {
+ GENERAL_NAME *gen;
+ gen = GENERAL_NAME_new();
+ if (!X509_NAME_set(&gen->d.directoryName, nm))
+ {
+ GENERAL_NAME_free(gen);
+ return 0;
+ }
+ gen->type = GEN_DIRNAME;
+ if (req->tbsRequest->requestorName)
+ GENERAL_NAME_free(req->tbsRequest->requestorName);
+ req->tbsRequest->requestorName = gen;
+ return 1;
+ }
+
+
+/* Add a certificate to an OCSP request */
+
+int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert)
+ {
+ OCSP_SIGNATURE *sig;
+ if (!req->optionalSignature)
+ req->optionalSignature = OCSP_SIGNATURE_new();
+ sig = req->optionalSignature;
+ if (!sig) return 0;
+ if (!cert) return 1;
+ if (!sig->certs && !(sig->certs = sk_X509_new_null()))
+ return 0;
+
+ if(!sk_X509_push(sig->certs, cert)) return 0;
+ CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
+ return 1;
+ }
+
+/* Sign an OCSP request set the requestorName to the subjec
+ * name of an optional signers certificate and include one
+ * or more optional certificates in the request. Behaves
+ * like PKCS7_sign().
+ */
+
+int OCSP_request_sign(OCSP_REQUEST *req,
+ X509 *signer,
+ EVP_PKEY *key,
+ const EVP_MD *dgst,
+ STACK_OF(X509) *certs,
+ unsigned long flags)
+ {
+ int i;
+ OCSP_SIGNATURE *sig;
+ X509 *x;
+
+ if (signer &&
+ !OCSP_request_set1_name(req, X509_get_subject_name(signer)))
+ goto err;
+
+ if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) goto err;
+ if (!dgst) dgst = EVP_sha1();
+ if (key && !OCSP_REQUEST_sign(req, key, dgst)) goto err;
+ if (!(flags & OCSP_NOCERTS))
+ {
+ if (!OCSP_request_add1_cert(req, signer)) goto err;
+ for (i = 0; i < sk_X509_num(certs); i++)
+ {
+ x = sk_X509_value(certs, i);
+ if (!OCSP_request_add1_cert(req, x)) goto err;
+ }
+ }
+ return 1;
+err:
+ OCSP_SIGNATURE_free(req->optionalSignature);
+ req->optionalSignature = NULL;
+ return 0;
+ }
+
+/* Get response status */
+
+int OCSP_response_status(OCSP_RESPONSE *resp)
+ {
+ return ASN1_ENUMERATED_get(resp->responseStatus);
+ }
+
+/* Extract basic response from OCSP_RESPONSE or NULL if
+ * no basic response present.
+ */
+
+
+OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp)
+ {
+ OCSP_RESPBYTES *rb;
+ rb = resp->responseBytes;
+ if (!rb)
+ {
+ OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA);
+ return NULL;
+ }
+ if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic)
+ {
+ OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE);
+ return NULL;
+ }
+
+ return ASN1_item_unpack(rb->response, &OCSP_BASICRESP_it);
+ }
+
+/* Return number of OCSP_SINGLERESP reponses present in
+ * a basic response.
+ */
+
+int OCSP_resp_count(OCSP_BASICRESP *bs)
+ {
+ if (!bs) return -1;
+ return sk_OCSP_SINGLERESP_num(bs->tbsResponseData->responses);
+ }
+
+/* Extract an OCSP_SINGLERESP response with a given index */
+
+OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx)
+ {
+ if (!bs) return NULL;
+ return sk_OCSP_SINGLERESP_value(bs->tbsResponseData->responses, idx);
+ }
+
+/* Look single response matching a given certificate ID */
+
+int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last)
+ {
+ int i;
+ STACK_OF(OCSP_SINGLERESP) *sresp;
+ OCSP_SINGLERESP *single;
+ if (!bs) return -1;
+ if (last < 0) last = 0;
+ else last++;
+ sresp = bs->tbsResponseData->responses;
+ for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++)
+ {
+ single = sk_OCSP_SINGLERESP_value(sresp, i);
+ if (!OCSP_id_cmp(id, single->certId)) return i;
+ }
+ return -1;
+ }
+
+/* Extract status information from an OCSP_SINGLERESP structure.
+ * Note: the revtime and reason values are only set if the
+ * certificate status is revoked. Returns numerical value of
+ * status.
+ */
+
+int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
+ ASN1_GENERALIZEDTIME **revtime,
+ ASN1_GENERALIZEDTIME **thisupd,
+ ASN1_GENERALIZEDTIME **nextupd)
+ {
+ int ret;
+ OCSP_CERTSTATUS *cst = single->certStatus;
+ if(!single) return -1;
+ ret = cst->type;
+ if (ret == V_OCSP_CERTSTATUS_REVOKED)
+ {
+ OCSP_REVOKEDINFO *rev = cst->value.revoked;
+ if (revtime) *revtime = rev->revocationTime;
+ if (reason)
+ {
+ if(rev->revocationReason)
+ *reason = ASN1_ENUMERATED_get(rev->revocationReason);
+ else *reason = -1;
+ }
+ }
+ if(thisupd) *thisupd = single->thisUpdate;
+ if(nextupd) *nextupd = single->nextUpdate;
+ return ret;
+ }
+
+/* This function combines the previous ones: look a certificate ID and
+ * if found extract status information. Return 0 is successful.
+ */
+
+int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
+ int *reason,
+ ASN1_GENERALIZEDTIME **revtime,
+ ASN1_GENERALIZEDTIME **thisupd,
+ ASN1_GENERALIZEDTIME **nextupd)
+ {
+ int i;
+ OCSP_SINGLERESP *single;
+ i = OCSP_resp_find(bs, id, -1);
+ /* Maybe check for multiple responses and give an error? */
+ if(i < 0) return 0;
+ single = OCSP_resp_get0(bs, i);
+ i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd);
+ if(reason) *reason = i;
+ return 1;
+ }
diff --git a/crypto/ocsp/ocsp_err.c b/crypto/ocsp/ocsp_err.c
index da0f557275..dd9756a254 100644
--- a/crypto/ocsp/ocsp_err.c
+++ b/crypto/ocsp/ocsp_err.c
@@ -72,6 +72,8 @@ static ERR_STRING_DATA OCSP_str_functs[]=
{ERR_PACK(0,OCSP_F_CERT_ID_NEW,0), "CERT_ID_NEW"},
{ERR_PACK(0,OCSP_F_CERT_STATUS_NEW,0), "CERT_STATUS_NEW"},
{ERR_PACK(0,OCSP_F_D2I_OCSP_NONCE,0), "D2I_OCSP_NONCE"},
+{ERR_PACK(0,OCSP_F_OCSP_CHECK_NONCE,0), "OCSP_check_nonce"},
+{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"},
{ERR_PACK(0,OCSP_F_RESPONSE_VERIFY,0), "RESPONSE_VERIFY"},
@@ -89,6 +91,9 @@ static ERR_STRING_DATA OCSP_str_reasons[]=
{OCSP_R_FAILED_TO_READ ,"failed to read"},
{OCSP_R_FAILED_TO_STAT ,"failed to stat"},
{OCSP_R_MISSING_VALUE ,"missing value"},
+{OCSP_R_NONCE_MISSING_IN_RESPONSE ,"nonce missing in response"},
+{OCSP_R_NONCE_VALUE_MISMATCH ,"nonce value mismatch"},
+{OCSP_R_NOT_BASIC_RESPONSE ,"not basic response"},
{OCSP_R_NO_CERTIFICATE ,"no certificate"},
{OCSP_R_NO_CONTENT ,"no content"},
{OCSP_R_NO_PUBLIC_KEY ,"no public key"},
@@ -99,6 +104,7 @@ static ERR_STRING_DATA OCSP_str_reasons[]=
{OCSP_R_SERVER_RESPONSE_ERROR ,"server response error"},
{OCSP_R_SERVER_RESPONSE_PARSE_ERROR ,"server response parse error"},
{OCSP_R_SERVER_WRITE_ERROR ,"server write error"},
+{OCSP_R_UNEXPECTED_NONCE_IN_RESPONSE ,"unexpected nonce in response"},
{OCSP_R_UNKNOWN_NID ,"unknown nid"},
{OCSP_R_UNSUPPORTED_OPTION ,"unsupported option"},
{OCSP_R_VALUE_ALREADY ,"value already"},
diff --git a/crypto/ocsp/ocsp_ext.c b/crypto/ocsp/ocsp_ext.c
index ab1e1ca480..36e51ddd91 100644
--- a/crypto/ocsp/ocsp_ext.c
+++ b/crypto/ocsp/ocsp_ext.c
@@ -66,6 +66,7 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/ocsp.h>
+#include <openssl/rand.h>
#include <openssl/x509v3.h>
/* Standard wrapper functions for extensions */
@@ -300,6 +301,76 @@ err:
return NULL;
}
+/* Nonce handling functions */
+
+/* Add a nonce to an OCSP request. A nonce can be specificed or if NULL
+ * a random nonce will be generated.
+ */
+
+int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len)
+ {
+ unsigned char *tmpval;
+ ASN1_OCTET_STRING os;
+ int ret = 0;
+ if (len <= 0) len = OCSP_DEFAULT_NONCE_LENGTH;
+ if (val) tmpval = val;
+ else
+ {
+ if (!(tmpval = OPENSSL_malloc(len))) goto err;
+ RAND_pseudo_bytes(tmpval, len);
+ }
+ os.data = tmpval;
+ os.length = len;
+ if(!OCSP_REQUEST_add1_ext_i2d(req, NID_id_pkix_OCSP_Nonce,
+ &os, 0, X509V3_ADD_REPLACE))
+ goto err;
+ ret = 1;
+ err:
+ if(!val) OPENSSL_free(tmpval);
+ return ret;
+ }
+
+/* Check nonce validity in a request and response: the nonce
+ * must be either absent in both or present and equal in both.
+ */
+int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs)
+ {
+ /*
+ * Since we are only interested in the presence or absence of
+ * the nonce and comparing its value there is no need to use
+ * the X509V3 routines: this way we can avoid them allocating an
+ * ASN1_OCTET_STRING structure for the value which would be
+ * freed immediately anyway.
+ */
+
+ int ret = 0, req_idx, resp_idx;
+ X509_EXTENSION *req_ext, *resp_ext;
+ req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
+ resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1);
+ /* If both absent its OK */
+ if((req_idx < 0) && (resp_idx < 0)) return 1;
+ if((req_idx < 0) && (resp_idx >= 0))
+ {
+ OCSPerr(OCSP_F_OCSP_CHECK_NONCE, OCSP_R_NONCE_MISSING_IN_RESPONSE);
+ goto err;
+ }
+ if((req_idx < 0) && (resp_idx >= 0))
+ {
+ OCSPerr(OCSP_F_OCSP_CHECK_NONCE, OCSP_R_UNEXPECTED_NONCE_IN_RESPONSE);
+ goto err;
+ }
+ req_ext = OCSP_REQUEST_get_ext(req, req_idx);
+ resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx);
+ if(ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value))
+ {
+ OCSPerr(OCSP_F_OCSP_CHECK_NONCE, OCSP_R_NONCE_VALUE_MISMATCH);
+ goto err;
+ }
+ ret = 1;
+ err:
+ return ret;
+ }
+
X509_EXTENSION *OCSP_nonce_new(void *p, unsigned int len)
{
X509_EXTENSION *x=NULL;
diff --git a/crypto/ocsp/ocsp_lib.c b/crypto/ocsp/ocsp_lib.c
index 2a6c472f23..f9d2978402 100644
--- a/crypto/ocsp/ocsp_lib.c
+++ b/crypto/ocsp/ocsp_lib.c
@@ -64,6 +64,7 @@
#include <stdio.h>
#include <cryptlib.h>
#include <openssl/objects.h>
+#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
@@ -162,51 +163,16 @@ err:
return NULL;
}
-OCSP_ONEREQ *OCSP_request_add0(OCSP_REQUEST *req, OCSP_CERTID *cid)
- {
- OCSP_ONEREQ *one = NULL;
-
- if (!(one = OCSP_ONEREQ_new())) goto err;
- if (one->reqCert) OCSP_CERTID_free(one->reqCert);
- one->reqCert = cid;
- if (req &&
- !sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one))
- goto err;
- return one;
-err:
- if (one) OCSP_ONEREQ_free(one);
- return NULL;
- }
-
-int OCSP_request_sign(OCSP_REQUEST *req,
- EVP_PKEY *key,
- const EVP_MD *dgst,
- STACK_OF(X509) *certs)
- {
- int i;
- OCSP_SIGNATURE *sig;
-
- if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) goto err;
- if (!OCSP_REQUEST_sign(req, key, dgst)) goto err;
- if (certs)
- {
- if (!(sig->certs = sk_X509_dup(certs))) goto err;
- for (i = 0; i < sk_X509_num(sig->certs); i++)
- {
- sk_X509_set(sig->certs, i,
- X509_dup(sk_X509_value(certs,i)));
- if (! sk_X509_value(sig->certs, i))
- goto err;
- }
- }
- return 1;
-err:
- if (req->optionalSignature)
- {
- OCSP_SIGNATURE_free(req->optionalSignature);
- req->optionalSignature = NULL;
- }
- return 0;
+int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
+ {
+ int ret;
+ ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm);
+ if (ret) return ret;
+ ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash);
+ if (ret) return ret;
+ ret = ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash);
+ if (ret) return ret;
+ return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber);
}
OCSP_BASICRESP *OCSP_basic_response_new(int type, X509* cert)
diff --git a/crypto/ocsp/ocsp_prn.c b/crypto/ocsp/ocsp_prn.c
index 533d3010f2..f949e4b8ae 100644
--- a/crypto/ocsp/ocsp_prn.c
+++ b/crypto/ocsp/ocsp_prn.c
@@ -100,7 +100,7 @@ static char *table2string(long s, OCSP_TBLSTR *ts, int len)
static char* ocspResponseStatus2string(long s)
{
static OCSP_TBLSTR rstat_tbl[] = {
- { OCSP_RESPONSE_STATUS_SUCCESSFULL, "successful" },
+ { OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" },
{ OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest" },
{ OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror" },
{ OCSP_RESPONSE_STATUS_TRYLATER, "trylater" },
@@ -153,7 +153,6 @@ int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* o, unsigned long flags)
if (BIO_write(bp,"\n Requestor List:\n",21) <= 0) goto err;
for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++)
{
- if (!sk_OCSP_ONEREQ_value(inf->requestList, i)) continue;
one = sk_OCSP_ONEREQ_value(inf->requestList, i);
cid = one->reqCert;
ocsp_certid_print(bp, cid, 8);
@@ -207,6 +206,7 @@ int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags)
BIO_puts(bp," (unknown response type)\n");
return 1;
}
+
p = ASN1_STRING_data(rb->response);
i = ASN1_STRING_length(rb->response);
if (!(d2i_OCSP_BASICRESP(&br, &p, i))) goto err;