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.
上级 0f5fa24a
......@@ -3,7 +3,29 @@
Changes between 0.9.6 and 0.9.7 [xx XXX 2000]
*) Change function OCSP_request_add() to OCSP_request_add0().
*) Move OCSP client related routines to ocsp_cl.c. These
provide utility functions which an application needing
to issue a request to an OCSP responder and analyse the
response will typically need: as opposed to those which an
OCSP responder itself would need which will be added later.
OCSP_request_sign() signs an OCSP request with an API similar
to PKCS7_sign(). OCSP_response_status() returns status of OCSP
response. OCSP_response_get1_basic() extracts basic response
from response. OCSP_resp_find_status(): finds and extracts status
information from an OCSP_CERTID structure (which will be created
when the request structure is built). These are built from lower
level functions which work on OCSP_SINGLERESP structures but
wont normally be used unless the application wishes to examine
extensions in the OCSP response for example.
Replace nonce routines with a pair of functions.
OCSP_request_add1_nonce() adds a nonce value and optionally
generates a random value. OCSP_check_nonce() checks the
validity of the nonce in an OCSP response.
[Steve Henson]
*) Change function OCSP_request_add() to OCSP_request_add0_id().
This doesn't copy the supplied OCSP_CERTID and avoids the
need to free up the newly created id. Change return type
to OCSP_ONEREQ to return the internal OCSP_ONEREQ structure.
......
......@@ -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)
......
......@@ -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
......
/* 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;
}
......@@ -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"},
......
......@@ -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;
......
......@@ -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)
......
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
新手
引导
客服 返回
顶部