1 /* 2 * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include <time.h> 12 #include "internal/cryptlib.h" 13 #include <openssl/asn1.h> 14 #include <openssl/objects.h> 15 #include <openssl/x509.h> 16 #include <openssl/pem.h> 17 #include <openssl/x509v3.h> 18 #include <openssl/ocsp.h> 19 #include "ocsp_local.h" 20 21 /* 22 * Utility functions related to sending OCSP requests and extracting relevant 23 * information from the response. 24 */ 25 26 /* 27 * Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ pointer: 28 * useful if we want to add extensions. 29 */ 30 31 OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid) 32 { 33 OCSP_ONEREQ *one = NULL; 34 35 if ((one = OCSP_ONEREQ_new()) == NULL) 36 return NULL; 37 OCSP_CERTID_free(one->reqCert); 38 one->reqCert = cid; 39 if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest.requestList, one)) { 40 one->reqCert = NULL; /* do not free on error */ 41 goto err; 42 } 43 return one; 44 err: 45 OCSP_ONEREQ_free(one); 46 return NULL; 47 } 48 49 /* Set requestorName from an X509_NAME structure */ 50 51 int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm) 52 { 53 GENERAL_NAME *gen; 54 55 gen = GENERAL_NAME_new(); 56 if (gen == NULL) 57 return 0; 58 if (!X509_NAME_set(&gen->d.directoryName, nm)) { 59 GENERAL_NAME_free(gen); 60 return 0; 61 } 62 gen->type = GEN_DIRNAME; 63 GENERAL_NAME_free(req->tbsRequest.requestorName); 64 req->tbsRequest.requestorName = gen; 65 return 1; 66 } 67 68 /* Add a certificate to an OCSP request */ 69 70 int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert) 71 { 72 OCSP_SIGNATURE *sig; 73 if (req->optionalSignature == NULL) 74 req->optionalSignature = OCSP_SIGNATURE_new(); 75 sig = req->optionalSignature; 76 if (sig == NULL) 77 return 0; 78 if (cert == NULL) 79 return 1; 80 if (sig->certs == NULL 81 && (sig->certs = sk_X509_new_null()) == NULL) 82 return 0; 83 84 if (!sk_X509_push(sig->certs, cert)) 85 return 0; 86 X509_up_ref(cert); 87 return 1; 88 } 89 90 /* 91 * Sign an OCSP request set the requestorName to the subject name of an 92 * optional signers certificate and include one or more optional certificates 93 * in the request. Behaves like PKCS7_sign(). 94 */ 95 96 int OCSP_request_sign(OCSP_REQUEST *req, 97 X509 *signer, 98 EVP_PKEY *key, 99 const EVP_MD *dgst, 100 STACK_OF(X509) *certs, unsigned long flags) 101 { 102 int i; 103 X509 *x; 104 105 if (!OCSP_request_set1_name(req, X509_get_subject_name(signer))) 106 goto err; 107 108 if ((req->optionalSignature = OCSP_SIGNATURE_new()) == NULL) 109 goto err; 110 if (key) { 111 if (!X509_check_private_key(signer, key)) { 112 OCSPerr(OCSP_F_OCSP_REQUEST_SIGN, 113 OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 114 goto err; 115 } 116 if (!OCSP_REQUEST_sign(req, key, dgst)) 117 goto err; 118 } 119 120 if (!(flags & OCSP_NOCERTS)) { 121 if (!OCSP_request_add1_cert(req, signer)) 122 goto err; 123 for (i = 0; i < sk_X509_num(certs); i++) { 124 x = sk_X509_value(certs, i); 125 if (!OCSP_request_add1_cert(req, x)) 126 goto err; 127 } 128 } 129 130 return 1; 131 err: 132 OCSP_SIGNATURE_free(req->optionalSignature); 133 req->optionalSignature = NULL; 134 return 0; 135 } 136 137 /* Get response status */ 138 139 int OCSP_response_status(OCSP_RESPONSE *resp) 140 { 141 return ASN1_ENUMERATED_get(resp->responseStatus); 142 } 143 144 /* 145 * Extract basic response from OCSP_RESPONSE or NULL if no basic response 146 * present. 147 */ 148 149 OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp) 150 { 151 OCSP_RESPBYTES *rb; 152 rb = resp->responseBytes; 153 if (!rb) { 154 OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA); 155 return NULL; 156 } 157 if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { 158 OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE); 159 return NULL; 160 } 161 162 return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP)); 163 } 164 165 const ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs) 166 { 167 return bs->signature; 168 } 169 170 const X509_ALGOR *OCSP_resp_get0_tbs_sigalg(const OCSP_BASICRESP *bs) 171 { 172 return &bs->signatureAlgorithm; 173 } 174 175 const OCSP_RESPDATA *OCSP_resp_get0_respdata(const OCSP_BASICRESP *bs) 176 { 177 return &bs->tbsResponseData; 178 } 179 180 /* 181 * Return number of OCSP_SINGLERESP responses present in a basic response. 182 */ 183 184 int OCSP_resp_count(OCSP_BASICRESP *bs) 185 { 186 if (!bs) 187 return -1; 188 return sk_OCSP_SINGLERESP_num(bs->tbsResponseData.responses); 189 } 190 191 /* Extract an OCSP_SINGLERESP response with a given index */ 192 193 OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx) 194 { 195 if (!bs) 196 return NULL; 197 return sk_OCSP_SINGLERESP_value(bs->tbsResponseData.responses, idx); 198 } 199 200 const ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP* bs) 201 { 202 return bs->tbsResponseData.producedAt; 203 } 204 205 const STACK_OF(X509) *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs) 206 { 207 return bs->certs; 208 } 209 210 int OCSP_resp_get0_id(const OCSP_BASICRESP *bs, 211 const ASN1_OCTET_STRING **pid, 212 const X509_NAME **pname) 213 { 214 const OCSP_RESPID *rid = &bs->tbsResponseData.responderId; 215 216 if (rid->type == V_OCSP_RESPID_NAME) { 217 *pname = rid->value.byName; 218 *pid = NULL; 219 } else if (rid->type == V_OCSP_RESPID_KEY) { 220 *pid = rid->value.byKey; 221 *pname = NULL; 222 } else { 223 return 0; 224 } 225 return 1; 226 } 227 228 int OCSP_resp_get1_id(const OCSP_BASICRESP *bs, 229 ASN1_OCTET_STRING **pid, 230 X509_NAME **pname) 231 { 232 const OCSP_RESPID *rid = &bs->tbsResponseData.responderId; 233 234 if (rid->type == V_OCSP_RESPID_NAME) { 235 *pname = X509_NAME_dup(rid->value.byName); 236 *pid = NULL; 237 } else if (rid->type == V_OCSP_RESPID_KEY) { 238 *pid = ASN1_OCTET_STRING_dup(rid->value.byKey); 239 *pname = NULL; 240 } else { 241 return 0; 242 } 243 if (*pname == NULL && *pid == NULL) 244 return 0; 245 return 1; 246 } 247 248 /* Look single response matching a given certificate ID */ 249 250 int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last) 251 { 252 int i; 253 STACK_OF(OCSP_SINGLERESP) *sresp; 254 OCSP_SINGLERESP *single; 255 if (!bs) 256 return -1; 257 if (last < 0) 258 last = 0; 259 else 260 last++; 261 sresp = bs->tbsResponseData.responses; 262 for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++) { 263 single = sk_OCSP_SINGLERESP_value(sresp, i); 264 if (!OCSP_id_cmp(id, single->certId)) 265 return i; 266 } 267 return -1; 268 } 269 270 /* 271 * Extract status information from an OCSP_SINGLERESP structure. Note: the 272 * revtime and reason values are only set if the certificate status is 273 * revoked. Returns numerical value of status. 274 */ 275 276 int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, 277 ASN1_GENERALIZEDTIME **revtime, 278 ASN1_GENERALIZEDTIME **thisupd, 279 ASN1_GENERALIZEDTIME **nextupd) 280 { 281 int ret; 282 OCSP_CERTSTATUS *cst; 283 if (!single) 284 return -1; 285 cst = single->certStatus; 286 ret = cst->type; 287 if (ret == V_OCSP_CERTSTATUS_REVOKED) { 288 OCSP_REVOKEDINFO *rev = cst->value.revoked; 289 if (revtime) 290 *revtime = rev->revocationTime; 291 if (reason) { 292 if (rev->revocationReason) 293 *reason = ASN1_ENUMERATED_get(rev->revocationReason); 294 else 295 *reason = -1; 296 } 297 } 298 if (thisupd) 299 *thisupd = single->thisUpdate; 300 if (nextupd) 301 *nextupd = single->nextUpdate; 302 return ret; 303 } 304 305 /* 306 * This function combines the previous ones: look up a certificate ID and if 307 * found extract status information. Return 0 is successful. 308 */ 309 310 int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, 311 int *reason, 312 ASN1_GENERALIZEDTIME **revtime, 313 ASN1_GENERALIZEDTIME **thisupd, 314 ASN1_GENERALIZEDTIME **nextupd) 315 { 316 int i; 317 OCSP_SINGLERESP *single; 318 i = OCSP_resp_find(bs, id, -1); 319 /* Maybe check for multiple responses and give an error? */ 320 if (i < 0) 321 return 0; 322 single = OCSP_resp_get0(bs, i); 323 i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd); 324 if (status) 325 *status = i; 326 return 1; 327 } 328 329 /* 330 * Check validity of thisUpdate and nextUpdate fields. It is possible that 331 * the request will take a few seconds to process and/or the time won't be 332 * totally accurate. Therefore to avoid rejecting otherwise valid time we 333 * allow the times to be within 'nsec' of the current time. Also to avoid 334 * accepting very old responses without a nextUpdate field an optional maxage 335 * parameter specifies the maximum age the thisUpdate field can be. 336 */ 337 338 int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, 339 ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec) 340 { 341 int ret = 1; 342 time_t t_now, t_tmp; 343 time(&t_now); 344 /* Check thisUpdate is valid and not more than nsec in the future */ 345 if (!ASN1_GENERALIZEDTIME_check(thisupd)) { 346 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD); 347 ret = 0; 348 } else { 349 t_tmp = t_now + nsec; 350 if (X509_cmp_time(thisupd, &t_tmp) > 0) { 351 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID); 352 ret = 0; 353 } 354 355 /* 356 * If maxsec specified check thisUpdate is not more than maxsec in 357 * the past 358 */ 359 if (maxsec >= 0) { 360 t_tmp = t_now - maxsec; 361 if (X509_cmp_time(thisupd, &t_tmp) < 0) { 362 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD); 363 ret = 0; 364 } 365 } 366 } 367 368 if (!nextupd) 369 return ret; 370 371 /* Check nextUpdate is valid and not more than nsec in the past */ 372 if (!ASN1_GENERALIZEDTIME_check(nextupd)) { 373 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD); 374 ret = 0; 375 } else { 376 t_tmp = t_now - nsec; 377 if (X509_cmp_time(nextupd, &t_tmp) < 0) { 378 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED); 379 ret = 0; 380 } 381 } 382 383 /* Also don't allow nextUpdate to precede thisUpdate */ 384 if (ASN1_STRING_cmp(nextupd, thisupd) < 0) { 385 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, 386 OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE); 387 ret = 0; 388 } 389 390 return ret; 391 } 392 393 const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *single) 394 { 395 return single->certId; 396 } 397