提交 0b33bc65 编写于 作者: D Dr. Stephen Henson

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.
先完成此消息的编辑!
想要评论请 注册