1109998Smarkm/* ocsp_ext.c */ 2296465Sdelphij/* 3296465Sdelphij * Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL 4296465Sdelphij * project. 5296465Sdelphij */ 6109998Smarkm 7296465Sdelphij/* 8296465Sdelphij * History: This file was transfered to Richard Levitte from CertCo by Kathy 9296465Sdelphij * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a 10296465Sdelphij * patch kit. 11296465Sdelphij */ 12109998Smarkm 13109998Smarkm/* ==================================================================== 14109998Smarkm * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 15109998Smarkm * 16109998Smarkm * Redistribution and use in source and binary forms, with or without 17109998Smarkm * modification, are permitted provided that the following conditions 18109998Smarkm * are met: 19109998Smarkm * 20109998Smarkm * 1. Redistributions of source code must retain the above copyright 21296465Sdelphij * notice, this list of conditions and the following disclaimer. 22109998Smarkm * 23109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 24109998Smarkm * notice, this list of conditions and the following disclaimer in 25109998Smarkm * the documentation and/or other materials provided with the 26109998Smarkm * distribution. 27109998Smarkm * 28109998Smarkm * 3. All advertising materials mentioning features or use of this 29109998Smarkm * software must display the following acknowledgment: 30109998Smarkm * "This product includes software developed by the OpenSSL Project 31109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 32109998Smarkm * 33109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 34109998Smarkm * endorse or promote products derived from this software without 35109998Smarkm * prior written permission. For written permission, please contact 36109998Smarkm * openssl-core@openssl.org. 37109998Smarkm * 38109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 39109998Smarkm * nor may "OpenSSL" appear in their names without prior written 40109998Smarkm * permission of the OpenSSL Project. 41109998Smarkm * 42109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 43109998Smarkm * acknowledgment: 44109998Smarkm * "This product includes software developed by the OpenSSL Project 45109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 46109998Smarkm * 47109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 48109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 50109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 51109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 52109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 53109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 54109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 56109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 57109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 58109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 59109998Smarkm * ==================================================================== 60109998Smarkm * 61109998Smarkm * This product includes cryptographic software written by Eric Young 62109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 63109998Smarkm * Hudson (tjh@cryptsoft.com). 64109998Smarkm * 65109998Smarkm */ 66109998Smarkm 67109998Smarkm#include <stdio.h> 68109998Smarkm#include <cryptlib.h> 69109998Smarkm#include <openssl/objects.h> 70109998Smarkm#include <openssl/x509.h> 71109998Smarkm#include <openssl/ocsp.h> 72109998Smarkm#include <openssl/rand.h> 73109998Smarkm#include <openssl/x509v3.h> 74109998Smarkm 75109998Smarkm/* Standard wrapper functions for extensions */ 76109998Smarkm 77109998Smarkm/* OCSP request extensions */ 78109998Smarkm 79109998Smarkmint OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x) 80296465Sdelphij{ 81296465Sdelphij return (X509v3_get_ext_count(x->tbsRequest->requestExtensions)); 82296465Sdelphij} 83109998Smarkm 84109998Smarkmint OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos) 85296465Sdelphij{ 86296465Sdelphij return (X509v3_get_ext_by_NID 87296465Sdelphij (x->tbsRequest->requestExtensions, nid, lastpos)); 88296465Sdelphij} 89109998Smarkm 90296465Sdelphijint OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, 91296465Sdelphij int lastpos) 92296465Sdelphij{ 93296465Sdelphij return (X509v3_get_ext_by_OBJ 94296465Sdelphij (x->tbsRequest->requestExtensions, obj, lastpos)); 95296465Sdelphij} 96109998Smarkm 97109998Smarkmint OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos) 98296465Sdelphij{ 99296465Sdelphij return (X509v3_get_ext_by_critical 100296465Sdelphij (x->tbsRequest->requestExtensions, crit, lastpos)); 101296465Sdelphij} 102109998Smarkm 103109998SmarkmX509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc) 104296465Sdelphij{ 105296465Sdelphij return (X509v3_get_ext(x->tbsRequest->requestExtensions, loc)); 106296465Sdelphij} 107109998Smarkm 108109998SmarkmX509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc) 109296465Sdelphij{ 110296465Sdelphij return (X509v3_delete_ext(x->tbsRequest->requestExtensions, loc)); 111296465Sdelphij} 112109998Smarkm 113109998Smarkmvoid *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx) 114296465Sdelphij{ 115296465Sdelphij return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx); 116296465Sdelphij} 117109998Smarkm 118109998Smarkmint OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, 119296465Sdelphij unsigned long flags) 120296465Sdelphij{ 121296465Sdelphij return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, 122296465Sdelphij crit, flags); 123296465Sdelphij} 124109998Smarkm 125109998Smarkmint OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc) 126296465Sdelphij{ 127296465Sdelphij return (X509v3_add_ext(&(x->tbsRequest->requestExtensions), ex, loc) != 128296465Sdelphij NULL); 129296465Sdelphij} 130109998Smarkm 131109998Smarkm/* Single extensions */ 132109998Smarkm 133109998Smarkmint OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x) 134296465Sdelphij{ 135296465Sdelphij return (X509v3_get_ext_count(x->singleRequestExtensions)); 136296465Sdelphij} 137109998Smarkm 138109998Smarkmint OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos) 139296465Sdelphij{ 140296465Sdelphij return (X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos)); 141296465Sdelphij} 142109998Smarkm 143109998Smarkmint OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos) 144296465Sdelphij{ 145296465Sdelphij return (X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos)); 146296465Sdelphij} 147109998Smarkm 148109998Smarkmint OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos) 149296465Sdelphij{ 150296465Sdelphij return (X509v3_get_ext_by_critical 151296465Sdelphij (x->singleRequestExtensions, crit, lastpos)); 152296465Sdelphij} 153109998Smarkm 154109998SmarkmX509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc) 155296465Sdelphij{ 156296465Sdelphij return (X509v3_get_ext(x->singleRequestExtensions, loc)); 157296465Sdelphij} 158109998Smarkm 159109998SmarkmX509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc) 160296465Sdelphij{ 161296465Sdelphij return (X509v3_delete_ext(x->singleRequestExtensions, loc)); 162296465Sdelphij} 163109998Smarkm 164109998Smarkmvoid *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx) 165296465Sdelphij{ 166296465Sdelphij return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx); 167296465Sdelphij} 168109998Smarkm 169109998Smarkmint OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, 170296465Sdelphij unsigned long flags) 171296465Sdelphij{ 172296465Sdelphij return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, 173296465Sdelphij flags); 174296465Sdelphij} 175109998Smarkm 176109998Smarkmint OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc) 177296465Sdelphij{ 178296465Sdelphij return (X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL); 179296465Sdelphij} 180109998Smarkm 181109998Smarkm/* OCSP Basic response */ 182109998Smarkm 183109998Smarkmint OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x) 184296465Sdelphij{ 185296465Sdelphij return (X509v3_get_ext_count(x->tbsResponseData->responseExtensions)); 186296465Sdelphij} 187109998Smarkm 188109998Smarkmint OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos) 189296465Sdelphij{ 190296465Sdelphij return (X509v3_get_ext_by_NID 191296465Sdelphij (x->tbsResponseData->responseExtensions, nid, lastpos)); 192296465Sdelphij} 193109998Smarkm 194296465Sdelphijint OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, 195296465Sdelphij int lastpos) 196296465Sdelphij{ 197296465Sdelphij return (X509v3_get_ext_by_OBJ 198296465Sdelphij (x->tbsResponseData->responseExtensions, obj, lastpos)); 199296465Sdelphij} 200109998Smarkm 201296465Sdelphijint OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, 202296465Sdelphij int lastpos) 203296465Sdelphij{ 204296465Sdelphij return (X509v3_get_ext_by_critical 205296465Sdelphij (x->tbsResponseData->responseExtensions, crit, lastpos)); 206296465Sdelphij} 207109998Smarkm 208109998SmarkmX509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc) 209296465Sdelphij{ 210296465Sdelphij return (X509v3_get_ext(x->tbsResponseData->responseExtensions, loc)); 211296465Sdelphij} 212109998Smarkm 213109998SmarkmX509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc) 214296465Sdelphij{ 215296465Sdelphij return (X509v3_delete_ext(x->tbsResponseData->responseExtensions, loc)); 216296465Sdelphij} 217109998Smarkm 218296465Sdelphijvoid *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, 219296465Sdelphij int *idx) 220296465Sdelphij{ 221296465Sdelphij return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit, 222296465Sdelphij idx); 223296465Sdelphij} 224109998Smarkm 225296465Sdelphijint OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, 226296465Sdelphij int crit, unsigned long flags) 227296465Sdelphij{ 228296465Sdelphij return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, 229296465Sdelphij value, crit, flags); 230296465Sdelphij} 231109998Smarkm 232109998Smarkmint OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc) 233296465Sdelphij{ 234296465Sdelphij return (X509v3_add_ext(&(x->tbsResponseData->responseExtensions), ex, loc) 235296465Sdelphij != NULL); 236296465Sdelphij} 237109998Smarkm 238109998Smarkm/* OCSP single response extensions */ 239109998Smarkm 240109998Smarkmint OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x) 241296465Sdelphij{ 242296465Sdelphij return (X509v3_get_ext_count(x->singleExtensions)); 243296465Sdelphij} 244109998Smarkm 245109998Smarkmint OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos) 246296465Sdelphij{ 247296465Sdelphij return (X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos)); 248296465Sdelphij} 249109998Smarkm 250296465Sdelphijint OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, 251296465Sdelphij int lastpos) 252296465Sdelphij{ 253296465Sdelphij return (X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos)); 254296465Sdelphij} 255109998Smarkm 256296465Sdelphijint OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, 257296465Sdelphij int lastpos) 258296465Sdelphij{ 259296465Sdelphij return (X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos)); 260296465Sdelphij} 261109998Smarkm 262109998SmarkmX509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc) 263296465Sdelphij{ 264296465Sdelphij return (X509v3_get_ext(x->singleExtensions, loc)); 265296465Sdelphij} 266109998Smarkm 267109998SmarkmX509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc) 268296465Sdelphij{ 269296465Sdelphij return (X509v3_delete_ext(x->singleExtensions, loc)); 270296465Sdelphij} 271109998Smarkm 272296465Sdelphijvoid *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, 273296465Sdelphij int *idx) 274296465Sdelphij{ 275296465Sdelphij return X509V3_get_d2i(x->singleExtensions, nid, crit, idx); 276296465Sdelphij} 277109998Smarkm 278296465Sdelphijint OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, 279296465Sdelphij int crit, unsigned long flags) 280296465Sdelphij{ 281296465Sdelphij return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags); 282296465Sdelphij} 283109998Smarkm 284109998Smarkmint OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) 285296465Sdelphij{ 286296465Sdelphij return (X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL); 287296465Sdelphij} 288109998Smarkm 289109998Smarkm/* also CRL Entry Extensions */ 290109998Smarkm 291160814SsimonASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d, 292296465Sdelphij void *data, STACK_OF(ASN1_OBJECT) *sk) 293296465Sdelphij{ 294296465Sdelphij int i; 295296465Sdelphij unsigned char *p, *b = NULL; 296109998Smarkm 297296465Sdelphij if (data) { 298296465Sdelphij if ((i = i2d(data, NULL)) <= 0) 299296465Sdelphij goto err; 300296465Sdelphij if (!(b = p = OPENSSL_malloc((unsigned int)i))) 301296465Sdelphij goto err; 302296465Sdelphij if (i2d(data, &p) <= 0) 303296465Sdelphij goto err; 304296465Sdelphij } else if (sk) { 305296465Sdelphij if ((i = i2d_ASN1_SET_OF_ASN1_OBJECT(sk, NULL, 306296465Sdelphij (I2D_OF(ASN1_OBJECT)) i2d, 307296465Sdelphij V_ASN1_SEQUENCE, 308296465Sdelphij V_ASN1_UNIVERSAL, 309296465Sdelphij IS_SEQUENCE)) <= 0) 310296465Sdelphij goto err; 311296465Sdelphij if (!(b = p = OPENSSL_malloc((unsigned int)i))) 312296465Sdelphij goto err; 313296465Sdelphij if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk, &p, (I2D_OF(ASN1_OBJECT)) i2d, 314296465Sdelphij V_ASN1_SEQUENCE, 315296465Sdelphij V_ASN1_UNIVERSAL, IS_SEQUENCE) <= 0) 316296465Sdelphij goto err; 317296465Sdelphij } else { 318296465Sdelphij OCSPerr(OCSP_F_ASN1_STRING_ENCODE, OCSP_R_BAD_DATA); 319296465Sdelphij goto err; 320296465Sdelphij } 321296465Sdelphij if (!s && !(s = ASN1_STRING_new())) 322296465Sdelphij goto err; 323296465Sdelphij if (!(ASN1_STRING_set(s, b, i))) 324296465Sdelphij goto err; 325296465Sdelphij OPENSSL_free(b); 326296465Sdelphij return s; 327296465Sdelphij err: 328296465Sdelphij if (b) 329296465Sdelphij OPENSSL_free(b); 330296465Sdelphij return NULL; 331296465Sdelphij} 332109998Smarkm 333109998Smarkm/* Nonce handling functions */ 334109998Smarkm 335296465Sdelphij/* 336296465Sdelphij * Add a nonce to an extension stack. A nonce can be specificed or if NULL a 337296465Sdelphij * random nonce will be generated. Note: OpenSSL 0.9.7d and later create an 338296465Sdelphij * OCTET STRING containing the nonce, previous versions used the raw nonce. 339109998Smarkm */ 340109998Smarkm 341296465Sdelphijstatic int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, 342296465Sdelphij unsigned char *val, int len) 343296465Sdelphij{ 344296465Sdelphij unsigned char *tmpval; 345296465Sdelphij ASN1_OCTET_STRING os; 346296465Sdelphij int ret = 0; 347296465Sdelphij if (len <= 0) 348296465Sdelphij len = OCSP_DEFAULT_NONCE_LENGTH; 349296465Sdelphij /* 350296465Sdelphij * Create the OCTET STRING manually by writing out the header and 351296465Sdelphij * appending the content octets. This avoids an extra memory allocation 352296465Sdelphij * operation in some cases. Applications should *NOT* do this because it 353296465Sdelphij * relies on library internals. 354296465Sdelphij */ 355296465Sdelphij os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING); 356296465Sdelphij os.data = OPENSSL_malloc(os.length); 357296465Sdelphij if (os.data == NULL) 358296465Sdelphij goto err; 359296465Sdelphij tmpval = os.data; 360296465Sdelphij ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL); 361296465Sdelphij if (val) 362296465Sdelphij memcpy(tmpval, val, len); 363296465Sdelphij else 364296465Sdelphij RAND_pseudo_bytes(tmpval, len); 365296465Sdelphij if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, 366296465Sdelphij &os, 0, X509V3_ADD_REPLACE)) 367296465Sdelphij goto err; 368296465Sdelphij ret = 1; 369296465Sdelphij err: 370296465Sdelphij if (os.data) 371296465Sdelphij OPENSSL_free(os.data); 372296465Sdelphij return ret; 373296465Sdelphij} 374109998Smarkm 375109998Smarkm/* Add nonce to an OCSP request */ 376109998Smarkm 377109998Smarkmint OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) 378296465Sdelphij{ 379296465Sdelphij return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len); 380296465Sdelphij} 381109998Smarkm 382109998Smarkm/* Same as above but for a response */ 383109998Smarkm 384109998Smarkmint OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) 385296465Sdelphij{ 386296465Sdelphij return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, 387296465Sdelphij len); 388296465Sdelphij} 389109998Smarkm 390296465Sdelphij/*- 391296465Sdelphij * Check nonce validity in a request and response. 392109998Smarkm * Return value reflects result: 393109998Smarkm * 1: nonces present and equal. 394109998Smarkm * 2: nonces both absent. 395109998Smarkm * 3: nonce present in response only. 396109998Smarkm * 0: nonces both present and not equal. 397109998Smarkm * -1: nonce in request only. 398109998Smarkm * 399109998Smarkm * For most responders clients can check return > 0. 400109998Smarkm * If responder doesn't handle nonces return != 0 may be 401109998Smarkm * necessary. return == 0 is always an error. 402109998Smarkm */ 403109998Smarkm 404109998Smarkmint OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) 405296465Sdelphij{ 406296465Sdelphij /* 407296465Sdelphij * Since we are only interested in the presence or absence of 408296465Sdelphij * the nonce and comparing its value there is no need to use 409296465Sdelphij * the X509V3 routines: this way we can avoid them allocating an 410296465Sdelphij * ASN1_OCTET_STRING structure for the value which would be 411296465Sdelphij * freed immediately anyway. 412296465Sdelphij */ 413109998Smarkm 414296465Sdelphij int req_idx, resp_idx; 415296465Sdelphij X509_EXTENSION *req_ext, *resp_ext; 416296465Sdelphij req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); 417296465Sdelphij resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1); 418296465Sdelphij /* Check both absent */ 419296465Sdelphij if ((req_idx < 0) && (resp_idx < 0)) 420296465Sdelphij return 2; 421296465Sdelphij /* Check in request only */ 422296465Sdelphij if ((req_idx >= 0) && (resp_idx < 0)) 423296465Sdelphij return -1; 424296465Sdelphij /* Check in response but not request */ 425296465Sdelphij if ((req_idx < 0) && (resp_idx >= 0)) 426296465Sdelphij return 3; 427296465Sdelphij /* 428296465Sdelphij * Otherwise nonce in request and response so retrieve the extensions 429296465Sdelphij */ 430296465Sdelphij req_ext = OCSP_REQUEST_get_ext(req, req_idx); 431296465Sdelphij resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx); 432296465Sdelphij if (ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value)) 433296465Sdelphij return 0; 434296465Sdelphij return 1; 435296465Sdelphij} 436109998Smarkm 437296465Sdelphij/* 438296465Sdelphij * Copy the nonce value (if any) from an OCSP request to a response. 439109998Smarkm */ 440109998Smarkm 441109998Smarkmint OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req) 442296465Sdelphij{ 443296465Sdelphij X509_EXTENSION *req_ext; 444296465Sdelphij int req_idx; 445296465Sdelphij /* Check for nonce in request */ 446296465Sdelphij req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); 447296465Sdelphij /* If no nonce that's OK */ 448296465Sdelphij if (req_idx < 0) 449296465Sdelphij return 2; 450296465Sdelphij req_ext = OCSP_REQUEST_get_ext(req, req_idx); 451296465Sdelphij return OCSP_BASICRESP_add_ext(resp, req_ext, -1); 452296465Sdelphij} 453109998Smarkm 454109998SmarkmX509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim) 455296465Sdelphij{ 456296465Sdelphij X509_EXTENSION *x = NULL; 457296465Sdelphij OCSP_CRLID *cid = NULL; 458109998Smarkm 459296465Sdelphij if (!(cid = OCSP_CRLID_new())) 460296465Sdelphij goto err; 461296465Sdelphij if (url) { 462296465Sdelphij if (!(cid->crlUrl = ASN1_IA5STRING_new())) 463296465Sdelphij goto err; 464296465Sdelphij if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) 465296465Sdelphij goto err; 466296465Sdelphij } 467296465Sdelphij if (n) { 468296465Sdelphij if (!(cid->crlNum = ASN1_INTEGER_new())) 469296465Sdelphij goto err; 470296465Sdelphij if (!(ASN1_INTEGER_set(cid->crlNum, *n))) 471296465Sdelphij goto err; 472296465Sdelphij } 473296465Sdelphij if (tim) { 474296465Sdelphij if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) 475296465Sdelphij goto err; 476296465Sdelphij if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) 477296465Sdelphij goto err; 478296465Sdelphij } 479296465Sdelphij if (!(x = X509_EXTENSION_new())) 480296465Sdelphij goto err; 481296465Sdelphij if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_CrlID))) 482296465Sdelphij goto err; 483296465Sdelphij if (!(ASN1_STRING_encode_of(OCSP_CRLID, x->value, i2d_OCSP_CRLID, cid, 484296465Sdelphij NULL))) 485296465Sdelphij goto err; 486296465Sdelphij OCSP_CRLID_free(cid); 487296465Sdelphij return x; 488296465Sdelphij err: 489296465Sdelphij if (x) 490296465Sdelphij X509_EXTENSION_free(x); 491296465Sdelphij if (cid) 492296465Sdelphij OCSP_CRLID_free(cid); 493296465Sdelphij return NULL; 494296465Sdelphij} 495296465Sdelphij 496109998Smarkm/* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ 497109998SmarkmX509_EXTENSION *OCSP_accept_responses_new(char **oids) 498296465Sdelphij{ 499296465Sdelphij int nid; 500296465Sdelphij STACK_OF(ASN1_OBJECT) *sk = NULL; 501296465Sdelphij ASN1_OBJECT *o = NULL; 502296465Sdelphij X509_EXTENSION *x = NULL; 503109998Smarkm 504296465Sdelphij if (!(sk = sk_ASN1_OBJECT_new_null())) 505296465Sdelphij goto err; 506296465Sdelphij while (oids && *oids) { 507296465Sdelphij if ((nid = OBJ_txt2nid(*oids)) != NID_undef && (o = OBJ_nid2obj(nid))) 508296465Sdelphij sk_ASN1_OBJECT_push(sk, o); 509296465Sdelphij oids++; 510296465Sdelphij } 511296465Sdelphij if (!(x = X509_EXTENSION_new())) 512296465Sdelphij goto err; 513296465Sdelphij if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_acceptableResponses))) 514296465Sdelphij goto err; 515296465Sdelphij if (!(ASN1_STRING_encode_of(ASN1_OBJECT, x->value, i2d_ASN1_OBJECT, NULL, 516296465Sdelphij sk))) 517296465Sdelphij goto err; 518296465Sdelphij sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); 519296465Sdelphij return x; 520296465Sdelphij err: 521296465Sdelphij if (x) 522296465Sdelphij X509_EXTENSION_free(x); 523296465Sdelphij if (sk) 524296465Sdelphij sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); 525296465Sdelphij return NULL; 526296465Sdelphij} 527109998Smarkm 528109998Smarkm/* ArchiveCutoff ::= GeneralizedTime */ 529296465SdelphijX509_EXTENSION *OCSP_archive_cutoff_new(char *tim) 530296465Sdelphij{ 531296465Sdelphij X509_EXTENSION *x = NULL; 532296465Sdelphij ASN1_GENERALIZEDTIME *gt = NULL; 533109998Smarkm 534296465Sdelphij if (!(gt = ASN1_GENERALIZEDTIME_new())) 535296465Sdelphij goto err; 536296465Sdelphij if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) 537296465Sdelphij goto err; 538296465Sdelphij if (!(x = X509_EXTENSION_new())) 539296465Sdelphij goto err; 540296465Sdelphij if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_archiveCutoff))) 541296465Sdelphij goto err; 542296465Sdelphij if (!(ASN1_STRING_encode_of(ASN1_GENERALIZEDTIME, x->value, 543296465Sdelphij i2d_ASN1_GENERALIZEDTIME, gt, NULL))) 544296465Sdelphij goto err; 545296465Sdelphij ASN1_GENERALIZEDTIME_free(gt); 546296465Sdelphij return x; 547296465Sdelphij err: 548296465Sdelphij if (gt) 549296465Sdelphij ASN1_GENERALIZEDTIME_free(gt); 550296465Sdelphij if (x) 551296465Sdelphij X509_EXTENSION_free(x); 552296465Sdelphij return NULL; 553296465Sdelphij} 554109998Smarkm 555296465Sdelphij/* 556296465Sdelphij * per ACCESS_DESCRIPTION parameter are oids, of which there are currently 557296465Sdelphij * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value. This method 558296465Sdelphij * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String. 559109998Smarkm */ 560296465SdelphijX509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls) 561296465Sdelphij{ 562296465Sdelphij X509_EXTENSION *x = NULL; 563296465Sdelphij ASN1_IA5STRING *ia5 = NULL; 564296465Sdelphij OCSP_SERVICELOC *sloc = NULL; 565296465Sdelphij ACCESS_DESCRIPTION *ad = NULL; 566109998Smarkm 567296465Sdelphij if (!(sloc = OCSP_SERVICELOC_new())) 568296465Sdelphij goto err; 569296465Sdelphij if (!(sloc->issuer = X509_NAME_dup(issuer))) 570296465Sdelphij goto err; 571296465Sdelphij if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) 572296465Sdelphij goto err; 573296465Sdelphij while (urls && *urls) { 574296465Sdelphij if (!(ad = ACCESS_DESCRIPTION_new())) 575296465Sdelphij goto err; 576296465Sdelphij if (!(ad->method = OBJ_nid2obj(NID_ad_OCSP))) 577296465Sdelphij goto err; 578296465Sdelphij if (!(ad->location = GENERAL_NAME_new())) 579296465Sdelphij goto err; 580296465Sdelphij if (!(ia5 = ASN1_IA5STRING_new())) 581296465Sdelphij goto err; 582296465Sdelphij if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1)) 583296465Sdelphij goto err; 584296465Sdelphij ad->location->type = GEN_URI; 585296465Sdelphij ad->location->d.ia5 = ia5; 586296465Sdelphij if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) 587296465Sdelphij goto err; 588296465Sdelphij urls++; 589296465Sdelphij } 590296465Sdelphij if (!(x = X509_EXTENSION_new())) 591296465Sdelphij goto err; 592296465Sdelphij if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_serviceLocator))) 593296465Sdelphij goto err; 594296465Sdelphij if (!(ASN1_STRING_encode_of(OCSP_SERVICELOC, x->value, 595296465Sdelphij i2d_OCSP_SERVICELOC, sloc, NULL))) 596296465Sdelphij goto err; 597296465Sdelphij OCSP_SERVICELOC_free(sloc); 598296465Sdelphij return x; 599296465Sdelphij err: 600296465Sdelphij if (x) 601296465Sdelphij X509_EXTENSION_free(x); 602296465Sdelphij if (sloc) 603296465Sdelphij OCSP_SERVICELOC_free(sloc); 604296465Sdelphij return NULL; 605296465Sdelphij} 606