1109998Smarkm/* ocsp_ext.c */ 2109998Smarkm/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL 3109998Smarkm * project. */ 4109998Smarkm 5109998Smarkm/* History: 6109998Smarkm This file was transfered to Richard Levitte from CertCo by Kathy 7109998Smarkm Weinhold in mid-spring 2000 to be included in OpenSSL or released 8109998Smarkm as a patch kit. */ 9109998Smarkm 10109998Smarkm/* ==================================================================== 11109998Smarkm * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 12109998Smarkm * 13109998Smarkm * Redistribution and use in source and binary forms, with or without 14109998Smarkm * modification, are permitted provided that the following conditions 15109998Smarkm * are met: 16109998Smarkm * 17109998Smarkm * 1. Redistributions of source code must retain the above copyright 18109998Smarkm * notice, this list of conditions and the following disclaimer. 19109998Smarkm * 20109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 21109998Smarkm * notice, this list of conditions and the following disclaimer in 22109998Smarkm * the documentation and/or other materials provided with the 23109998Smarkm * distribution. 24109998Smarkm * 25109998Smarkm * 3. All advertising materials mentioning features or use of this 26109998Smarkm * software must display the following acknowledgment: 27109998Smarkm * "This product includes software developed by the OpenSSL Project 28109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 29109998Smarkm * 30109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 31109998Smarkm * endorse or promote products derived from this software without 32109998Smarkm * prior written permission. For written permission, please contact 33109998Smarkm * openssl-core@openssl.org. 34109998Smarkm * 35109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 36109998Smarkm * nor may "OpenSSL" appear in their names without prior written 37109998Smarkm * permission of the OpenSSL Project. 38109998Smarkm * 39109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 40109998Smarkm * acknowledgment: 41109998Smarkm * "This product includes software developed by the OpenSSL Project 42109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 43109998Smarkm * 44109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 45109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 47109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 48109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 49109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 51109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 53109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 54109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 55109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 56109998Smarkm * ==================================================================== 57109998Smarkm * 58109998Smarkm * This product includes cryptographic software written by Eric Young 59109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 60109998Smarkm * Hudson (tjh@cryptsoft.com). 61109998Smarkm * 62109998Smarkm */ 63109998Smarkm 64109998Smarkm#include <stdio.h> 65109998Smarkm#include <cryptlib.h> 66109998Smarkm#include <openssl/objects.h> 67109998Smarkm#include <openssl/x509.h> 68109998Smarkm#include <openssl/ocsp.h> 69109998Smarkm#include <openssl/rand.h> 70109998Smarkm#include <openssl/x509v3.h> 71109998Smarkm 72109998Smarkm/* Standard wrapper functions for extensions */ 73109998Smarkm 74109998Smarkm/* OCSP request extensions */ 75109998Smarkm 76109998Smarkmint OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x) 77109998Smarkm { 78109998Smarkm return(X509v3_get_ext_count(x->tbsRequest->requestExtensions)); 79109998Smarkm } 80109998Smarkm 81109998Smarkmint OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos) 82109998Smarkm { 83109998Smarkm return(X509v3_get_ext_by_NID(x->tbsRequest->requestExtensions,nid,lastpos)); 84109998Smarkm } 85109998Smarkm 86109998Smarkmint OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos) 87109998Smarkm { 88109998Smarkm return(X509v3_get_ext_by_OBJ(x->tbsRequest->requestExtensions,obj,lastpos)); 89109998Smarkm } 90109998Smarkm 91109998Smarkmint OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos) 92109998Smarkm { 93109998Smarkm return(X509v3_get_ext_by_critical(x->tbsRequest->requestExtensions,crit,lastpos)); 94109998Smarkm } 95109998Smarkm 96109998SmarkmX509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc) 97109998Smarkm { 98109998Smarkm return(X509v3_get_ext(x->tbsRequest->requestExtensions,loc)); 99109998Smarkm } 100109998Smarkm 101109998SmarkmX509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc) 102109998Smarkm { 103109998Smarkm return(X509v3_delete_ext(x->tbsRequest->requestExtensions,loc)); 104109998Smarkm } 105109998Smarkm 106109998Smarkmvoid *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx) 107109998Smarkm { 108109998Smarkm return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx); 109109998Smarkm } 110109998Smarkm 111109998Smarkmint OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, 112109998Smarkm unsigned long flags) 113109998Smarkm { 114109998Smarkm return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, crit, flags); 115109998Smarkm } 116109998Smarkm 117109998Smarkmint OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc) 118109998Smarkm { 119109998Smarkm return(X509v3_add_ext(&(x->tbsRequest->requestExtensions),ex,loc) != NULL); 120109998Smarkm } 121109998Smarkm 122109998Smarkm/* Single extensions */ 123109998Smarkm 124109998Smarkmint OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x) 125109998Smarkm { 126109998Smarkm return(X509v3_get_ext_count(x->singleRequestExtensions)); 127109998Smarkm } 128109998Smarkm 129109998Smarkmint OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos) 130109998Smarkm { 131109998Smarkm return(X509v3_get_ext_by_NID(x->singleRequestExtensions,nid,lastpos)); 132109998Smarkm } 133109998Smarkm 134109998Smarkmint OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos) 135109998Smarkm { 136109998Smarkm return(X509v3_get_ext_by_OBJ(x->singleRequestExtensions,obj,lastpos)); 137109998Smarkm } 138109998Smarkm 139109998Smarkmint OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos) 140109998Smarkm { 141109998Smarkm return(X509v3_get_ext_by_critical(x->singleRequestExtensions,crit,lastpos)); 142109998Smarkm } 143109998Smarkm 144109998SmarkmX509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc) 145109998Smarkm { 146109998Smarkm return(X509v3_get_ext(x->singleRequestExtensions,loc)); 147109998Smarkm } 148109998Smarkm 149109998SmarkmX509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc) 150109998Smarkm { 151109998Smarkm return(X509v3_delete_ext(x->singleRequestExtensions,loc)); 152109998Smarkm } 153109998Smarkm 154109998Smarkmvoid *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx) 155109998Smarkm { 156109998Smarkm return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx); 157109998Smarkm } 158109998Smarkm 159109998Smarkmint OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, 160109998Smarkm unsigned long flags) 161109998Smarkm { 162109998Smarkm return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, flags); 163109998Smarkm } 164109998Smarkm 165109998Smarkmint OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc) 166109998Smarkm { 167109998Smarkm return(X509v3_add_ext(&(x->singleRequestExtensions),ex,loc) != NULL); 168109998Smarkm } 169109998Smarkm 170109998Smarkm/* OCSP Basic response */ 171109998Smarkm 172109998Smarkmint OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x) 173109998Smarkm { 174109998Smarkm return(X509v3_get_ext_count(x->tbsResponseData->responseExtensions)); 175109998Smarkm } 176109998Smarkm 177109998Smarkmint OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos) 178109998Smarkm { 179109998Smarkm return(X509v3_get_ext_by_NID(x->tbsResponseData->responseExtensions,nid,lastpos)); 180109998Smarkm } 181109998Smarkm 182109998Smarkmint OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos) 183109998Smarkm { 184109998Smarkm return(X509v3_get_ext_by_OBJ(x->tbsResponseData->responseExtensions,obj,lastpos)); 185109998Smarkm } 186109998Smarkm 187109998Smarkmint OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos) 188109998Smarkm { 189109998Smarkm return(X509v3_get_ext_by_critical(x->tbsResponseData->responseExtensions,crit,lastpos)); 190109998Smarkm } 191109998Smarkm 192109998SmarkmX509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc) 193109998Smarkm { 194109998Smarkm return(X509v3_get_ext(x->tbsResponseData->responseExtensions,loc)); 195109998Smarkm } 196109998Smarkm 197109998SmarkmX509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc) 198109998Smarkm { 199109998Smarkm return(X509v3_delete_ext(x->tbsResponseData->responseExtensions,loc)); 200109998Smarkm } 201109998Smarkm 202109998Smarkmvoid *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx) 203109998Smarkm { 204109998Smarkm return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit, idx); 205109998Smarkm } 206109998Smarkm 207109998Smarkmint OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit, 208109998Smarkm unsigned long flags) 209109998Smarkm { 210109998Smarkm return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, value, crit, flags); 211109998Smarkm } 212109998Smarkm 213109998Smarkmint OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc) 214109998Smarkm { 215109998Smarkm return(X509v3_add_ext(&(x->tbsResponseData->responseExtensions),ex,loc) != NULL); 216109998Smarkm } 217109998Smarkm 218109998Smarkm/* OCSP single response extensions */ 219109998Smarkm 220109998Smarkmint OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x) 221109998Smarkm { 222109998Smarkm return(X509v3_get_ext_count(x->singleExtensions)); 223109998Smarkm } 224109998Smarkm 225109998Smarkmint OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos) 226109998Smarkm { 227109998Smarkm return(X509v3_get_ext_by_NID(x->singleExtensions,nid,lastpos)); 228109998Smarkm } 229109998Smarkm 230109998Smarkmint OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, int lastpos) 231109998Smarkm { 232109998Smarkm return(X509v3_get_ext_by_OBJ(x->singleExtensions,obj,lastpos)); 233109998Smarkm } 234109998Smarkm 235109998Smarkmint OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos) 236109998Smarkm { 237109998Smarkm return(X509v3_get_ext_by_critical(x->singleExtensions,crit,lastpos)); 238109998Smarkm } 239109998Smarkm 240109998SmarkmX509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc) 241109998Smarkm { 242109998Smarkm return(X509v3_get_ext(x->singleExtensions,loc)); 243109998Smarkm } 244109998Smarkm 245109998SmarkmX509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc) 246109998Smarkm { 247109998Smarkm return(X509v3_delete_ext(x->singleExtensions,loc)); 248109998Smarkm } 249109998Smarkm 250109998Smarkmvoid *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx) 251109998Smarkm { 252109998Smarkm return X509V3_get_d2i(x->singleExtensions, nid, crit, idx); 253109998Smarkm } 254109998Smarkm 255109998Smarkmint OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit, 256109998Smarkm unsigned long flags) 257109998Smarkm { 258109998Smarkm return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags); 259109998Smarkm } 260109998Smarkm 261109998Smarkmint OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) 262109998Smarkm { 263109998Smarkm return(X509v3_add_ext(&(x->singleExtensions),ex,loc) != NULL); 264109998Smarkm } 265109998Smarkm 266109998Smarkm/* also CRL Entry Extensions */ 267238405Sjkim#if 0 268160814SsimonASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d, 269160814Ssimon void *data, STACK_OF(ASN1_OBJECT) *sk) 270109998Smarkm { 271109998Smarkm int i; 272109998Smarkm unsigned char *p, *b = NULL; 273109998Smarkm 274109998Smarkm if (data) 275109998Smarkm { 276109998Smarkm if ((i=i2d(data,NULL)) <= 0) goto err; 277160814Ssimon if (!(b=p=OPENSSL_malloc((unsigned int)i))) 278109998Smarkm goto err; 279109998Smarkm if (i2d(data, &p) <= 0) goto err; 280109998Smarkm } 281109998Smarkm else if (sk) 282109998Smarkm { 283160814Ssimon if ((i=i2d_ASN1_SET_OF_ASN1_OBJECT(sk,NULL, 284160814Ssimon (I2D_OF(ASN1_OBJECT))i2d, 285160814Ssimon V_ASN1_SEQUENCE, 286160814Ssimon V_ASN1_UNIVERSAL, 287160814Ssimon IS_SEQUENCE))<=0) goto err; 288160814Ssimon if (!(b=p=OPENSSL_malloc((unsigned int)i))) 289109998Smarkm goto err; 290160814Ssimon if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk,&p,(I2D_OF(ASN1_OBJECT))i2d, 291160814Ssimon V_ASN1_SEQUENCE, 292160814Ssimon V_ASN1_UNIVERSAL, 293160814Ssimon IS_SEQUENCE)<=0) goto err; 294109998Smarkm } 295109998Smarkm else 296109998Smarkm { 297109998Smarkm OCSPerr(OCSP_F_ASN1_STRING_ENCODE,OCSP_R_BAD_DATA); 298109998Smarkm goto err; 299109998Smarkm } 300109998Smarkm if (!s && !(s = ASN1_STRING_new())) goto err; 301109998Smarkm if (!(ASN1_STRING_set(s, b, i))) goto err; 302109998Smarkm OPENSSL_free(b); 303109998Smarkm return s; 304109998Smarkmerr: 305109998Smarkm if (b) OPENSSL_free(b); 306109998Smarkm return NULL; 307109998Smarkm } 308238405Sjkim#endif 309109998Smarkm 310109998Smarkm/* Nonce handling functions */ 311109998Smarkm 312109998Smarkm/* Add a nonce to an extension stack. A nonce can be specificed or if NULL 313109998Smarkm * a random nonce will be generated. 314127128Snectar * Note: OpenSSL 0.9.7d and later create an OCTET STRING containing the 315127128Snectar * nonce, previous versions used the raw nonce. 316109998Smarkm */ 317109998Smarkm 318109998Smarkmstatic int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, unsigned char *val, int len) 319109998Smarkm { 320109998Smarkm unsigned char *tmpval; 321109998Smarkm ASN1_OCTET_STRING os; 322109998Smarkm int ret = 0; 323109998Smarkm if (len <= 0) len = OCSP_DEFAULT_NONCE_LENGTH; 324127128Snectar /* Create the OCTET STRING manually by writing out the header and 325127128Snectar * appending the content octets. This avoids an extra memory allocation 326127128Snectar * operation in some cases. Applications should *NOT* do this because 327127128Snectar * it relies on library internals. 328127128Snectar */ 329127128Snectar os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING); 330127128Snectar os.data = OPENSSL_malloc(os.length); 331127128Snectar if (os.data == NULL) 332127128Snectar goto err; 333127128Snectar tmpval = os.data; 334127128Snectar ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL); 335127128Snectar if (val) 336127128Snectar memcpy(tmpval, val, len); 337109998Smarkm else 338109998Smarkm RAND_pseudo_bytes(tmpval, len); 339109998Smarkm if(!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, 340109998Smarkm &os, 0, X509V3_ADD_REPLACE)) 341109998Smarkm goto err; 342109998Smarkm ret = 1; 343109998Smarkm err: 344127128Snectar if (os.data) 345127128Snectar OPENSSL_free(os.data); 346109998Smarkm return ret; 347109998Smarkm } 348109998Smarkm 349109998Smarkm 350109998Smarkm/* Add nonce to an OCSP request */ 351109998Smarkm 352109998Smarkmint OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) 353109998Smarkm { 354109998Smarkm return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len); 355109998Smarkm } 356109998Smarkm 357109998Smarkm/* Same as above but for a response */ 358109998Smarkm 359109998Smarkmint OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) 360109998Smarkm { 361109998Smarkm return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, len); 362109998Smarkm } 363109998Smarkm 364109998Smarkm/* Check nonce validity in a request and response. 365109998Smarkm * Return value reflects result: 366109998Smarkm * 1: nonces present and equal. 367109998Smarkm * 2: nonces both absent. 368109998Smarkm * 3: nonce present in response only. 369109998Smarkm * 0: nonces both present and not equal. 370109998Smarkm * -1: nonce in request only. 371109998Smarkm * 372109998Smarkm * For most responders clients can check return > 0. 373109998Smarkm * If responder doesn't handle nonces return != 0 may be 374109998Smarkm * necessary. return == 0 is always an error. 375109998Smarkm */ 376109998Smarkm 377109998Smarkmint OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) 378109998Smarkm { 379109998Smarkm /* 380109998Smarkm * Since we are only interested in the presence or absence of 381109998Smarkm * the nonce and comparing its value there is no need to use 382109998Smarkm * the X509V3 routines: this way we can avoid them allocating an 383109998Smarkm * ASN1_OCTET_STRING structure for the value which would be 384109998Smarkm * freed immediately anyway. 385109998Smarkm */ 386109998Smarkm 387109998Smarkm int req_idx, resp_idx; 388109998Smarkm X509_EXTENSION *req_ext, *resp_ext; 389109998Smarkm req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); 390109998Smarkm resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1); 391109998Smarkm /* Check both absent */ 392109998Smarkm if((req_idx < 0) && (resp_idx < 0)) 393109998Smarkm return 2; 394109998Smarkm /* Check in request only */ 395109998Smarkm if((req_idx >= 0) && (resp_idx < 0)) 396109998Smarkm return -1; 397109998Smarkm /* Check in response but not request */ 398109998Smarkm if((req_idx < 0) && (resp_idx >= 0)) 399109998Smarkm return 3; 400109998Smarkm /* Otherwise nonce in request and response so retrieve the extensions */ 401109998Smarkm req_ext = OCSP_REQUEST_get_ext(req, req_idx); 402109998Smarkm resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx); 403109998Smarkm if(ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value)) 404109998Smarkm return 0; 405109998Smarkm return 1; 406109998Smarkm } 407109998Smarkm 408109998Smarkm/* Copy the nonce value (if any) from an OCSP request to 409109998Smarkm * a response. 410109998Smarkm */ 411109998Smarkm 412109998Smarkmint OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req) 413109998Smarkm { 414109998Smarkm X509_EXTENSION *req_ext; 415109998Smarkm int req_idx; 416109998Smarkm /* Check for nonce in request */ 417109998Smarkm req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); 418109998Smarkm /* If no nonce that's OK */ 419109998Smarkm if (req_idx < 0) return 2; 420109998Smarkm req_ext = OCSP_REQUEST_get_ext(req, req_idx); 421109998Smarkm return OCSP_BASICRESP_add_ext(resp, req_ext, -1); 422109998Smarkm } 423109998Smarkm 424109998SmarkmX509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim) 425109998Smarkm { 426109998Smarkm X509_EXTENSION *x = NULL; 427109998Smarkm OCSP_CRLID *cid = NULL; 428109998Smarkm 429109998Smarkm if (!(cid = OCSP_CRLID_new())) goto err; 430109998Smarkm if (url) 431109998Smarkm { 432109998Smarkm if (!(cid->crlUrl = ASN1_IA5STRING_new())) goto err; 433109998Smarkm if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) goto err; 434109998Smarkm } 435109998Smarkm if (n) 436109998Smarkm { 437109998Smarkm if (!(cid->crlNum = ASN1_INTEGER_new())) goto err; 438109998Smarkm if (!(ASN1_INTEGER_set(cid->crlNum, *n))) goto err; 439109998Smarkm } 440109998Smarkm if (tim) 441109998Smarkm { 442109998Smarkm if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) goto err; 443109998Smarkm if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) 444109998Smarkm goto err; 445109998Smarkm } 446238405Sjkim x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid); 447109998Smarkmerr: 448109998Smarkm if (cid) OCSP_CRLID_free(cid); 449238405Sjkim return x; 450109998Smarkm } 451109998Smarkm 452109998Smarkm/* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ 453109998SmarkmX509_EXTENSION *OCSP_accept_responses_new(char **oids) 454109998Smarkm { 455109998Smarkm int nid; 456109998Smarkm STACK_OF(ASN1_OBJECT) *sk = NULL; 457109998Smarkm ASN1_OBJECT *o = NULL; 458109998Smarkm X509_EXTENSION *x = NULL; 459109998Smarkm 460109998Smarkm if (!(sk = sk_ASN1_OBJECT_new_null())) goto err; 461109998Smarkm while (oids && *oids) 462109998Smarkm { 463109998Smarkm if ((nid=OBJ_txt2nid(*oids))!=NID_undef&&(o=OBJ_nid2obj(nid))) 464109998Smarkm sk_ASN1_OBJECT_push(sk, o); 465109998Smarkm oids++; 466109998Smarkm } 467238405Sjkim x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk); 468109998Smarkmerr: 469109998Smarkm if (sk) sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); 470238405Sjkim return x; 471109998Smarkm } 472109998Smarkm 473109998Smarkm/* ArchiveCutoff ::= GeneralizedTime */ 474109998SmarkmX509_EXTENSION *OCSP_archive_cutoff_new(char* tim) 475109998Smarkm { 476109998Smarkm X509_EXTENSION *x=NULL; 477109998Smarkm ASN1_GENERALIZEDTIME *gt = NULL; 478109998Smarkm 479109998Smarkm if (!(gt = ASN1_GENERALIZEDTIME_new())) goto err; 480109998Smarkm if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) goto err; 481238405Sjkim x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt); 482109998Smarkmerr: 483109998Smarkm if (gt) ASN1_GENERALIZEDTIME_free(gt); 484238405Sjkim return x; 485109998Smarkm } 486109998Smarkm 487109998Smarkm/* per ACCESS_DESCRIPTION parameter are oids, of which there are currently 488109998Smarkm * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value. This 489109998Smarkm * method forces NID_ad_ocsp and uniformResourceLocator [6] IA5String. 490109998Smarkm */ 491109998SmarkmX509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls) 492109998Smarkm { 493109998Smarkm X509_EXTENSION *x = NULL; 494109998Smarkm ASN1_IA5STRING *ia5 = NULL; 495109998Smarkm OCSP_SERVICELOC *sloc = NULL; 496109998Smarkm ACCESS_DESCRIPTION *ad = NULL; 497109998Smarkm 498109998Smarkm if (!(sloc = OCSP_SERVICELOC_new())) goto err; 499109998Smarkm if (!(sloc->issuer = X509_NAME_dup(issuer))) goto err; 500109998Smarkm if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) goto err; 501109998Smarkm while (urls && *urls) 502109998Smarkm { 503109998Smarkm if (!(ad = ACCESS_DESCRIPTION_new())) goto err; 504109998Smarkm if (!(ad->method=OBJ_nid2obj(NID_ad_OCSP))) goto err; 505109998Smarkm if (!(ad->location = GENERAL_NAME_new())) goto err; 506109998Smarkm if (!(ia5 = ASN1_IA5STRING_new())) goto err; 507109998Smarkm if (!ASN1_STRING_set((ASN1_STRING*)ia5, *urls, -1)) goto err; 508109998Smarkm ad->location->type = GEN_URI; 509109998Smarkm ad->location->d.ia5 = ia5; 510109998Smarkm if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) goto err; 511109998Smarkm urls++; 512109998Smarkm } 513238405Sjkim x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc); 514109998Smarkmerr: 515109998Smarkm if (sloc) OCSP_SERVICELOC_free(sloc); 516238405Sjkim return x; 517109998Smarkm } 518109998Smarkm 519