| Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/libressl/src/tls/tls_ocsp.c |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | /* | - | ||||||||||||||||||||||||
| 2 | * Copyright (c) 2015 Marko Kreen <markokr@gmail.com> | - | ||||||||||||||||||||||||
| 3 | * Copyright (c) 2016 Bob Beck <beck@openbsd.org> | - | ||||||||||||||||||||||||
| 4 | * | - | ||||||||||||||||||||||||
| 5 | * Permission to use, copy, modify, and distribute this software for any | - | ||||||||||||||||||||||||
| 6 | * purpose with or without fee is hereby granted, provided that the above | - | ||||||||||||||||||||||||
| 7 | * copyright notice and this permission notice appear in all copies. | - | ||||||||||||||||||||||||
| 8 | * | - | ||||||||||||||||||||||||
| 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | - | ||||||||||||||||||||||||
| 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | - | ||||||||||||||||||||||||
| 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | - | ||||||||||||||||||||||||
| 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | - | ||||||||||||||||||||||||
| 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | - | ||||||||||||||||||||||||
| 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | - | ||||||||||||||||||||||||
| 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | - | ||||||||||||||||||||||||
| 16 | */ | - | ||||||||||||||||||||||||
| 17 | - | |||||||||||||||||||||||||
| 18 | #include <sys/types.h> | - | ||||||||||||||||||||||||
| 19 | - | |||||||||||||||||||||||||
| 20 | #include <arpa/inet.h> | - | ||||||||||||||||||||||||
| 21 | #include <netinet/in.h> | - | ||||||||||||||||||||||||
| 22 | - | |||||||||||||||||||||||||
| 23 | #include <openssl/err.h> | - | ||||||||||||||||||||||||
| 24 | #include <openssl/ocsp.h> | - | ||||||||||||||||||||||||
| 25 | #include <openssl/x509.h> | - | ||||||||||||||||||||||||
| 26 | - | |||||||||||||||||||||||||
| 27 | #include <tls.h> | - | ||||||||||||||||||||||||
| 28 | #include "tls_internal.h" | - | ||||||||||||||||||||||||
| 29 | - | |||||||||||||||||||||||||
| 30 | #define MAXAGE_SEC (14*24*60*60) | - | ||||||||||||||||||||||||
| 31 | #define JITTER_SEC (60) | - | ||||||||||||||||||||||||
| 32 | - | |||||||||||||||||||||||||
| 33 | /* | - | ||||||||||||||||||||||||
| 34 | * State for request. | - | ||||||||||||||||||||||||
| 35 | */ | - | ||||||||||||||||||||||||
| 36 | - | |||||||||||||||||||||||||
| 37 | static struct tls_ocsp * | - | ||||||||||||||||||||||||
| 38 | tls_ocsp_new(void) | - | ||||||||||||||||||||||||
| 39 | { | - | ||||||||||||||||||||||||
| 40 | return (calloc(1, sizeof(struct tls_ocsp))); executed 8 times by 1 test: return (calloc(1, sizeof(struct tls_ocsp)));Executed by:
| 8 | ||||||||||||||||||||||||
| 41 | } | - | ||||||||||||||||||||||||
| 42 | - | |||||||||||||||||||||||||
| 43 | void | - | ||||||||||||||||||||||||
| 44 | tls_ocsp_free(struct tls_ocsp *ocsp) | - | ||||||||||||||||||||||||
| 45 | { | - | ||||||||||||||||||||||||
| 46 | if (ocsp == NULL)
| 8-78 | ||||||||||||||||||||||||
| 47 | return; executed 78 times by 2 tests: return;Executed by:
| 78 | ||||||||||||||||||||||||
| 48 | - | |||||||||||||||||||||||||
| 49 | X509_free(ocsp->main_cert); | - | ||||||||||||||||||||||||
| 50 | free(ocsp->ocsp_result); | - | ||||||||||||||||||||||||
| 51 | free(ocsp->ocsp_url); | - | ||||||||||||||||||||||||
| 52 | - | |||||||||||||||||||||||||
| 53 | free(ocsp); | - | ||||||||||||||||||||||||
| 54 | } executed 8 times by 1 test: end of blockExecuted by:
| 8 | ||||||||||||||||||||||||
| 55 | - | |||||||||||||||||||||||||
| 56 | static int | - | ||||||||||||||||||||||||
| 57 | tls_ocsp_asn1_parse_time(struct tls *ctx, ASN1_GENERALIZEDTIME *gt, time_t *gt_time) | - | ||||||||||||||||||||||||
| 58 | { | - | ||||||||||||||||||||||||
| 59 | struct tm tm; | - | ||||||||||||||||||||||||
| 60 | - | |||||||||||||||||||||||||
| 61 | if (gt == NULL)
| 0 | ||||||||||||||||||||||||
| 62 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 63 | /* RFC 6960 specifies that all times in OCSP must be GENERALIZEDTIME */ | - | ||||||||||||||||||||||||
| 64 | if (ASN1_time_parse(gt->data, gt->length, &tm,
| 0 | ||||||||||||||||||||||||
| 65 | V_ASN1_GENERALIZEDTIME) == -1)
| 0 | ||||||||||||||||||||||||
| 66 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 67 | if ((*gt_time = timegm(&tm)) == -1)
| 0 | ||||||||||||||||||||||||
| 68 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 69 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||
| 70 | } | - | ||||||||||||||||||||||||
| 71 | - | |||||||||||||||||||||||||
| 72 | static int | - | ||||||||||||||||||||||||
| 73 | tls_ocsp_fill_info(struct tls *ctx, int response_status, int cert_status, | - | ||||||||||||||||||||||||
| 74 | int crl_reason, ASN1_GENERALIZEDTIME *revtime, | - | ||||||||||||||||||||||||
| 75 | ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd) | - | ||||||||||||||||||||||||
| 76 | { | - | ||||||||||||||||||||||||
| 77 | struct tls_ocsp_result *info = NULL; | - | ||||||||||||||||||||||||
| 78 | - | |||||||||||||||||||||||||
| 79 | free(ctx->ocsp->ocsp_result); | - | ||||||||||||||||||||||||
| 80 | ctx->ocsp->ocsp_result = NULL; | - | ||||||||||||||||||||||||
| 81 | - | |||||||||||||||||||||||||
| 82 | if ((info = calloc(1, sizeof (struct tls_ocsp_result))) == NULL) {
| 0 | ||||||||||||||||||||||||
| 83 | tls_set_error(ctx, "calloc"); | - | ||||||||||||||||||||||||
| 84 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 85 | } | - | ||||||||||||||||||||||||
| 86 | info->response_status = response_status; | - | ||||||||||||||||||||||||
| 87 | info->cert_status = cert_status; | - | ||||||||||||||||||||||||
| 88 | info->crl_reason = crl_reason; | - | ||||||||||||||||||||||||
| 89 | if (info->response_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
| 0 | ||||||||||||||||||||||||
| 90 | info->result_msg = | - | ||||||||||||||||||||||||
| 91 | OCSP_response_status_str(info->response_status); | - | ||||||||||||||||||||||||
| 92 | } else if (info->cert_status != V_OCSP_CERTSTATUS_REVOKED) { never executed: end of block
| 0 | ||||||||||||||||||||||||
| 93 | info->result_msg = OCSP_cert_status_str(info->cert_status); | - | ||||||||||||||||||||||||
| 94 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||
| 95 | info->result_msg = OCSP_crl_reason_str(info->crl_reason); | - | ||||||||||||||||||||||||
| 96 | } never executed: end of block | 0 | ||||||||||||||||||||||||
| 97 | info->revocation_time = info->this_update = info->next_update = -1; | - | ||||||||||||||||||||||||
| 98 | if (revtime != NULL &&
| 0 | ||||||||||||||||||||||||
| 99 | tls_ocsp_asn1_parse_time(ctx, revtime, &info->revocation_time) != 0) {
| 0 | ||||||||||||||||||||||||
| 100 | tls_set_error(ctx, | - | ||||||||||||||||||||||||
| 101 | "unable to parse revocation time in OCSP reply"); | - | ||||||||||||||||||||||||
| 102 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 103 | } | - | ||||||||||||||||||||||||
| 104 | if (thisupd != NULL &&
| 0 | ||||||||||||||||||||||||
| 105 | tls_ocsp_asn1_parse_time(ctx, thisupd, &info->this_update) != 0) {
| 0 | ||||||||||||||||||||||||
| 106 | tls_set_error(ctx, | - | ||||||||||||||||||||||||
| 107 | "unable to parse this update time in OCSP reply"); | - | ||||||||||||||||||||||||
| 108 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 109 | } | - | ||||||||||||||||||||||||
| 110 | if (nextupd != NULL &&
| 0 | ||||||||||||||||||||||||
| 111 | tls_ocsp_asn1_parse_time(ctx, nextupd, &info->next_update) != 0) {
| 0 | ||||||||||||||||||||||||
| 112 | tls_set_error(ctx, | - | ||||||||||||||||||||||||
| 113 | "unable to parse next update time in OCSP reply"); | - | ||||||||||||||||||||||||
| 114 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 115 | } | - | ||||||||||||||||||||||||
| 116 | ctx->ocsp->ocsp_result = info; | - | ||||||||||||||||||||||||
| 117 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||
| 118 | - | |||||||||||||||||||||||||
| 119 | err: | - | ||||||||||||||||||||||||
| 120 | free(info); | - | ||||||||||||||||||||||||
| 121 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 122 | } | - | ||||||||||||||||||||||||
| 123 | - | |||||||||||||||||||||||||
| 124 | static OCSP_CERTID * | - | ||||||||||||||||||||||||
| 125 | tls_ocsp_get_certid(X509 *main_cert, STACK_OF(X509) *extra_certs, | - | ||||||||||||||||||||||||
| 126 | SSL_CTX *ssl_ctx) | - | ||||||||||||||||||||||||
| 127 | { | - | ||||||||||||||||||||||||
| 128 | X509_NAME *issuer_name; | - | ||||||||||||||||||||||||
| 129 | X509 *issuer; | - | ||||||||||||||||||||||||
| 130 | X509_STORE_CTX storectx; | - | ||||||||||||||||||||||||
| 131 | X509_OBJECT tmpobj; | - | ||||||||||||||||||||||||
| 132 | OCSP_CERTID *cid = NULL; | - | ||||||||||||||||||||||||
| 133 | X509_STORE *store; | - | ||||||||||||||||||||||||
| 134 | - | |||||||||||||||||||||||||
| 135 | if ((issuer_name = X509_get_issuer_name(main_cert)) == NULL)
| 0 | ||||||||||||||||||||||||
| 136 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||||||||
| 137 | - | |||||||||||||||||||||||||
| 138 | if (extra_certs != NULL) {
| 0 | ||||||||||||||||||||||||
| 139 | issuer = X509_find_by_subject(extra_certs, issuer_name); | - | ||||||||||||||||||||||||
| 140 | if (issuer != NULL)
| 0 | ||||||||||||||||||||||||
| 141 | return OCSP_cert_to_id(NULL, main_cert, issuer); never executed: return OCSP_cert_to_id( ((void *)0) , main_cert, issuer); | 0 | ||||||||||||||||||||||||
| 142 | } never executed: end of block | 0 | ||||||||||||||||||||||||
| 143 | - | |||||||||||||||||||||||||
| 144 | if ((store = SSL_CTX_get_cert_store(ssl_ctx)) == NULL)
| 0 | ||||||||||||||||||||||||
| 145 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||||||||
| 146 | if (X509_STORE_CTX_init(&storectx, store, main_cert, extra_certs) != 1)
| 0 | ||||||||||||||||||||||||
| 147 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||||||||
| 148 | if (X509_STORE_get_by_subject(&storectx, X509_LU_X509, issuer_name,
| 0 | ||||||||||||||||||||||||
| 149 | &tmpobj) == 1) {
| 0 | ||||||||||||||||||||||||
| 150 | cid = OCSP_cert_to_id(NULL, main_cert, tmpobj.data.x509); | - | ||||||||||||||||||||||||
| 151 | X509_OBJECT_free_contents(&tmpobj); | - | ||||||||||||||||||||||||
| 152 | } never executed: end of block | 0 | ||||||||||||||||||||||||
| 153 | X509_STORE_CTX_cleanup(&storectx); | - | ||||||||||||||||||||||||
| 154 | return cid; never executed: return cid; | 0 | ||||||||||||||||||||||||
| 155 | } | - | ||||||||||||||||||||||||
| 156 | - | |||||||||||||||||||||||||
| 157 | struct tls_ocsp * | - | ||||||||||||||||||||||||
| 158 | tls_ocsp_setup_from_peer(struct tls *ctx) | - | ||||||||||||||||||||||||
| 159 | { | - | ||||||||||||||||||||||||
| 160 | struct tls_ocsp *ocsp = NULL; | - | ||||||||||||||||||||||||
| 161 | STACK_OF(OPENSSL_STRING) *ocsp_urls = NULL; | - | ||||||||||||||||||||||||
| 162 | - | |||||||||||||||||||||||||
| 163 | if ((ocsp = tls_ocsp_new()) == NULL)
| 0-8 | ||||||||||||||||||||||||
| 164 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 165 | - | |||||||||||||||||||||||||
| 166 | /* steal state from ctx struct */ | - | ||||||||||||||||||||||||
| 167 | ocsp->main_cert = SSL_get_peer_certificate(ctx->ssl_conn); | - | ||||||||||||||||||||||||
| 168 | ocsp->extra_certs = SSL_get_peer_cert_chain(ctx->ssl_conn); | - | ||||||||||||||||||||||||
| 169 | if (ocsp->main_cert == NULL) {
| 4 | ||||||||||||||||||||||||
| 170 | tls_set_errorx(ctx, "no peer certificate for OCSP"); | - | ||||||||||||||||||||||||
| 171 | goto err; executed 4 times by 1 test: goto err;Executed by:
| 4 | ||||||||||||||||||||||||
| 172 | } | - | ||||||||||||||||||||||||
| 173 | - | |||||||||||||||||||||||||
| 174 | ocsp_urls = X509_get1_ocsp(ocsp->main_cert); | - | ||||||||||||||||||||||||
| 175 | if (ocsp_urls == NULL) {
| 0-4 | ||||||||||||||||||||||||
| 176 | tls_set_errorx(ctx, "no OCSP URLs in peer certificate"); | - | ||||||||||||||||||||||||
| 177 | goto err; executed 4 times by 1 test: goto err;Executed by:
| 4 | ||||||||||||||||||||||||
| 178 | } | - | ||||||||||||||||||||||||
| 179 | - | |||||||||||||||||||||||||
| 180 | ocsp->ocsp_url = strdup(sk_OPENSSL_STRING_value(ocsp_urls, 0)); never executed: __retval = (char *) memcpy (__retval, ((OPENSSL_STRING)sk_value(((_STACK*) (1 ? ocsp_urls : (struct stack_st_OPENSSL_STRING*)0)), 0)) , __len);
| 0 | ||||||||||||||||||||||||
| 181 | if (ocsp->ocsp_url == NULL) {
| 0 | ||||||||||||||||||||||||
| 182 | tls_set_errorx(ctx, "out of memory"); | - | ||||||||||||||||||||||||
| 183 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 184 | } | - | ||||||||||||||||||||||||
| 185 | - | |||||||||||||||||||||||||
| 186 | X509_email_free(ocsp_urls); | - | ||||||||||||||||||||||||
| 187 | return ocsp; never executed: return ocsp; | 0 | ||||||||||||||||||||||||
| 188 | - | |||||||||||||||||||||||||
| 189 | err: | - | ||||||||||||||||||||||||
| 190 | tls_ocsp_free(ocsp); | - | ||||||||||||||||||||||||
| 191 | X509_email_free(ocsp_urls); | - | ||||||||||||||||||||||||
| 192 | return NULL; executed 8 times by 1 test: return ((void *)0) ;Executed by:
| 8 | ||||||||||||||||||||||||
| 193 | } | - | ||||||||||||||||||||||||
| 194 | - | |||||||||||||||||||||||||
| 195 | static int | - | ||||||||||||||||||||||||
| 196 | tls_ocsp_verify_response(struct tls *ctx, OCSP_RESPONSE *resp) | - | ||||||||||||||||||||||||
| 197 | { | - | ||||||||||||||||||||||||
| 198 | OCSP_BASICRESP *br = NULL; | - | ||||||||||||||||||||||||
| 199 | ASN1_GENERALIZEDTIME *revtime = NULL, *thisupd = NULL, *nextupd = NULL; | - | ||||||||||||||||||||||||
| 200 | OCSP_CERTID *cid = NULL; | - | ||||||||||||||||||||||||
| 201 | STACK_OF(X509) *combined = NULL; | - | ||||||||||||||||||||||||
| 202 | int response_status=0, cert_status=0, crl_reason=0; | - | ||||||||||||||||||||||||
| 203 | int ret = -1; | - | ||||||||||||||||||||||||
| 204 | unsigned long flags; | - | ||||||||||||||||||||||||
| 205 | - | |||||||||||||||||||||||||
| 206 | if ((br = OCSP_response_get1_basic(resp)) == NULL) {
| 0 | ||||||||||||||||||||||||
| 207 | tls_set_errorx(ctx, "cannot load ocsp reply"); | - | ||||||||||||||||||||||||
| 208 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 209 | } | - | ||||||||||||||||||||||||
| 210 | - | |||||||||||||||||||||||||
| 211 | /* | - | ||||||||||||||||||||||||
| 212 | * Skip validation of 'extra_certs' as this should be done | - | ||||||||||||||||||||||||
| 213 | * already as part of main handshake. | - | ||||||||||||||||||||||||
| 214 | */ | - | ||||||||||||||||||||||||
| 215 | flags = OCSP_TRUSTOTHER; | - | ||||||||||||||||||||||||
| 216 | - | |||||||||||||||||||||||||
| 217 | /* now verify */ | - | ||||||||||||||||||||||||
| 218 | if (OCSP_basic_verify(br, ctx->ocsp->extra_certs,
| 0 | ||||||||||||||||||||||||
| 219 | SSL_CTX_get_cert_store(ctx->ssl_ctx), flags) != 1) {
| 0 | ||||||||||||||||||||||||
| 220 | tls_set_error(ctx, "ocsp verify failed"); | - | ||||||||||||||||||||||||
| 221 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 222 | } | - | ||||||||||||||||||||||||
| 223 | - | |||||||||||||||||||||||||
| 224 | /* signature OK, look inside */ | - | ||||||||||||||||||||||||
| 225 | response_status = OCSP_response_status(resp); | - | ||||||||||||||||||||||||
| 226 | if (response_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
| 0 | ||||||||||||||||||||||||
| 227 | tls_set_errorx(ctx, "ocsp verify failed: response - %s", | - | ||||||||||||||||||||||||
| 228 | OCSP_response_status_str(response_status)); | - | ||||||||||||||||||||||||
| 229 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 230 | } | - | ||||||||||||||||||||||||
| 231 | - | |||||||||||||||||||||||||
| 232 | cid = tls_ocsp_get_certid(ctx->ocsp->main_cert, | - | ||||||||||||||||||||||||
| 233 | ctx->ocsp->extra_certs, ctx->ssl_ctx); | - | ||||||||||||||||||||||||
| 234 | if (cid == NULL) {
| 0 | ||||||||||||||||||||||||
| 235 | tls_set_errorx(ctx, "ocsp verify failed: no issuer cert"); | - | ||||||||||||||||||||||||
| 236 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 237 | } | - | ||||||||||||||||||||||||
| 238 | - | |||||||||||||||||||||||||
| 239 | if (OCSP_resp_find_status(br, cid, &cert_status, &crl_reason,
| 0 | ||||||||||||||||||||||||
| 240 | &revtime, &thisupd, &nextupd) != 1) {
| 0 | ||||||||||||||||||||||||
| 241 | tls_set_errorx(ctx, "ocsp verify failed: no result for cert"); | - | ||||||||||||||||||||||||
| 242 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 243 | } | - | ||||||||||||||||||||||||
| 244 | - | |||||||||||||||||||||||||
| 245 | if (OCSP_check_validity(thisupd, nextupd, JITTER_SEC,
| 0 | ||||||||||||||||||||||||
| 246 | MAXAGE_SEC) != 1) {
| 0 | ||||||||||||||||||||||||
| 247 | tls_set_errorx(ctx, | - | ||||||||||||||||||||||||
| 248 | "ocsp verify failed: ocsp response not current"); | - | ||||||||||||||||||||||||
| 249 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 250 | } | - | ||||||||||||||||||||||||
| 251 | - | |||||||||||||||||||||||||
| 252 | if (tls_ocsp_fill_info(ctx, response_status, cert_status,
| 0 | ||||||||||||||||||||||||
| 253 | crl_reason, revtime, thisupd, nextupd) != 0)
| 0 | ||||||||||||||||||||||||
| 254 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 255 | - | |||||||||||||||||||||||||
| 256 | /* finally can look at status */ | - | ||||||||||||||||||||||||
| 257 | if (cert_status != V_OCSP_CERTSTATUS_GOOD && cert_status !=
| 0 | ||||||||||||||||||||||||
| 258 | V_OCSP_CERTSTATUS_UNKNOWN) {
| 0 | ||||||||||||||||||||||||
| 259 | tls_set_errorx(ctx, "ocsp verify failed: revoked cert - %s", | - | ||||||||||||||||||||||||
| 260 | OCSP_crl_reason_str(crl_reason)); | - | ||||||||||||||||||||||||
| 261 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 262 | } | - | ||||||||||||||||||||||||
| 263 | ret = 0; | - | ||||||||||||||||||||||||
| 264 | - | |||||||||||||||||||||||||
| 265 | err: code before this statement never executed: err: | 0 | ||||||||||||||||||||||||
| 266 | sk_X509_free(combined); | - | ||||||||||||||||||||||||
| 267 | OCSP_CERTID_free(cid); | - | ||||||||||||||||||||||||
| 268 | OCSP_BASICRESP_free(br); | - | ||||||||||||||||||||||||
| 269 | return ret; never executed: return ret; | 0 | ||||||||||||||||||||||||
| 270 | } | - | ||||||||||||||||||||||||
| 271 | - | |||||||||||||||||||||||||
| 272 | /* | - | ||||||||||||||||||||||||
| 273 | * Process a raw OCSP response from an OCSP server request. | - | ||||||||||||||||||||||||
| 274 | * OCSP details can then be retrieved with tls_peer_ocsp_* functions. | - | ||||||||||||||||||||||||
| 275 | * returns 0 if certificate ok, -1 otherwise. | - | ||||||||||||||||||||||||
| 276 | */ | - | ||||||||||||||||||||||||
| 277 | static int | - | ||||||||||||||||||||||||
| 278 | tls_ocsp_process_response_internal(struct tls *ctx, const unsigned char *response, | - | ||||||||||||||||||||||||
| 279 | size_t size) | - | ||||||||||||||||||||||||
| 280 | { | - | ||||||||||||||||||||||||
| 281 | int ret; | - | ||||||||||||||||||||||||
| 282 | OCSP_RESPONSE *resp; | - | ||||||||||||||||||||||||
| 283 | - | |||||||||||||||||||||||||
| 284 | resp = d2i_OCSP_RESPONSE(NULL, &response, size); | - | ||||||||||||||||||||||||
| 285 | if (resp == NULL) {
| 0 | ||||||||||||||||||||||||
| 286 | tls_ocsp_free(ctx->ocsp); | - | ||||||||||||||||||||||||
| 287 | ctx->ocsp = NULL; | - | ||||||||||||||||||||||||
| 288 | tls_set_error(ctx, "unable to parse OCSP response"); | - | ||||||||||||||||||||||||
| 289 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 290 | } | - | ||||||||||||||||||||||||
| 291 | ret = tls_ocsp_verify_response(ctx, resp); | - | ||||||||||||||||||||||||
| 292 | OCSP_RESPONSE_free(resp); | - | ||||||||||||||||||||||||
| 293 | return ret; never executed: return ret; | 0 | ||||||||||||||||||||||||
| 294 | } | - | ||||||||||||||||||||||||
| 295 | - | |||||||||||||||||||||||||
| 296 | /* TLS handshake verification callback for stapled requests */ | - | ||||||||||||||||||||||||
| 297 | int | - | ||||||||||||||||||||||||
| 298 | tls_ocsp_verify_cb(SSL *ssl, void *arg) | - | ||||||||||||||||||||||||
| 299 | { | - | ||||||||||||||||||||||||
| 300 | const unsigned char *raw = NULL; | - | ||||||||||||||||||||||||
| 301 | int size, res = -1; | - | ||||||||||||||||||||||||
| 302 | struct tls *ctx; | - | ||||||||||||||||||||||||
| 303 | - | |||||||||||||||||||||||||
| 304 | if ((ctx = SSL_get_app_data(ssl)) == NULL)
| 0-4 | ||||||||||||||||||||||||
| 305 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 306 | - | |||||||||||||||||||||||||
| 307 | size = SSL_get_tlsext_status_ocsp_resp(ssl, &raw); | - | ||||||||||||||||||||||||
| 308 | if (size <= 0) {
| 0-4 | ||||||||||||||||||||||||
| 309 | if (ctx->config->ocsp_require_stapling) {
| 0-4 | ||||||||||||||||||||||||
| 310 | tls_set_errorx(ctx, "no stapled OCSP response provided"); | - | ||||||||||||||||||||||||
| 311 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||
| 312 | } | - | ||||||||||||||||||||||||
| 313 | return 1; executed 4 times by 1 test: return 1;Executed by:
| 4 | ||||||||||||||||||||||||
| 314 | } | - | ||||||||||||||||||||||||
| 315 | - | |||||||||||||||||||||||||
| 316 | tls_ocsp_free(ctx->ocsp); | - | ||||||||||||||||||||||||
| 317 | if ((ctx->ocsp = tls_ocsp_setup_from_peer(ctx)) == NULL)
| 0 | ||||||||||||||||||||||||
| 318 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||
| 319 | - | |||||||||||||||||||||||||
| 320 | if (ctx->config->verify_cert == 0 || ctx->config->verify_time == 0)
| 0 | ||||||||||||||||||||||||
| 321 | return 1; never executed: return 1; | 0 | ||||||||||||||||||||||||
| 322 | - | |||||||||||||||||||||||||
| 323 | res = tls_ocsp_process_response_internal(ctx, raw, size); | - | ||||||||||||||||||||||||
| 324 | - | |||||||||||||||||||||||||
| 325 | return (res == 0) ? 1 : 0; never executed: return (res == 0) ? 1 : 0;
| 0 | ||||||||||||||||||||||||
| 326 | } | - | ||||||||||||||||||||||||
| 327 | - | |||||||||||||||||||||||||
| 328 | - | |||||||||||||||||||||||||
| 329 | /* Staple the OCSP information in ctx->ocsp to the server handshake. */ | - | ||||||||||||||||||||||||
| 330 | int | - | ||||||||||||||||||||||||
| 331 | tls_ocsp_stapling_cb(SSL *ssl, void *arg) | - | ||||||||||||||||||||||||
| 332 | { | - | ||||||||||||||||||||||||
| 333 | int ret = SSL_TLSEXT_ERR_ALERT_FATAL; | - | ||||||||||||||||||||||||
| 334 | unsigned char *ocsp_staple = NULL; | - | ||||||||||||||||||||||||
| 335 | struct tls *ctx; | - | ||||||||||||||||||||||||
| 336 | - | |||||||||||||||||||||||||
| 337 | if ((ctx = SSL_get_app_data(ssl)) == NULL)
| 0-4 | ||||||||||||||||||||||||
| 338 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 339 | - | |||||||||||||||||||||||||
| 340 | if (ctx->keypair == NULL || ctx->keypair->ocsp_staple == NULL ||
| 0-4 | ||||||||||||||||||||||||
| 341 | ctx->keypair->ocsp_staple_len == 0)
| 0 | ||||||||||||||||||||||||
| 342 | return SSL_TLSEXT_ERR_NOACK; executed 4 times by 1 test: return 3;Executed by:
| 4 | ||||||||||||||||||||||||
| 343 | - | |||||||||||||||||||||||||
| 344 | if ((ocsp_staple = malloc(ctx->keypair->ocsp_staple_len)) == NULL)
| 0 | ||||||||||||||||||||||||
| 345 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 346 | - | |||||||||||||||||||||||||
| 347 | memcpy(ocsp_staple, ctx->keypair->ocsp_staple, | - | ||||||||||||||||||||||||
| 348 | ctx->keypair->ocsp_staple_len); | - | ||||||||||||||||||||||||
| 349 | - | |||||||||||||||||||||||||
| 350 | if (SSL_set_tlsext_status_ocsp_resp(ctx->ssl_conn, ocsp_staple,
| 0 | ||||||||||||||||||||||||
| 351 | ctx->keypair->ocsp_staple_len) != 1)
| 0 | ||||||||||||||||||||||||
| 352 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||
| 353 | - | |||||||||||||||||||||||||
| 354 | ret = SSL_TLSEXT_ERR_OK; | - | ||||||||||||||||||||||||
| 355 | err: code before this statement never executed: err: | 0 | ||||||||||||||||||||||||
| 356 | if (ret != SSL_TLSEXT_ERR_OK)
| 0 | ||||||||||||||||||||||||
| 357 | free(ocsp_staple); never executed: free(ocsp_staple); | 0 | ||||||||||||||||||||||||
| 358 | - | |||||||||||||||||||||||||
| 359 | return ret; never executed: return ret; | 0 | ||||||||||||||||||||||||
| 360 | } | - | ||||||||||||||||||||||||
| 361 | - | |||||||||||||||||||||||||
| 362 | /* | - | ||||||||||||||||||||||||
| 363 | * Public API | - | ||||||||||||||||||||||||
| 364 | */ | - | ||||||||||||||||||||||||
| 365 | - | |||||||||||||||||||||||||
| 366 | /* Retrieve OCSP URL from peer certificate, if present. */ | - | ||||||||||||||||||||||||
| 367 | const char * | - | ||||||||||||||||||||||||
| 368 | tls_peer_ocsp_url(struct tls *ctx) | - | ||||||||||||||||||||||||
| 369 | { | - | ||||||||||||||||||||||||
| 370 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
| 371 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||||||||
| 372 | return ctx->ocsp->ocsp_url; never executed: return ctx->ocsp->ocsp_url; | 0 | ||||||||||||||||||||||||
| 373 | } | - | ||||||||||||||||||||||||
| 374 | - | |||||||||||||||||||||||||
| 375 | const char * | - | ||||||||||||||||||||||||
| 376 | tls_peer_ocsp_result(struct tls *ctx) | - | ||||||||||||||||||||||||
| 377 | { | - | ||||||||||||||||||||||||
| 378 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
| 379 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||||||||
| 380 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
| 381 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||||||||
| 382 | return ctx->ocsp->ocsp_result->result_msg; never executed: return ctx->ocsp->ocsp_result->result_msg; | 0 | ||||||||||||||||||||||||
| 383 | } | - | ||||||||||||||||||||||||
| 384 | - | |||||||||||||||||||||||||
| 385 | int | - | ||||||||||||||||||||||||
| 386 | tls_peer_ocsp_response_status(struct tls *ctx) | - | ||||||||||||||||||||||||
| 387 | { | - | ||||||||||||||||||||||||
| 388 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
| 389 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 390 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
| 391 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 392 | return ctx->ocsp->ocsp_result->response_status; never executed: return ctx->ocsp->ocsp_result->response_status; | 0 | ||||||||||||||||||||||||
| 393 | } | - | ||||||||||||||||||||||||
| 394 | - | |||||||||||||||||||||||||
| 395 | int | - | ||||||||||||||||||||||||
| 396 | tls_peer_ocsp_cert_status(struct tls *ctx) | - | ||||||||||||||||||||||||
| 397 | { | - | ||||||||||||||||||||||||
| 398 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
| 399 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 400 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
| 401 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 402 | return ctx->ocsp->ocsp_result->cert_status; never executed: return ctx->ocsp->ocsp_result->cert_status; | 0 | ||||||||||||||||||||||||
| 403 | } | - | ||||||||||||||||||||||||
| 404 | - | |||||||||||||||||||||||||
| 405 | int | - | ||||||||||||||||||||||||
| 406 | tls_peer_ocsp_crl_reason(struct tls *ctx) | - | ||||||||||||||||||||||||
| 407 | { | - | ||||||||||||||||||||||||
| 408 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
| 409 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 410 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
| 411 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 412 | return ctx->ocsp->ocsp_result->crl_reason; never executed: return ctx->ocsp->ocsp_result->crl_reason; | 0 | ||||||||||||||||||||||||
| 413 | } | - | ||||||||||||||||||||||||
| 414 | - | |||||||||||||||||||||||||
| 415 | time_t | - | ||||||||||||||||||||||||
| 416 | tls_peer_ocsp_this_update(struct tls *ctx) | - | ||||||||||||||||||||||||
| 417 | { | - | ||||||||||||||||||||||||
| 418 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
| 419 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 420 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
| 421 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 422 | return ctx->ocsp->ocsp_result->this_update; never executed: return ctx->ocsp->ocsp_result->this_update; | 0 | ||||||||||||||||||||||||
| 423 | } | - | ||||||||||||||||||||||||
| 424 | - | |||||||||||||||||||||||||
| 425 | time_t | - | ||||||||||||||||||||||||
| 426 | tls_peer_ocsp_next_update(struct tls *ctx) | - | ||||||||||||||||||||||||
| 427 | { | - | ||||||||||||||||||||||||
| 428 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
| 429 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 430 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
| 431 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 432 | return ctx->ocsp->ocsp_result->next_update; never executed: return ctx->ocsp->ocsp_result->next_update; | 0 | ||||||||||||||||||||||||
| 433 | } | - | ||||||||||||||||||||||||
| 434 | - | |||||||||||||||||||||||||
| 435 | time_t | - | ||||||||||||||||||||||||
| 436 | tls_peer_ocsp_revocation_time(struct tls *ctx) | - | ||||||||||||||||||||||||
| 437 | { | - | ||||||||||||||||||||||||
| 438 | if (ctx->ocsp == NULL)
| 0 | ||||||||||||||||||||||||
| 439 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 440 | if (ctx->ocsp->ocsp_result == NULL)
| 0 | ||||||||||||||||||||||||
| 441 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 442 | return ctx->ocsp->ocsp_result->revocation_time; never executed: return ctx->ocsp->ocsp_result->revocation_time; | 0 | ||||||||||||||||||||||||
| 443 | } | - | ||||||||||||||||||||||||
| 444 | - | |||||||||||||||||||||||||
| 445 | int | - | ||||||||||||||||||||||||
| 446 | tls_ocsp_process_response(struct tls *ctx, const unsigned char *response, | - | ||||||||||||||||||||||||
| 447 | size_t size) | - | ||||||||||||||||||||||||
| 448 | { | - | ||||||||||||||||||||||||
| 449 | if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0)
| 0 | ||||||||||||||||||||||||
| 450 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||
| 451 | return tls_ocsp_process_response_internal(ctx, response, size); never executed: return tls_ocsp_process_response_internal(ctx, response, size); | 0 | ||||||||||||||||||||||||
| 452 | } | - | ||||||||||||||||||||||||
| Source code | Switch to Preprocessed file |