1 /* Support of the Online Certificate Status Protocol (OCSP)
2 * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
3 * Zuercher Hochschule Winterthur
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 #include <sys/types.h>
27 #include <asn1/asn1.h>
28 #include <asn1/asn1_parser.h>
30 #include <crypto/rngs/rng.h>
31 #include <crypto/hashers/hasher.h>
33 #include "constants.h"
40 #include "smartcard.h"
47 #define NONCE_LENGTH 16
49 static const char *const cert_status_names
[] = {
57 static const char *const response_status_names
[] = {
67 /* response container */
68 typedef struct response response_t
;
72 chunk_t responder_id_name
;
73 chunk_t responder_id_key
;
81 const response_t empty_response
= {
82 { NULL
, 0 } , /* tbs */
83 { NULL
, 0 } , /* responder_id_name */
84 { NULL
, 0 } , /* responder_id_key */
85 UNDEFINED_TIME
, /* produced_at */
86 { NULL
, 0 } , /* single_response */
87 { NULL
, 0 } , /* nonce */
88 OID_UNKNOWN
, /* signature_algorithm */
89 { NULL
, 0 } /* signature */
92 /* single response container */
93 typedef struct single_response single_response_t
;
95 struct single_response
{
96 single_response_t
*next
;
98 chunk_t issuer_name_hash
;
99 chunk_t issuer_key_hash
;
100 chunk_t serialNumber
;
101 cert_status_t status
;
102 time_t revocationTime
;
103 crl_reason_t revocationReason
;
108 const single_response_t empty_single_response
= {
110 OID_UNKNOWN
, /* hash_algorithm */
111 { NULL
, 0 } , /* issuer_name_hash */
112 { NULL
, 0 } , /* issuer_key_hash */
113 { NULL
, 0 } , /* serial_number */
114 CERT_UNDEFINED
, /* status */
115 UNDEFINED_TIME
, /* revocationTime */
116 REASON_UNSPECIFIED
, /* revocationReason */
117 UNDEFINED_TIME
, /* this_update */
118 UNDEFINED_TIME
/* next_update */
122 /* list of single requests */
123 typedef struct request_list request_list_t
;
124 struct request_list
{
126 request_list_t
*next
;
129 /* some OCSP specific prefabricated ASN.1 constants */
131 static u_char ASN1_nonce_oid_str
[] = {
132 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
135 static const chunk_t ASN1_nonce_oid
= chunk_from_buf(ASN1_nonce_oid_str
);
137 static u_char ASN1_response_oid_str
[] = {
138 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
141 static const chunk_t ASN1_response_oid
= chunk_from_buf(ASN1_response_oid_str
);
143 static u_char ASN1_response_content_str
[] = {
146 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
149 static const chunk_t ASN1_response_content
= chunk_from_buf(ASN1_response_content_str
);
151 /* default OCSP uri */
152 static chunk_t ocsp_default_uri
;
154 /* ocsp cache: pointer to first element */
155 static ocsp_location_t
*ocsp_cache
= NULL
;
157 /* static temporary storage for ocsp requestor information */
158 static x509cert_t
*ocsp_requestor_cert
= NULL
;
160 static smartcard_t
*ocsp_requestor_sc
= NULL
;
162 static const struct RSA_private_key
*ocsp_requestor_pri
= NULL
;
165 * ASN.1 definition of ocspResponse
167 static const asn1Object_t ocspResponseObjects
[] = {
168 { 0, "OCSPResponse", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
169 { 1, "responseStatus", ASN1_ENUMERATED
, ASN1_BODY
}, /* 1 */
170 { 1, "responseBytesContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 2 */
171 { 2, "responseBytes", ASN1_SEQUENCE
, ASN1_NONE
}, /* 3 */
172 { 3, "responseType", ASN1_OID
, ASN1_BODY
}, /* 4 */
173 { 3, "response", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 5 */
174 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 6 */
175 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
177 #define OCSP_RESPONSE_STATUS 1
178 #define OCSP_RESPONSE_TYPE 4
179 #define OCSP_RESPONSE 5
182 * ASN.1 definition of basicResponse
184 static const asn1Object_t basicResponseObjects
[] = {
185 { 0, "BasicOCSPResponse", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
186 { 1, "tbsResponseData", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 1 */
187 { 2, "versionContext", ASN1_CONTEXT_C_0
, ASN1_NONE
|
189 { 3, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
190 { 2, "responderIdContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 4 */
191 { 3, "responderIdByName", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 5 */
192 { 2, "end choice", ASN1_EOC
, ASN1_END
}, /* 6 */
193 { 2, "responderIdContext", ASN1_CONTEXT_C_2
, ASN1_OPT
}, /* 7 */
194 { 3, "responderIdByKey", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 8 */
195 { 2, "end choice", ASN1_EOC
, ASN1_END
}, /* 9 */
196 { 2, "producedAt", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 10 */
197 { 2, "responses", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 11 */
198 { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 12 */
199 { 3, "responseExtensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 13 */
200 { 4, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 14 */
201 { 5, "extnID", ASN1_OID
, ASN1_BODY
}, /* 15 */
202 { 5, "critical", ASN1_BOOLEAN
, ASN1_BODY
|
204 { 5, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 17 */
205 { 4, "end loop", ASN1_EOC
, ASN1_END
}, /* 18 */
206 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 19 */
207 { 1, "signatureAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 20 */
208 { 1, "signature", ASN1_BIT_STRING
, ASN1_BODY
}, /* 21 */
209 { 1, "certsContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 22 */
210 { 2, "certs", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 23 */
211 { 3, "certificate", ASN1_SEQUENCE
, ASN1_RAW
}, /* 24 */
212 { 2, "end loop", ASN1_EOC
, ASN1_END
}, /* 25 */
213 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 26 */
214 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
216 #define BASIC_RESPONSE_TBS_DATA 1
217 #define BASIC_RESPONSE_VERSION 3
218 #define BASIC_RESPONSE_ID_BY_NAME 5
219 #define BASIC_RESPONSE_ID_BY_KEY 8
220 #define BASIC_RESPONSE_PRODUCED_AT 10
221 #define BASIC_RESPONSE_RESPONSES 11
222 #define BASIC_RESPONSE_EXT_ID 15
223 #define BASIC_RESPONSE_CRITICAL 16
224 #define BASIC_RESPONSE_EXT_VALUE 17
225 #define BASIC_RESPONSE_ALGORITHM 20
226 #define BASIC_RESPONSE_SIGNATURE 21
227 #define BASIC_RESPONSE_CERTIFICATE 24
230 * ASN.1 definition of responses
232 static const asn1Object_t responsesObjects
[] = {
233 { 0, "responses", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
234 { 1, "singleResponse", ASN1_EOC
, ASN1_RAW
}, /* 1 */
235 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 2 */
236 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
238 #define RESPONSES_SINGLE_RESPONSE 1
241 * ASN.1 definition of singleResponse
243 static const asn1Object_t singleResponseObjects
[] = {
244 { 0, "singleResponse", ASN1_SEQUENCE
, ASN1_BODY
}, /* 0 */
245 { 1, "certID", ASN1_SEQUENCE
, ASN1_NONE
}, /* 1 */
246 { 2, "algorithm", ASN1_EOC
, ASN1_RAW
}, /* 2 */
247 { 2, "issuerNameHash", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 3 */
248 { 2, "issuerKeyHash", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 4 */
249 { 2, "serialNumber", ASN1_INTEGER
, ASN1_BODY
}, /* 5 */
250 { 1, "certStatusGood", ASN1_CONTEXT_S_0
, ASN1_OPT
}, /* 6 */
251 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 7 */
252 { 1, "certStatusRevoked", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 8 */
253 { 2, "revocationTime", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 9 */
254 { 2, "revocationReason", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 10 */
255 { 3, "crlReason", ASN1_ENUMERATED
, ASN1_BODY
}, /* 11 */
256 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 12 */
257 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 13 */
258 { 1, "certStatusUnknown", ASN1_CONTEXT_S_2
, ASN1_OPT
}, /* 14 */
259 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 15 */
260 { 1, "thisUpdate", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 16 */
261 { 1, "nextUpdateContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 17 */
262 { 2, "nextUpdate", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 18 */
263 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 19 */
264 { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 20 */
265 { 2, "singleExtensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 21 */
266 { 3, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 22 */
267 { 4, "extnID", ASN1_OID
, ASN1_BODY
}, /* 23 */
268 { 4, "critical", ASN1_BOOLEAN
, ASN1_BODY
|
270 { 4, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 25 */
271 { 2, "end loop", ASN1_EOC
, ASN1_END
}, /* 26 */
272 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 27 */
273 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
275 #define SINGLE_RESPONSE_ALGORITHM 2
276 #define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
277 #define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
278 #define SINGLE_RESPONSE_SERIAL_NUMBER 5
279 #define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
280 #define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
281 #define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
282 #define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
283 #define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
284 #define SINGLE_RESPONSE_THIS_UPDATE 16
285 #define SINGLE_RESPONSE_NEXT_UPDATE 18
286 #define SINGLE_RESPONSE_EXT_ID 23
287 #define SINGLE_RESPONSE_CRITICAL 24
288 #define SINGLE_RESPONSE_EXT_VALUE 25
291 * Build an ocsp location from certificate information
292 * without unsharing its contents
294 static bool build_ocsp_location(const x509cert_t
*cert
, ocsp_location_t
*location
)
296 static u_char digest
[HASH_SIZE_SHA1
]; /* temporary storage */
298 location
->uri
= cert
->accessLocation
;
300 if (location
->uri
.ptr
== NULL
)
302 ca_info_t
*ca
= get_ca_info(cert
->issuer
, cert
->authKeySerialNumber
304 if (ca
!= NULL
&& ca
->ocspuri
!= NULL
)
306 location
->uri
= chunk_create(ca
->ocspuri
, strlen(ca
->ocspuri
));
309 { /* abort if no ocsp location uri is defined */
314 location
->authNameID
= chunk_create(digest
, HASH_SIZE_SHA1
);
315 compute_digest(cert
->issuer
, OID_SHA1
, &location
->authNameID
);
317 location
->next
= NULL
;
318 location
->issuer
= cert
->issuer
;
319 location
->authKeyID
= cert
->authKeyID
;
320 location
->authKeySerialNumber
= cert
->authKeySerialNumber
;
322 if (cert
->authKeyID
.ptr
== NULL
)
324 x509cert_t
*authcert
= get_authcert(cert
->issuer
325 , cert
->authKeySerialNumber
, cert
->authKeyID
, AUTH_CA
);
327 if (authcert
!= NULL
)
329 location
->authKeyID
= authcert
->subjectKeyID
;
330 location
->authKeySerialNumber
= authcert
->serialNumber
;
334 location
->nonce
= chunk_empty
;
335 location
->certinfo
= NULL
;
341 * Compare two ocsp locations for equality
343 static bool same_ocsp_location(const ocsp_location_t
*a
, const ocsp_location_t
*b
)
345 return ((a
->authKeyID
.ptr
!= NULL
)
346 ?
same_keyid(a
->authKeyID
, b
->authKeyID
)
347 : (same_dn(a
->issuer
, b
->issuer
)
348 && same_serial(a
->authKeySerialNumber
, b
->authKeySerialNumber
)))
349 && chunk_equals(a
->uri
, b
->uri
);
353 * Find an existing ocsp location in a chained list
355 ocsp_location_t
* get_ocsp_location(const ocsp_location_t
* loc
, ocsp_location_t
*chain
)
358 while (chain
!= NULL
)
360 if (same_ocsp_location(loc
, chain
))
368 * Retrieves the status of a cert from the ocsp cache
369 * returns CERT_UNDEFINED if no status is found
371 static cert_status_t
get_ocsp_status(const ocsp_location_t
*loc
,
372 chunk_t serialNumber
,
373 time_t *nextUpdate
, time_t *revocationTime
,
374 crl_reason_t
*revocationReason
)
376 ocsp_certinfo_t
*certinfo
, **certinfop
;
380 ocsp_location_t
*location
= get_ocsp_location(loc
, ocsp_cache
);
382 if (location
== NULL
)
383 return CERT_UNDEFINED
;
385 /* traverse list of certinfos in increasing order */
386 certinfop
= &location
->certinfo
;
387 certinfo
= *certinfop
;
389 while (certinfo
!= NULL
)
391 cmp
= chunk_compare(serialNumber
, certinfo
->serialNumber
);
394 certinfop
= &certinfo
->next
;
395 certinfo
= *certinfop
;
400 *nextUpdate
= certinfo
->nextUpdate
;
401 *revocationTime
= certinfo
->revocationTime
;
402 *revocationReason
= certinfo
->revocationReason
;
403 return certinfo
->status
;
406 return CERT_UNDEFINED
;
410 * Verify the ocsp status of a certificate
412 cert_status_t
verify_by_ocsp(const x509cert_t
*cert
, time_t *until
,
413 time_t *revocationDate
,
414 crl_reason_t
*revocationReason
)
416 cert_status_t status
;
417 ocsp_location_t location
;
418 time_t nextUpdate
= 0;
420 *revocationDate
= UNDEFINED_TIME
;
421 *revocationReason
= REASON_UNSPECIFIED
;
423 /* is an ocsp location defined? */
424 if (!build_ocsp_location(cert
, &location
))
425 return CERT_UNDEFINED
;
427 lock_ocsp_cache("verify_by_ocsp");
428 status
= get_ocsp_status(&location
, cert
->serialNumber
, &nextUpdate
429 , revocationDate
, revocationReason
);
430 unlock_ocsp_cache("verify_by_ocsp");
432 if (status
== CERT_UNDEFINED
|| nextUpdate
< time(NULL
))
434 plog("ocsp status is stale or not in cache");
435 add_ocsp_fetch_request(&location
, cert
->serialNumber
);
437 /* inititate fetching of ocsp status */
438 wake_fetch_thread("verify_by_ocsp");
445 * Check if an ocsp status is about to expire
447 void check_ocsp(void)
449 ocsp_location_t
*location
;
451 lock_ocsp_cache("check_ocsp");
452 location
= ocsp_cache
;
454 while (location
!= NULL
)
458 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
460 while (certinfo
!= NULL
)
464 time_t time_left
= certinfo
->nextUpdate
- time(NULL
);
469 dntoa(buf
, BUF_LEN
, location
->issuer
);
470 DBG_log("issuer: '%s'", buf
);
471 if (location
->authKeyID
.ptr
!= NULL
)
473 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
474 , ':', buf
, BUF_LEN
);
475 DBG_log("authkey: %s", buf
);
479 datatot(certinfo
->serialNumber
.ptr
, certinfo
->serialNumber
.len
480 , ':', buf
, BUF_LEN
);
481 DBG_log("serial: %s, %ld seconds left", buf
, time_left
)
484 if (time_left
< 2*crl_check_interval
)
485 add_ocsp_fetch_request(location
, certinfo
->serialNumber
);
487 certinfo
= certinfo
->next
;
489 location
= location
->next
;
491 unlock_ocsp_cache("check_ocsp");
495 * frees the allocated memory of a certinfo struct
497 static void free_certinfo(ocsp_certinfo_t
*certinfo
)
499 free(certinfo
->serialNumber
.ptr
);
504 * frees all certinfos in a chained list
506 static void free_certinfos(ocsp_certinfo_t
*chain
)
508 ocsp_certinfo_t
*certinfo
;
510 while (chain
!= NULL
)
514 free_certinfo(certinfo
);
519 * Frees the memory allocated to an ocsp location including all certinfos
521 static void free_ocsp_location(ocsp_location_t
* location
)
523 free(location
->issuer
.ptr
);
524 free(location
->authNameID
.ptr
);
525 free(location
->authKeyID
.ptr
);
526 free(location
->authKeySerialNumber
.ptr
);
527 free(location
->uri
.ptr
);
528 free_certinfos(location
->certinfo
);
533 * Free a chained list of ocsp locations
535 void free_ocsp_locations(ocsp_location_t
**chain
)
537 while (*chain
!= NULL
)
539 ocsp_location_t
*location
= *chain
;
540 *chain
= location
->next
;
541 free_ocsp_location(location
);
546 * Free the ocsp cache
548 void free_ocsp_cache(void)
550 lock_ocsp_cache("free_ocsp_cache");
551 free_ocsp_locations(&ocsp_cache
);
552 unlock_ocsp_cache("free_ocsp_cache");
556 * Frees the ocsp cache and global variables
560 free(ocsp_default_uri
.ptr
);
565 * List a chained list of ocsp_locations
567 void list_ocsp_locations(ocsp_location_t
*location
, bool requests
,
568 bool utc
, bool strict
)
572 while (location
!= NULL
)
574 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
576 if (certinfo
!= NULL
)
582 whack_log(RC_COMMENT
, " ");
583 whack_log(RC_COMMENT
, "List of OCSP %s:", requests?
584 "fetch requests":"responses");
587 whack_log(RC_COMMENT
, " ");
588 if (location
->issuer
.ptr
!= NULL
)
590 dntoa(buf
, BUF_LEN
, location
->issuer
);
591 whack_log(RC_COMMENT
, " issuer: '%s'", buf
);
593 whack_log(RC_COMMENT
, " uri: '%.*s'", (int)location
->uri
.len
594 , location
->uri
.ptr
);
595 if (location
->authNameID
.ptr
!= NULL
)
597 datatot(location
->authNameID
.ptr
, location
->authNameID
.len
, ':'
599 whack_log(RC_COMMENT
, " authname: %s", buf
);
601 if (location
->authKeyID
.ptr
!= NULL
)
603 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
, ':'
605 whack_log(RC_COMMENT
, " authkey: %s", buf
);
607 if (location
->authKeySerialNumber
.ptr
!= NULL
)
609 datatot(location
->authKeySerialNumber
.ptr
610 , location
->authKeySerialNumber
.len
, ':', buf
, BUF_LEN
);
611 whack_log(RC_COMMENT
, " aserial: %s", buf
);
613 while (certinfo
!= NULL
)
615 char thisUpdate
[BUF_LEN
];
617 snprintf(thisUpdate
, BUF_LEN
, "%T", &certinfo
->thisUpdate
, utc
);
621 whack_log(RC_COMMENT
, "%s, trials: %d", thisUpdate
624 else if (certinfo
->once
)
626 whack_log(RC_COMMENT
, "%s, onetime use%s", thisUpdate
627 , (certinfo
->nextUpdate
< time(NULL
))?
" (expired)": "");
631 whack_log(RC_COMMENT
, "%s, until %T %s", thisUpdate
632 , &certinfo
->nextUpdate
, utc
633 , check_expiry(certinfo
->nextUpdate
, OCSP_WARNING_INTERVAL
, strict
));
635 datatot(certinfo
->serialNumber
.ptr
, certinfo
->serialNumber
.len
, ':'
637 whack_log(RC_COMMENT
, " serial: %s, %s", buf
638 , cert_status_names
[certinfo
->status
]);
639 certinfo
= certinfo
->next
;
642 location
= location
->next
;
647 * List the ocsp cache
649 void list_ocsp_cache(bool utc
, bool strict
)
651 lock_ocsp_cache("list_ocsp_cache");
652 list_ocsp_locations(ocsp_cache
, FALSE
, utc
, strict
);
653 unlock_ocsp_cache("list_ocsp_cache");
656 static bool get_ocsp_requestor_cert(ocsp_location_t
*location
)
658 x509cert_t
*cert
= NULL
;
660 /* initialize temporary static storage */
661 ocsp_requestor_cert
= NULL
;
662 ocsp_requestor_sc
= NULL
;
663 ocsp_requestor_pri
= NULL
;
669 /* looking for a certificate from the same issuer */
670 cert
= get_x509cert(location
->issuer
, location
->authKeySerialNumber
671 ,location
->authKeyID
, cert
);
676 dntoa(buf
, BUF_LEN
, cert
->subject
);
677 DBG_log("candidate: '%s'", buf
);
682 /* look for a matching private key on a smartcard */
683 smartcard_t
*sc
= scx_get(cert
);
688 DBG_log("matching smartcard found")
692 ocsp_requestor_cert
= cert
;
693 ocsp_requestor_sc
= sc
;
696 plog("unable to sign ocsp request without PIN");
701 /* look for a matching private key in the chained list */
702 const struct RSA_private_key
*pri
= get_x509_private_key(cert
);
707 DBG_log("matching private key found")
709 ocsp_requestor_cert
= cert
;
710 ocsp_requestor_pri
= pri
;
718 static chunk_t
generate_signature(chunk_t digest
, smartcard_t
*sc
,
719 const RSA_private_key_t
*pri
)
727 /* RSA signature is done on smartcard */
729 if (!scx_establish_context(sc
) || !scx_login(sc
))
731 scx_release_context(sc
);
735 siglen
= scx_get_keylength(sc
);
739 plog("failed to get keylength from smartcard");
740 scx_release_context(sc
);
744 DBG(DBG_CONTROL
| DBG_CRYPT
,
745 DBG_log("signing hash with RSA key from smartcard (slot: %d, id: %s)"
746 , (int)sc
->slot
, sc
->id
)
749 pos
= asn1_build_object(&sigdata
, ASN1_BIT_STRING
, 1 + siglen
);
751 scx_sign_hash(sc
, digest
.ptr
, digest
.len
, pos
, siglen
);
752 if (!pkcs11_keep_state
)
753 scx_release_context(sc
);
757 /* RSA signature is done in software */
759 pos
= asn1_build_object(&sigdata
, ASN1_BIT_STRING
, 1 + siglen
);
761 sign_hash(pri
, digest
.ptr
, digest
.len
, pos
, siglen
);
767 * build signature into ocsp request gets built only if a request cert
768 * with a corresponding private key is found
770 static chunk_t
build_signature(chunk_t tbsRequest
)
772 chunk_t sigdata
, certs
;
775 u_char digest_buf
[MAX_DIGEST_LEN
];
776 chunk_t digest_raw
= { digest_buf
, MAX_DIGEST_LEN
};
778 if (!compute_digest(tbsRequest
, OID_SHA1
, &digest_raw
))
781 /* according to PKCS#1 v2.1 digest must be packaged into
782 * an ASN.1 structure for encryption
784 digest_info
= asn1_wrap(ASN1_SEQUENCE
, "cm"
785 , asn1_algorithmIdentifier(OID_SHA1
)
786 , asn1_simple_object(ASN1_OCTET_STRING
, digest_raw
));
788 /* generate the RSA signature */
789 sigdata
= generate_signature(digest_info
791 , ocsp_requestor_pri
);
792 free(digest_info
.ptr
);
794 /* has the RSA signature generation been successful? */
795 if (sigdata
.ptr
== NULL
)
798 /* include our certificate */
799 certs
= asn1_wrap(ASN1_CONTEXT_C_0
, "m"
800 , asn1_simple_object(ASN1_SEQUENCE
801 , ocsp_requestor_cert
->certificate
805 /* build signature comprising algorithm, signature and cert */
806 return asn1_wrap(ASN1_CONTEXT_C_0
, "m"
807 , asn1_wrap(ASN1_SEQUENCE
, "cmm"
808 , asn1_algorithmIdentifier(OID_SHA1_WITH_RSA
)
816 * Build request (into requestList)
817 * no singleRequestExtensions used
819 static chunk_t
build_request(ocsp_location_t
*location
, ocsp_certinfo_t
*certinfo
)
821 chunk_t reqCert
= asn1_wrap(ASN1_SEQUENCE
, "cmmm"
822 , asn1_algorithmIdentifier(OID_SHA1
)
823 , asn1_simple_object(ASN1_OCTET_STRING
, location
->authNameID
)
824 , asn1_simple_object(ASN1_OCTET_STRING
, location
->authKeyID
)
825 , asn1_simple_object(ASN1_INTEGER
, certinfo
->serialNumber
));
827 return asn1_wrap(ASN1_SEQUENCE
, "m", reqCert
);
831 * build requestList (into TBSRequest)
833 static chunk_t
build_request_list(ocsp_location_t
*location
)
836 request_list_t
*reqs
= NULL
;
837 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
843 while (certinfo
!= NULL
)
845 /* build request for every certificate in list
846 * and store them in a chained list
848 request_list_t
*req
= malloc_thing(request_list_t
);
850 req
->request
= build_request(location
, certinfo
);
854 datalen
+= req
->request
.len
;
855 certinfo
= certinfo
->next
;
858 pos
= asn1_build_object(&requestList
, ASN1_SEQUENCE
, datalen
);
860 /* copy all in chained list, free list afterwards */
863 request_list_t
*req
= reqs
;
865 mv_chunk(&pos
, req
->request
);
874 * Build requestorName (into TBSRequest)
876 static chunk_t
build_requestor_name(void)
878 return asn1_wrap(ASN1_CONTEXT_C_1
, "m"
879 , asn1_simple_object(ASN1_CONTEXT_C_4
880 , ocsp_requestor_cert
->subject
));
884 * build nonce extension (into requestExtensions)
886 static chunk_t
build_nonce_extension(ocsp_location_t
*location
)
890 /* generate a random nonce */
891 location
->nonce
.ptr
= malloc(NONCE_LENGTH
),
892 location
->nonce
.len
= NONCE_LENGTH
;
893 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_STRONG
);
894 rng
->get_bytes(rng
, location
->nonce
.len
, location
->nonce
.ptr
);
897 return asn1_wrap(ASN1_SEQUENCE
, "cm"
899 , asn1_simple_object(ASN1_OCTET_STRING
, location
->nonce
));
903 * Build requestExtensions (into TBSRequest)
905 static chunk_t
build_request_ext(ocsp_location_t
*location
)
907 return asn1_wrap(ASN1_CONTEXT_C_2
, "m"
908 , asn1_wrap(ASN1_SEQUENCE
, "mm"
909 , build_nonce_extension(location
)
910 , asn1_wrap(ASN1_SEQUENCE
, "cc"
912 , ASN1_response_content
919 * Build TBSRequest (into OCSPRequest)
921 static chunk_t
build_tbs_request(ocsp_location_t
*location
, bool has_requestor_cert
)
923 /* version is skipped since the default is ok */
924 return asn1_wrap(ASN1_SEQUENCE
, "mmm"
925 , (has_requestor_cert
)
926 ?
build_requestor_name()
928 , build_request_list(location
)
929 , build_request_ext(location
));
933 * Assembles an ocsp request to given location
934 * and sets nonce field in location to the sent nonce
936 chunk_t
build_ocsp_request(ocsp_location_t
*location
)
938 bool has_requestor_cert
;
939 chunk_t tbsRequest
, signature
;
943 DBG_log("assembling ocsp request");
944 dntoa(buf
, BUF_LEN
, location
->issuer
);
945 DBG_log("issuer: '%s'", buf
);
946 if (location
->authKeyID
.ptr
!= NULL
)
948 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
, ':'
950 DBG_log("authkey: %s", buf
);
953 lock_certs_and_keys("build_ocsp_request");
955 /* looks for requestor cert and matching private key */
956 has_requestor_cert
= get_ocsp_requestor_cert(location
);
959 tbsRequest
= build_tbs_request(location
, has_requestor_cert
);
961 /* sign tbsReuqest */
962 signature
= (has_requestor_cert
)?
build_signature(tbsRequest
)
965 unlock_certs_and_keys("build_ocsp_request");
967 return asn1_wrap(ASN1_SEQUENCE
, "mm"
973 * Check if the OCSP response has a valid signature
975 static bool valid_ocsp_response(response_t
*res
)
978 x509cert_t
*authcert
;
980 lock_authcert_list("valid_ocsp_response");
982 authcert
= get_authcert(res
->responder_id_name
, chunk_empty
983 , res
->responder_id_key
, AUTH_OCSP
| AUTH_CA
);
985 if (authcert
== NULL
)
987 plog("no matching ocsp signer cert found");
988 unlock_authcert_list("valid_ocsp_response");
992 DBG_log("ocsp signer cert found")
995 if (!check_signature(res
->tbs
, res
->signature
, res
->algorithm
996 , res
->algorithm
, authcert
))
998 plog("signature of ocsp response is invalid");
999 unlock_authcert_list("valid_ocsp_response");
1003 DBG_log("signature of ocsp response is valid")
1007 for (pathlen
= 0; pathlen
< MAX_CA_PATH_LEN
; pathlen
++)
1009 u_char buf
[BUF_LEN
];
1013 x509cert_t
*cert
= authcert
;
1016 dntoa(buf
, BUF_LEN
, cert
->subject
);
1017 DBG_log("subject: '%s'",buf
);
1018 dntoa(buf
, BUF_LEN
, cert
->issuer
);
1019 DBG_log("issuer: '%s'",buf
);
1020 if (cert
->authKeyID
.ptr
!= NULL
)
1022 datatot(cert
->authKeyID
.ptr
, cert
->authKeyID
.len
, ':'
1024 DBG_log("authkey: %s", buf
);
1028 ugh
= check_validity(authcert
, &until
);
1033 unlock_authcert_list("valid_ocsp_response");
1038 DBG_log("certificate is valid")
1041 authcert
= get_authcert(cert
->issuer
, cert
->authKeySerialNumber
1042 , cert
->authKeyID
, AUTH_CA
);
1044 if (authcert
== NULL
)
1046 plog("issuer cacert not found");
1047 unlock_authcert_list("valid_ocsp_response");
1051 DBG_log("issuer cacert found")
1054 if (!check_signature(cert
->tbsCertificate
, cert
->signature
1055 , cert
->algorithm
, cert
->algorithm
, authcert
))
1057 plog("certificate signature is invalid");
1058 unlock_authcert_list("valid_ocsp_response");
1062 DBG_log("certificate signature is valid")
1065 /* check if cert is self-signed */
1066 if (same_dn(cert
->issuer
, cert
->subject
))
1069 DBG_log("reached self-signed root ca")
1071 unlock_authcert_list("valid_ocsp_response");
1075 plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN
);
1076 unlock_authcert_list("valid_ocsp_response");
1081 * Parse a basic OCSP response
1083 static bool parse_basic_ocsp_response(chunk_t blob
, int level0
, response_t
*res
)
1085 asn1_parser_t
*parser
;
1088 u_char buf
[BUF_LEN
];
1090 int extn_oid
= OID_UNKNOWN
;
1091 bool success
= FALSE
;
1094 parser
= asn1_parser_create(basicResponseObjects
, blob
);
1095 parser
->set_top_level(parser
, level0
);
1097 while (parser
->iterate(parser
, &objectID
, &object
))
1101 case BASIC_RESPONSE_TBS_DATA
:
1104 case BASIC_RESPONSE_VERSION
:
1105 version
= (object
.len
)?
(1 + (u_int
)*object
.ptr
) : 1;
1106 if (version
!= OCSP_BASIC_RESPONSE_VERSION
)
1108 plog("wrong ocsp basic response version (version= %i)", version
);
1112 case BASIC_RESPONSE_ID_BY_NAME
:
1113 res
->responder_id_name
= object
;
1115 dntoa(buf
, BUF_LEN
, object
);
1116 DBG_log(" '%s'",buf
)
1119 case BASIC_RESPONSE_ID_BY_KEY
:
1120 res
->responder_id_key
= object
;
1122 case BASIC_RESPONSE_PRODUCED_AT
:
1123 res
->produced_at
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
1125 case BASIC_RESPONSE_RESPONSES
:
1126 res
->responses
= object
;
1128 case BASIC_RESPONSE_EXT_ID
:
1129 extn_oid
= asn1_known_oid(object
);
1131 case BASIC_RESPONSE_CRITICAL
:
1132 critical
= object
.len
&& *object
.ptr
;
1134 DBG_log(" %s",(critical
)?
"TRUE":"FALSE");
1137 case BASIC_RESPONSE_EXT_VALUE
:
1138 if (extn_oid
== OID_NONCE
)
1139 res
->nonce
= object
;
1141 case BASIC_RESPONSE_ALGORITHM
:
1142 res
->algorithm
= asn1_parse_algorithmIdentifier(object
,
1143 parser
->get_level(parser
)+1, NULL
);
1145 case BASIC_RESPONSE_SIGNATURE
:
1146 res
->signature
= object
;
1148 case BASIC_RESPONSE_CERTIFICATE
:
1150 chunk_t blob
= chunk_clone(object
);
1151 x509cert_t
*cert
= malloc_thing(x509cert_t
);
1153 *cert
= empty_x509cert
;
1155 if (parse_x509cert(blob
, parser
->get_level(parser
)+1, cert
)
1156 && cert
->isOcspSigner
1157 && trust_authcert_candidate(cert
, NULL
))
1159 add_authcert(cert
, AUTH_OCSP
);
1163 DBG(DBG_CONTROL
| DBG_PARSING
,
1164 DBG_log("embedded ocsp certificate rejected")
1166 free_x509cert(cert
);
1172 success
= parser
->success(parser
);
1175 parser
->destroy(parser
);
1182 * Parse an ocsp response and return the result as a response_t struct
1184 static response_status
parse_ocsp_response(chunk_t blob
, response_t
* res
)
1186 asn1_parser_t
*parser
;
1189 int ocspResponseType
= OID_UNKNOWN
;
1190 bool success
= FALSE
;
1191 response_status rStatus
= STATUS_INTERNALERROR
;
1193 parser
= asn1_parser_create(ocspResponseObjects
, blob
);
1195 while (parser
->iterate(parser
, &objectID
, &object
))
1198 case OCSP_RESPONSE_STATUS
:
1199 rStatus
= (response_status
) *object
.ptr
;
1203 case STATUS_SUCCESSFUL
:
1205 case STATUS_MALFORMEDREQUEST
:
1206 case STATUS_INTERNALERROR
:
1207 case STATUS_TRYLATER
:
1208 case STATUS_SIGREQUIRED
:
1209 case STATUS_UNAUTHORIZED
:
1210 plog("ocsp response: server said '%s'"
1211 , response_status_names
[rStatus
]);
1217 case OCSP_RESPONSE_TYPE
:
1218 ocspResponseType
= asn1_known_oid(object
);
1222 switch (ocspResponseType
) {
1224 success
= parse_basic_ocsp_response(object
,
1225 parser
->get_level(parser
)+1, res
);
1229 DBG_log("ocsp response is not of type BASIC");
1230 DBG_dump_chunk("ocsp response OID: ", object
);
1238 success
&= parser
->success(parser
);
1241 parser
->destroy(parser
);
1246 * Parse a basic OCSP response
1248 static bool parse_ocsp_single_response(chunk_t blob
, int level0
,
1249 single_response_t
*sres
)
1251 asn1_parser_t
*parser
;
1256 bool success
= FALSE
;
1258 parser
= asn1_parser_create(singleResponseObjects
, blob
);
1259 parser
->set_top_level(parser
, level0
);
1261 while (parser
->iterate(parser
, &objectID
, &object
))
1265 case SINGLE_RESPONSE_ALGORITHM
:
1266 sres
->hash_algorithm
= asn1_parse_algorithmIdentifier(object
,
1267 parser
->get_level(parser
)+1, NULL
);
1269 case SINGLE_RESPONSE_ISSUER_NAME_HASH
:
1270 sres
->issuer_name_hash
= object
;
1272 case SINGLE_RESPONSE_ISSUER_KEY_HASH
:
1273 sres
->issuer_key_hash
= object
;
1275 case SINGLE_RESPONSE_SERIAL_NUMBER
:
1276 sres
->serialNumber
= object
;
1278 case SINGLE_RESPONSE_CERT_STATUS_GOOD
:
1279 sres
->status
= CERT_GOOD
;
1281 case SINGLE_RESPONSE_CERT_STATUS_REVOKED
:
1282 sres
->status
= CERT_REVOKED
;
1284 case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME
:
1285 sres
->revocationTime
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
1287 case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON
:
1288 sres
->revocationReason
= (object
.len
== 1)
1289 ?
*object
.ptr
: REASON_UNSPECIFIED
;
1291 case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN
:
1292 sres
->status
= CERT_UNKNOWN
;
1294 case SINGLE_RESPONSE_THIS_UPDATE
:
1295 sres
->thisUpdate
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
1297 case SINGLE_RESPONSE_NEXT_UPDATE
:
1298 sres
->nextUpdate
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
1300 case SINGLE_RESPONSE_EXT_ID
:
1301 extn_oid
= asn1_known_oid(object
);
1303 case SINGLE_RESPONSE_CRITICAL
:
1304 critical
= object
.len
&& *object
.ptr
;
1306 DBG_log(" %s",(critical
)?
"TRUE":"FALSE");
1308 case SINGLE_RESPONSE_EXT_VALUE
:
1312 success
= parser
->success(parser
);
1313 parser
->destroy(parser
);
1318 * Add an ocsp location to a chained list
1320 ocsp_location_t
* add_ocsp_location(const ocsp_location_t
*loc
,
1321 ocsp_location_t
**chain
)
1323 ocsp_location_t
*location
= malloc_thing(ocsp_location_t
);
1325 /* unshare location fields */
1326 location
->issuer
= chunk_clone(loc
->issuer
);
1327 location
->authNameID
= chunk_clone(loc
->authNameID
);
1328 location
->authKeyID
= chunk_clone(loc
->authKeyID
);
1329 location
->authKeySerialNumber
= chunk_clone(loc
->authKeySerialNumber
);
1330 location
->uri
= chunk_clone(loc
->uri
);
1331 location
->certinfo
= NULL
;
1333 /* insert new ocsp location in front of chain */
1334 location
->next
= *chain
;
1338 DBG_log("new ocsp location added")
1345 * add a certinfo struct to a chained list
1347 void add_certinfo(ocsp_location_t
*loc
, ocsp_certinfo_t
*info
,
1348 ocsp_location_t
**chain
, bool request
)
1350 ocsp_location_t
*location
;
1351 ocsp_certinfo_t
*certinfo
, **certinfop
;
1356 location
= get_ocsp_location(loc
, *chain
);
1357 if (location
== NULL
)
1359 location
= add_ocsp_location(loc
, chain
);
1362 /* traverse list of certinfos in increasing order */
1363 certinfop
= &location
->certinfo
;
1364 certinfo
= *certinfop
;
1366 while (certinfo
!= NULL
)
1368 cmp
= chunk_compare(info
->serialNumber
, certinfo
->serialNumber
);
1371 certinfop
= &certinfo
->next
;
1372 certinfo
= *certinfop
;
1377 /* add a new certinfo entry */
1378 ocsp_certinfo_t
*cnew
= malloc_thing(ocsp_certinfo_t
);
1380 cnew
->serialNumber
= chunk_clone(info
->serialNumber
);
1381 cnew
->next
= certinfo
;
1387 datatot(info
->serialNumber
.ptr
, info
->serialNumber
.len
, ':'
1389 DBG_log("ocsp %s for serial %s %s"
1390 , request?
"fetch request":"certinfo"
1392 , (cmp
== 0)?
(request?
"already exists":"updated"):"added")
1399 certinfo
->status
= CERT_UNDEFINED
;
1403 certinfo
->thisUpdate
= now
;
1405 certinfo
->nextUpdate
= UNDEFINED_TIME
;
1409 certinfo
->status
= info
->status
;
1410 certinfo
->revocationTime
= info
->revocationTime
;
1411 certinfo
->revocationReason
= info
->revocationReason
;
1413 certinfo
->thisUpdate
= (info
->thisUpdate
!= UNDEFINED_TIME
)?
1414 info
->thisUpdate
: now
;
1416 certinfo
->once
= (info
->nextUpdate
== UNDEFINED_TIME
);
1418 certinfo
->nextUpdate
= (certinfo
->once
)?
1419 (now
+ OCSP_DEFAULT_VALID_TIME
) : info
->nextUpdate
;
1424 * Process received ocsp single response and add it to ocsp cache
1426 static void process_single_response(ocsp_location_t
*location
,
1427 single_response_t
*sres
)
1429 ocsp_certinfo_t
*certinfo
, **certinfop
;
1432 if (sres
->hash_algorithm
!= OID_SHA1
)
1434 plog("only SHA-1 hash supported in OCSP single response");
1437 if (!(chunk_equals(sres
->issuer_name_hash
, location
->authNameID
)
1438 && chunk_equals(sres
->issuer_key_hash
, location
->authKeyID
)))
1440 plog("ocsp single response has wrong issuer");
1444 /* traverse list of certinfos in increasing order */
1445 certinfop
= &location
->certinfo
;
1446 certinfo
= *certinfop
;
1448 while (certinfo
!= NULL
)
1450 cmp
= chunk_compare(sres
->serialNumber
, certinfo
->serialNumber
);
1453 certinfop
= &certinfo
->next
;
1454 certinfo
= *certinfop
;
1459 plog("received unrequested cert status from ocsp server");
1463 /* unlink cert from ocsp fetch request list */
1464 *certinfop
= certinfo
->next
;
1466 /* update certinfo using the single response information */
1467 certinfo
->thisUpdate
= sres
->thisUpdate
;
1468 certinfo
->nextUpdate
= sres
->nextUpdate
;
1469 certinfo
->status
= sres
->status
;
1470 certinfo
->revocationTime
= sres
->revocationTime
;
1471 certinfo
->revocationReason
= sres
->revocationReason
;
1473 /* add or update certinfo in ocsp cache */
1474 lock_ocsp_cache("process_single_response");
1475 add_certinfo(location
, certinfo
, &ocsp_cache
, FALSE
);
1476 unlock_ocsp_cache("process_single_response");
1478 /* free certinfo unlinked from ocsp fetch request list */
1479 free_certinfo(certinfo
);
1483 * Parse and verify ocsp response and update the ocsp cache
1485 void parse_ocsp(ocsp_location_t
*location
, chunk_t blob
)
1487 response_t res
= empty_response
;
1489 /* parse the ocsp response without looking at the single responses yet */
1490 response_status status
= parse_ocsp_response(blob
, &res
);
1492 if (status
!= STATUS_SUCCESSFUL
)
1494 plog("error in ocsp response");
1497 /* check if there was a nonce in the request */
1498 if (location
->nonce
.ptr
!= NULL
&& res
.nonce
.ptr
== NULL
)
1500 plog("ocsp response contains no nonce, replay attack possible");
1502 /* check if the nonce is identical */
1503 if (res
.nonce
.ptr
!= NULL
&& !chunk_equals(res
.nonce
, location
->nonce
))
1505 plog("invalid nonce in ocsp response");
1508 /* check if the response is signed by a trusted key */
1509 if (!valid_ocsp_response(&res
))
1511 plog("invalid ocsp response");
1515 DBG_log("valid ocsp response")
1518 /* now parse the single responses one at a time */
1520 asn1_parser_t
*parser
;
1524 parser
= asn1_parser_create(responsesObjects
, res
.responses
);
1526 while (parser
->iterate(parser
, &objectID
, &object
))
1528 if (objectID
== RESPONSES_SINGLE_RESPONSE
)
1530 single_response_t sres
= empty_single_response
;
1532 if (!parse_ocsp_single_response(object
,
1533 parser
->get_level(parser
)+1, &sres
))
1537 process_single_response(location
, &sres
);
1541 parser
->destroy(parser
);