1 /* Support of the Online Certificate Status Protocol (OCSP)
2 * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
3 * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
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"
46 #define NONCE_LENGTH 16
48 static const char *const cert_status_names
[] = {
56 static const char *const response_status_names
[] = {
66 /* response container */
67 typedef struct response response_t
;
71 chunk_t responder_id_name
;
72 chunk_t responder_id_key
;
80 const response_t empty_response
= {
81 { NULL
, 0 } , /* tbs */
82 { NULL
, 0 } , /* responder_id_name */
83 { NULL
, 0 } , /* responder_id_key */
84 UNDEFINED_TIME
, /* produced_at */
85 { NULL
, 0 } , /* single_response */
86 { NULL
, 0 } , /* nonce */
87 OID_UNKNOWN
, /* signature_algorithm */
88 { NULL
, 0 } /* signature */
91 /* single response container */
92 typedef struct single_response single_response_t
;
94 struct single_response
{
95 single_response_t
*next
;
97 chunk_t issuer_name_hash
;
98 chunk_t issuer_key_hash
;
100 cert_status_t status
;
101 time_t revocationTime
;
102 crl_reason_t revocationReason
;
107 const single_response_t empty_single_response
= {
109 OID_UNKNOWN
, /* hash_algorithm */
110 { NULL
, 0 } , /* issuer_name_hash */
111 { NULL
, 0 } , /* issuer_key_hash */
112 { NULL
, 0 } , /* serial_number */
113 CERT_UNDEFINED
, /* status */
114 UNDEFINED_TIME
, /* revocationTime */
115 REASON_UNSPECIFIED
, /* revocationReason */
116 UNDEFINED_TIME
, /* this_update */
117 UNDEFINED_TIME
/* next_update */
121 /* list of single requests */
122 typedef struct request_list request_list_t
;
123 struct request_list
{
125 request_list_t
*next
;
128 /* some OCSP specific prefabricated ASN.1 constants */
130 static u_char ASN1_nonce_oid_str
[] = {
131 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
134 static const chunk_t ASN1_nonce_oid
= chunk_from_buf(ASN1_nonce_oid_str
);
136 static u_char ASN1_response_oid_str
[] = {
137 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
140 static const chunk_t ASN1_response_oid
= chunk_from_buf(ASN1_response_oid_str
);
142 static u_char ASN1_response_content_str
[] = {
145 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
148 static const chunk_t ASN1_response_content
= chunk_from_buf(ASN1_response_content_str
);
150 /* default OCSP uri */
151 static chunk_t ocsp_default_uri
;
153 /* ocsp cache: pointer to first element */
154 static ocsp_location_t
*ocsp_cache
= NULL
;
156 /* static temporary storage for ocsp requestor information */
157 static x509cert_t
*ocsp_requestor_cert
= NULL
;
159 static smartcard_t
*ocsp_requestor_sc
= NULL
;
161 static private_key_t
*ocsp_requestor_key
= NULL
;
164 * ASN.1 definition of ocspResponse
166 static const asn1Object_t ocspResponseObjects
[] = {
167 { 0, "OCSPResponse", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
168 { 1, "responseStatus", ASN1_ENUMERATED
, ASN1_BODY
}, /* 1 */
169 { 1, "responseBytesContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 2 */
170 { 2, "responseBytes", ASN1_SEQUENCE
, ASN1_NONE
}, /* 3 */
171 { 3, "responseType", ASN1_OID
, ASN1_BODY
}, /* 4 */
172 { 3, "response", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 5 */
173 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 6 */
174 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
176 #define OCSP_RESPONSE_STATUS 1
177 #define OCSP_RESPONSE_TYPE 4
178 #define OCSP_RESPONSE 5
181 * ASN.1 definition of basicResponse
183 static const asn1Object_t basicResponseObjects
[] = {
184 { 0, "BasicOCSPResponse", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
185 { 1, "tbsResponseData", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 1 */
186 { 2, "versionContext", ASN1_CONTEXT_C_0
, ASN1_NONE
|
188 { 3, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
189 { 2, "responderIdContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 4 */
190 { 3, "responderIdByName", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 5 */
191 { 2, "end choice", ASN1_EOC
, ASN1_END
}, /* 6 */
192 { 2, "responderIdContext", ASN1_CONTEXT_C_2
, ASN1_OPT
}, /* 7 */
193 { 3, "responderIdByKey", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 8 */
194 { 2, "end choice", ASN1_EOC
, ASN1_END
}, /* 9 */
195 { 2, "producedAt", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 10 */
196 { 2, "responses", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 11 */
197 { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 12 */
198 { 3, "responseExtensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 13 */
199 { 4, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 14 */
200 { 5, "extnID", ASN1_OID
, ASN1_BODY
}, /* 15 */
201 { 5, "critical", ASN1_BOOLEAN
, ASN1_BODY
|
203 { 5, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 17 */
204 { 4, "end loop", ASN1_EOC
, ASN1_END
}, /* 18 */
205 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 19 */
206 { 1, "signatureAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 20 */
207 { 1, "signature", ASN1_BIT_STRING
, ASN1_BODY
}, /* 21 */
208 { 1, "certsContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 22 */
209 { 2, "certs", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 23 */
210 { 3, "certificate", ASN1_SEQUENCE
, ASN1_RAW
}, /* 24 */
211 { 2, "end loop", ASN1_EOC
, ASN1_END
}, /* 25 */
212 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 26 */
213 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
215 #define BASIC_RESPONSE_TBS_DATA 1
216 #define BASIC_RESPONSE_VERSION 3
217 #define BASIC_RESPONSE_ID_BY_NAME 5
218 #define BASIC_RESPONSE_ID_BY_KEY 8
219 #define BASIC_RESPONSE_PRODUCED_AT 10
220 #define BASIC_RESPONSE_RESPONSES 11
221 #define BASIC_RESPONSE_EXT_ID 15
222 #define BASIC_RESPONSE_CRITICAL 16
223 #define BASIC_RESPONSE_EXT_VALUE 17
224 #define BASIC_RESPONSE_ALGORITHM 20
225 #define BASIC_RESPONSE_SIGNATURE 21
226 #define BASIC_RESPONSE_CERTIFICATE 24
229 * ASN.1 definition of responses
231 static const asn1Object_t responsesObjects
[] = {
232 { 0, "responses", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
233 { 1, "singleResponse", ASN1_EOC
, ASN1_RAW
}, /* 1 */
234 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 2 */
235 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
237 #define RESPONSES_SINGLE_RESPONSE 1
240 * ASN.1 definition of singleResponse
242 static const asn1Object_t singleResponseObjects
[] = {
243 { 0, "singleResponse", ASN1_SEQUENCE
, ASN1_BODY
}, /* 0 */
244 { 1, "certID", ASN1_SEQUENCE
, ASN1_NONE
}, /* 1 */
245 { 2, "algorithm", ASN1_EOC
, ASN1_RAW
}, /* 2 */
246 { 2, "issuerNameHash", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 3 */
247 { 2, "issuerKeyHash", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 4 */
248 { 2, "serialNumber", ASN1_INTEGER
, ASN1_BODY
}, /* 5 */
249 { 1, "certStatusGood", ASN1_CONTEXT_S_0
, ASN1_OPT
}, /* 6 */
250 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 7 */
251 { 1, "certStatusRevoked", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 8 */
252 { 2, "revocationTime", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 9 */
253 { 2, "revocationReason", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 10 */
254 { 3, "crlReason", ASN1_ENUMERATED
, ASN1_BODY
}, /* 11 */
255 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 12 */
256 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 13 */
257 { 1, "certStatusUnknown", ASN1_CONTEXT_S_2
, ASN1_OPT
}, /* 14 */
258 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 15 */
259 { 1, "thisUpdate", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 16 */
260 { 1, "nextUpdateContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 17 */
261 { 2, "nextUpdate", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 18 */
262 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 19 */
263 { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 20 */
264 { 2, "singleExtensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 21 */
265 { 3, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 22 */
266 { 4, "extnID", ASN1_OID
, ASN1_BODY
}, /* 23 */
267 { 4, "critical", ASN1_BOOLEAN
, ASN1_BODY
|
269 { 4, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 25 */
270 { 2, "end loop", ASN1_EOC
, ASN1_END
}, /* 26 */
271 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 27 */
272 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
274 #define SINGLE_RESPONSE_ALGORITHM 2
275 #define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
276 #define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
277 #define SINGLE_RESPONSE_SERIAL_NUMBER 5
278 #define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
279 #define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
280 #define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
281 #define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
282 #define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
283 #define SINGLE_RESPONSE_THIS_UPDATE 16
284 #define SINGLE_RESPONSE_NEXT_UPDATE 18
285 #define SINGLE_RESPONSE_EXT_ID 23
286 #define SINGLE_RESPONSE_CRITICAL 24
287 #define SINGLE_RESPONSE_EXT_VALUE 25
290 * Build an ocsp location from certificate information
291 * without unsharing its contents
293 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 /* compute authNameID from as SHA-1 hash of issuer DN */
315 location
->authNameID
= chunk_create(digest
, HASH_SIZE_SHA1
);
316 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
321 hasher
->get_hash(hasher
, cert
->issuer
, digest
);
322 hasher
->destroy(hasher
);
324 location
->next
= NULL
;
325 location
->issuer
= cert
->issuer
;
326 location
->authKeyID
= cert
->authKeyID
;
327 location
->authKeySerialNumber
= cert
->authKeySerialNumber
;
329 if (cert
->authKeyID
.ptr
== NULL
)
331 x509cert_t
*authcert
= get_authcert(cert
->issuer
332 , cert
->authKeySerialNumber
, cert
->authKeyID
, AUTH_CA
);
334 if (authcert
!= NULL
)
336 location
->authKeyID
= authcert
->subjectKeyID
;
337 location
->authKeySerialNumber
= authcert
->serialNumber
;
341 location
->nonce
= chunk_empty
;
342 location
->certinfo
= NULL
;
348 * Compare two ocsp locations for equality
350 static bool same_ocsp_location(const ocsp_location_t
*a
, const ocsp_location_t
*b
)
352 return ((a
->authKeyID
.ptr
!= NULL
)
353 ?
same_keyid(a
->authKeyID
, b
->authKeyID
)
354 : (same_dn(a
->issuer
, b
->issuer
)
355 && same_serial(a
->authKeySerialNumber
, b
->authKeySerialNumber
)))
356 && chunk_equals(a
->uri
, b
->uri
);
360 * Find an existing ocsp location in a chained list
362 ocsp_location_t
* get_ocsp_location(const ocsp_location_t
* loc
, ocsp_location_t
*chain
)
365 while (chain
!= NULL
)
367 if (same_ocsp_location(loc
, chain
))
375 * Retrieves the status of a cert from the ocsp cache
376 * returns CERT_UNDEFINED if no status is found
378 static cert_status_t
get_ocsp_status(const ocsp_location_t
*loc
,
379 chunk_t serialNumber
,
380 time_t *nextUpdate
, time_t *revocationTime
,
381 crl_reason_t
*revocationReason
)
383 ocsp_certinfo_t
*certinfo
, **certinfop
;
387 ocsp_location_t
*location
= get_ocsp_location(loc
, ocsp_cache
);
389 if (location
== NULL
)
390 return CERT_UNDEFINED
;
392 /* traverse list of certinfos in increasing order */
393 certinfop
= &location
->certinfo
;
394 certinfo
= *certinfop
;
396 while (certinfo
!= NULL
)
398 cmp
= chunk_compare(serialNumber
, certinfo
->serialNumber
);
401 certinfop
= &certinfo
->next
;
402 certinfo
= *certinfop
;
407 *nextUpdate
= certinfo
->nextUpdate
;
408 *revocationTime
= certinfo
->revocationTime
;
409 *revocationReason
= certinfo
->revocationReason
;
410 return certinfo
->status
;
413 return CERT_UNDEFINED
;
417 * Verify the ocsp status of a certificate
419 cert_status_t
verify_by_ocsp(const x509cert_t
*cert
, time_t *until
,
420 time_t *revocationDate
,
421 crl_reason_t
*revocationReason
)
423 cert_status_t status
;
424 ocsp_location_t location
;
425 time_t nextUpdate
= 0;
427 *revocationDate
= UNDEFINED_TIME
;
428 *revocationReason
= REASON_UNSPECIFIED
;
430 /* is an ocsp location defined? */
431 if (!build_ocsp_location(cert
, &location
))
432 return CERT_UNDEFINED
;
434 lock_ocsp_cache("verify_by_ocsp");
435 status
= get_ocsp_status(&location
, cert
->serialNumber
, &nextUpdate
436 , revocationDate
, revocationReason
);
437 unlock_ocsp_cache("verify_by_ocsp");
439 if (status
== CERT_UNDEFINED
|| nextUpdate
< time(NULL
))
441 plog("ocsp status is stale or not in cache");
442 add_ocsp_fetch_request(&location
, cert
->serialNumber
);
444 /* inititate fetching of ocsp status */
445 wake_fetch_thread("verify_by_ocsp");
452 * Check if an ocsp status is about to expire
454 void check_ocsp(void)
456 ocsp_location_t
*location
;
458 lock_ocsp_cache("check_ocsp");
459 location
= ocsp_cache
;
461 while (location
!= NULL
)
465 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
467 while (certinfo
!= NULL
)
471 time_t time_left
= certinfo
->nextUpdate
- time(NULL
);
476 dntoa(buf
, BUF_LEN
, location
->issuer
);
477 DBG_log("issuer: '%s'", buf
);
478 if (location
->authKeyID
.ptr
!= NULL
)
480 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
481 , ':', buf
, BUF_LEN
);
482 DBG_log("authkey: %s", buf
);
486 datatot(certinfo
->serialNumber
.ptr
, certinfo
->serialNumber
.len
487 , ':', buf
, BUF_LEN
);
488 DBG_log("serial: %s, %ld seconds left", buf
, time_left
)
491 if (time_left
< 2*crl_check_interval
)
492 add_ocsp_fetch_request(location
, certinfo
->serialNumber
);
494 certinfo
= certinfo
->next
;
496 location
= location
->next
;
498 unlock_ocsp_cache("check_ocsp");
502 * frees the allocated memory of a certinfo struct
504 static void free_certinfo(ocsp_certinfo_t
*certinfo
)
506 free(certinfo
->serialNumber
.ptr
);
511 * frees all certinfos in a chained list
513 static void free_certinfos(ocsp_certinfo_t
*chain
)
515 ocsp_certinfo_t
*certinfo
;
517 while (chain
!= NULL
)
521 free_certinfo(certinfo
);
526 * Frees the memory allocated to an ocsp location including all certinfos
528 static void free_ocsp_location(ocsp_location_t
* location
)
530 free(location
->issuer
.ptr
);
531 free(location
->authNameID
.ptr
);
532 free(location
->authKeyID
.ptr
);
533 free(location
->authKeySerialNumber
.ptr
);
534 free(location
->uri
.ptr
);
535 free_certinfos(location
->certinfo
);
540 * Free a chained list of ocsp locations
542 void free_ocsp_locations(ocsp_location_t
**chain
)
544 while (*chain
!= NULL
)
546 ocsp_location_t
*location
= *chain
;
547 *chain
= location
->next
;
548 free_ocsp_location(location
);
553 * Free the ocsp cache
555 void free_ocsp_cache(void)
557 lock_ocsp_cache("free_ocsp_cache");
558 free_ocsp_locations(&ocsp_cache
);
559 unlock_ocsp_cache("free_ocsp_cache");
563 * Frees the ocsp cache and global variables
567 free(ocsp_default_uri
.ptr
);
572 * List a chained list of ocsp_locations
574 void list_ocsp_locations(ocsp_location_t
*location
, bool requests
,
575 bool utc
, bool strict
)
579 while (location
!= NULL
)
581 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
583 if (certinfo
!= NULL
)
589 whack_log(RC_COMMENT
, " ");
590 whack_log(RC_COMMENT
, "List of OCSP %s:", requests?
591 "fetch requests":"responses");
594 whack_log(RC_COMMENT
, " ");
595 if (location
->issuer
.ptr
!= NULL
)
597 dntoa(buf
, BUF_LEN
, location
->issuer
);
598 whack_log(RC_COMMENT
, " issuer: '%s'", buf
);
600 whack_log(RC_COMMENT
, " uri: '%.*s'", (int)location
->uri
.len
601 , location
->uri
.ptr
);
602 if (location
->authNameID
.ptr
!= NULL
)
604 datatot(location
->authNameID
.ptr
, location
->authNameID
.len
, ':'
606 whack_log(RC_COMMENT
, " authname: %s", buf
);
608 if (location
->authKeyID
.ptr
!= NULL
)
610 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
, ':'
612 whack_log(RC_COMMENT
, " authkey: %s", buf
);
614 if (location
->authKeySerialNumber
.ptr
!= NULL
)
616 datatot(location
->authKeySerialNumber
.ptr
617 , location
->authKeySerialNumber
.len
, ':', buf
, BUF_LEN
);
618 whack_log(RC_COMMENT
, " aserial: %s", buf
);
620 while (certinfo
!= NULL
)
622 char thisUpdate
[BUF_LEN
];
624 snprintf(thisUpdate
, BUF_LEN
, "%T", &certinfo
->thisUpdate
, utc
);
628 whack_log(RC_COMMENT
, "%s, trials: %d", thisUpdate
631 else if (certinfo
->once
)
633 whack_log(RC_COMMENT
, "%s, onetime use%s", thisUpdate
634 , (certinfo
->nextUpdate
< time(NULL
))?
" (expired)": "");
638 whack_log(RC_COMMENT
, "%s, until %T %s", thisUpdate
639 , &certinfo
->nextUpdate
, utc
640 , check_expiry(certinfo
->nextUpdate
, OCSP_WARNING_INTERVAL
, strict
));
642 datatot(certinfo
->serialNumber
.ptr
, certinfo
->serialNumber
.len
, ':'
644 whack_log(RC_COMMENT
, " serial: %s, %s", buf
645 , cert_status_names
[certinfo
->status
]);
646 certinfo
= certinfo
->next
;
649 location
= location
->next
;
654 * List the ocsp cache
656 void list_ocsp_cache(bool utc
, bool strict
)
658 lock_ocsp_cache("list_ocsp_cache");
659 list_ocsp_locations(ocsp_cache
, FALSE
, utc
, strict
);
660 unlock_ocsp_cache("list_ocsp_cache");
663 static bool get_ocsp_requestor_cert(ocsp_location_t
*location
)
665 x509cert_t
*cert
= NULL
;
667 /* initialize temporary static storage */
668 ocsp_requestor_cert
= NULL
;
669 ocsp_requestor_sc
= NULL
;
670 ocsp_requestor_key
= NULL
;
676 /* looking for a certificate from the same issuer */
677 cert
= get_x509cert(location
->issuer
, location
->authKeySerialNumber
678 ,location
->authKeyID
, cert
);
683 dntoa(buf
, BUF_LEN
, cert
->subject
);
684 DBG_log("candidate: '%s'", buf
);
689 /* look for a matching private key on a smartcard */
690 smartcard_t
*sc
= scx_get(cert
);
695 DBG_log("matching smartcard found")
699 ocsp_requestor_cert
= cert
;
700 ocsp_requestor_sc
= sc
;
703 plog("unable to sign ocsp request without PIN");
708 /* look for a matching private key in the chained list */
709 private_key_t
*private = get_x509_private_key(cert
);
714 DBG_log("matching private key found")
716 ocsp_requestor_cert
= cert
;
717 ocsp_requestor_key
= private;
725 static chunk_t
sc_build_sha1_signature(chunk_t tbs
, smartcard_t
*sc
)
729 u_char digest_buf
[HASH_SIZE_SHA1
];
730 chunk_t digest
= chunk_from_buf(digest_buf
);
731 chunk_t digest_info
, sigdata
;
734 if (!scx_establish_context(sc
) || !scx_login(sc
))
736 scx_release_context(sc
);
740 siglen
= scx_get_keylength(sc
);
744 plog("failed to get keylength from smartcard");
745 scx_release_context(sc
);
749 DBG(DBG_CONTROL
| DBG_CRYPT
,
750 DBG_log("signing hash with RSA key from smartcard (slot: %d, id: %s)"
751 , (int)sc
->slot
, sc
->id
)
754 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
759 hasher
->get_hash(hasher
, tbs
, digest_buf
);
760 hasher
->destroy(hasher
);
762 /* according to PKCS#1 v2.1 digest must be packaged into
763 * an ASN.1 structure for encryption
765 digest_info
= asn1_wrap(ASN1_SEQUENCE
, "mm"
766 , asn1_algorithmIdentifier(OID_SHA1
)
767 , asn1_simple_object(ASN1_OCTET_STRING
, digest
));
769 pos
= asn1_build_object(&sigdata
, ASN1_BIT_STRING
, 1 + siglen
);
771 scx_sign_hash(sc
, digest_info
.ptr
, digest_info
.len
, pos
, siglen
);
772 free(digest_info
.ptr
);
774 if (!pkcs11_keep_state
)
776 scx_release_context(sc
);
782 * build signature into ocsp request gets built only if a request cert
783 * with a corresponding private key is found
785 static chunk_t
build_signature(chunk_t tbsRequest
)
787 chunk_t sigdata
, certs
;
789 if (ocsp_requestor_sc
!= NULL
)
791 /* RSA signature is done on smartcard */
792 sigdata
= sc_build_sha1_signature(tbsRequest
, ocsp_requestor_sc
);
796 /* RSA signature is done in software */
797 sigdata
= x509_build_signature(tbsRequest
, OID_SHA1
, ocsp_requestor_key
,
800 if (sigdata
.ptr
== NULL
)
805 /* include our certificate */
806 certs
= asn1_wrap(ASN1_CONTEXT_C_0
, "m"
807 , asn1_simple_object(ASN1_SEQUENCE
808 , ocsp_requestor_cert
->certificate
812 /* build signature comprising algorithm, signature and cert */
813 return asn1_wrap(ASN1_CONTEXT_C_0
, "m"
814 , asn1_wrap(ASN1_SEQUENCE
, "mmm"
815 , asn1_algorithmIdentifier(OID_SHA1_WITH_RSA
)
823 * Build request (into requestList)
824 * no singleRequestExtensions used
826 static chunk_t
build_request(ocsp_location_t
*location
, ocsp_certinfo_t
*certinfo
)
828 chunk_t reqCert
= asn1_wrap(ASN1_SEQUENCE
, "mmmm"
829 , asn1_algorithmIdentifier(OID_SHA1
)
830 , asn1_simple_object(ASN1_OCTET_STRING
, location
->authNameID
)
831 , asn1_simple_object(ASN1_OCTET_STRING
, location
->authKeyID
)
832 , asn1_simple_object(ASN1_INTEGER
, certinfo
->serialNumber
));
834 return asn1_wrap(ASN1_SEQUENCE
, "m", reqCert
);
838 * build requestList (into TBSRequest)
840 static chunk_t
build_request_list(ocsp_location_t
*location
)
843 request_list_t
*reqs
= NULL
;
844 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
850 while (certinfo
!= NULL
)
852 /* build request for every certificate in list
853 * and store them in a chained list
855 request_list_t
*req
= malloc_thing(request_list_t
);
857 req
->request
= build_request(location
, certinfo
);
861 datalen
+= req
->request
.len
;
862 certinfo
= certinfo
->next
;
865 pos
= asn1_build_object(&requestList
, ASN1_SEQUENCE
, datalen
);
867 /* copy all in chained list, free list afterwards */
870 request_list_t
*req
= reqs
;
872 mv_chunk(&pos
, req
->request
);
881 * Build requestorName (into TBSRequest)
883 static chunk_t
build_requestor_name(void)
885 return asn1_wrap(ASN1_CONTEXT_C_1
, "m"
886 , asn1_simple_object(ASN1_CONTEXT_C_4
887 , ocsp_requestor_cert
->subject
));
891 * build nonce extension (into requestExtensions)
893 static chunk_t
build_nonce_extension(ocsp_location_t
*location
)
897 /* generate a random nonce */
898 location
->nonce
.ptr
= malloc(NONCE_LENGTH
),
899 location
->nonce
.len
= NONCE_LENGTH
;
900 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_STRONG
);
901 rng
->get_bytes(rng
, location
->nonce
.len
, location
->nonce
.ptr
);
904 return asn1_wrap(ASN1_SEQUENCE
, "cm"
906 , asn1_simple_object(ASN1_OCTET_STRING
, location
->nonce
));
910 * Build requestExtensions (into TBSRequest)
912 static chunk_t
build_request_ext(ocsp_location_t
*location
)
914 return asn1_wrap(ASN1_CONTEXT_C_2
, "m"
915 , asn1_wrap(ASN1_SEQUENCE
, "mm"
916 , build_nonce_extension(location
)
917 , asn1_wrap(ASN1_SEQUENCE
, "cc"
919 , ASN1_response_content
926 * Build TBSRequest (into OCSPRequest)
928 static chunk_t
build_tbs_request(ocsp_location_t
*location
, bool has_requestor_cert
)
930 /* version is skipped since the default is ok */
931 return asn1_wrap(ASN1_SEQUENCE
, "mmm"
932 , (has_requestor_cert
)
933 ?
build_requestor_name()
935 , build_request_list(location
)
936 , build_request_ext(location
));
940 * Assembles an ocsp request to given location
941 * and sets nonce field in location to the sent nonce
943 chunk_t
build_ocsp_request(ocsp_location_t
*location
)
945 bool has_requestor_cert
;
946 chunk_t tbsRequest
, signature
;
950 DBG_log("assembling ocsp request");
951 dntoa(buf
, BUF_LEN
, location
->issuer
);
952 DBG_log("issuer: '%s'", buf
);
953 if (location
->authKeyID
.ptr
!= NULL
)
955 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
, ':'
957 DBG_log("authkey: %s", buf
);
960 lock_certs_and_keys("build_ocsp_request");
962 /* looks for requestor cert and matching private key */
963 has_requestor_cert
= get_ocsp_requestor_cert(location
);
966 tbsRequest
= build_tbs_request(location
, has_requestor_cert
);
968 /* sign tbsReuqest */
969 signature
= (has_requestor_cert
)?
build_signature(tbsRequest
)
972 unlock_certs_and_keys("build_ocsp_request");
974 return asn1_wrap(ASN1_SEQUENCE
, "mm"
980 * Check if the OCSP response has a valid signature
982 static bool valid_ocsp_response(response_t
*res
)
985 x509cert_t
*authcert
;
987 lock_authcert_list("valid_ocsp_response");
989 authcert
= get_authcert(res
->responder_id_name
, chunk_empty
990 , res
->responder_id_key
, AUTH_OCSP
| AUTH_CA
);
992 if (authcert
== NULL
)
994 plog("no matching ocsp signer cert found");
995 unlock_authcert_list("valid_ocsp_response");
999 DBG_log("ocsp signer cert found")
1002 if (!x509_check_signature(res
->tbs
, res
->signature
, res
->algorithm
, authcert
))
1004 plog("signature of ocsp response is invalid");
1005 unlock_authcert_list("valid_ocsp_response");
1009 DBG_log("signature of ocsp response is valid")
1013 for (pathlen
= 0; pathlen
< MAX_CA_PATH_LEN
; pathlen
++)
1015 u_char buf
[BUF_LEN
];
1019 x509cert_t
*cert
= authcert
;
1022 dntoa(buf
, BUF_LEN
, cert
->subject
);
1023 DBG_log("subject: '%s'",buf
);
1024 dntoa(buf
, BUF_LEN
, cert
->issuer
);
1025 DBG_log("issuer: '%s'",buf
);
1026 if (cert
->authKeyID
.ptr
!= NULL
)
1028 datatot(cert
->authKeyID
.ptr
, cert
->authKeyID
.len
, ':'
1030 DBG_log("authkey: %s", buf
);
1034 ugh
= check_validity(authcert
, &until
);
1039 unlock_authcert_list("valid_ocsp_response");
1044 DBG_log("certificate is valid")
1047 authcert
= get_authcert(cert
->issuer
, cert
->authKeySerialNumber
1048 , cert
->authKeyID
, AUTH_CA
);
1050 if (authcert
== NULL
)
1052 plog("issuer cacert not found");
1053 unlock_authcert_list("valid_ocsp_response");
1057 DBG_log("issuer cacert found")
1060 if (!x509_check_signature(cert
->tbsCertificate
, cert
->signature
,
1061 cert
->algorithm
, authcert
))
1063 plog("certificate signature is invalid");
1064 unlock_authcert_list("valid_ocsp_response");
1068 DBG_log("certificate signature is valid")
1071 /* check if cert is self-signed */
1072 if (same_dn(cert
->issuer
, cert
->subject
))
1075 DBG_log("reached self-signed root ca")
1077 unlock_authcert_list("valid_ocsp_response");
1081 plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN
);
1082 unlock_authcert_list("valid_ocsp_response");
1087 * Parse a basic OCSP response
1089 static bool parse_basic_ocsp_response(chunk_t blob
, int level0
, response_t
*res
)
1091 asn1_parser_t
*parser
;
1094 u_char buf
[BUF_LEN
];
1096 int extn_oid
= OID_UNKNOWN
;
1097 bool success
= FALSE
;
1100 parser
= asn1_parser_create(basicResponseObjects
, blob
);
1101 parser
->set_top_level(parser
, level0
);
1103 while (parser
->iterate(parser
, &objectID
, &object
))
1107 case BASIC_RESPONSE_TBS_DATA
:
1110 case BASIC_RESPONSE_VERSION
:
1111 version
= (object
.len
)?
(1 + (u_int
)*object
.ptr
) : 1;
1112 if (version
!= OCSP_BASIC_RESPONSE_VERSION
)
1114 plog("wrong ocsp basic response version (version= %i)", version
);
1118 case BASIC_RESPONSE_ID_BY_NAME
:
1119 res
->responder_id_name
= object
;
1121 dntoa(buf
, BUF_LEN
, object
);
1122 DBG_log(" '%s'",buf
)
1125 case BASIC_RESPONSE_ID_BY_KEY
:
1126 res
->responder_id_key
= object
;
1128 case BASIC_RESPONSE_PRODUCED_AT
:
1129 res
->produced_at
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
1131 case BASIC_RESPONSE_RESPONSES
:
1132 res
->responses
= object
;
1134 case BASIC_RESPONSE_EXT_ID
:
1135 extn_oid
= asn1_known_oid(object
);
1137 case BASIC_RESPONSE_CRITICAL
:
1138 critical
= object
.len
&& *object
.ptr
;
1140 DBG_log(" %s",(critical
)?
"TRUE":"FALSE");
1143 case BASIC_RESPONSE_EXT_VALUE
:
1144 if (extn_oid
== OID_NONCE
)
1145 res
->nonce
= object
;
1147 case BASIC_RESPONSE_ALGORITHM
:
1148 res
->algorithm
= asn1_parse_algorithmIdentifier(object
,
1149 parser
->get_level(parser
)+1, NULL
);
1151 case BASIC_RESPONSE_SIGNATURE
:
1152 res
->signature
= object
;
1154 case BASIC_RESPONSE_CERTIFICATE
:
1156 chunk_t blob
= chunk_clone(object
);
1157 x509cert_t
*cert
= malloc_thing(x509cert_t
);
1159 *cert
= empty_x509cert
;
1161 if (parse_x509cert(blob
, parser
->get_level(parser
)+1, cert
)
1162 && cert
->isOcspSigner
1163 && trust_authcert_candidate(cert
, NULL
))
1165 add_authcert(cert
, AUTH_OCSP
);
1169 DBG(DBG_CONTROL
| DBG_PARSING
,
1170 DBG_log("embedded ocsp certificate rejected")
1172 free_x509cert(cert
);
1178 success
= parser
->success(parser
);
1181 parser
->destroy(parser
);
1188 * Parse an ocsp response and return the result as a response_t struct
1190 static response_status
parse_ocsp_response(chunk_t blob
, response_t
* res
)
1192 asn1_parser_t
*parser
;
1195 int ocspResponseType
= OID_UNKNOWN
;
1196 bool success
= FALSE
;
1197 response_status rStatus
= STATUS_INTERNALERROR
;
1199 parser
= asn1_parser_create(ocspResponseObjects
, blob
);
1201 while (parser
->iterate(parser
, &objectID
, &object
))
1204 case OCSP_RESPONSE_STATUS
:
1205 rStatus
= (response_status
) *object
.ptr
;
1209 case STATUS_SUCCESSFUL
:
1211 case STATUS_MALFORMEDREQUEST
:
1212 case STATUS_INTERNALERROR
:
1213 case STATUS_TRYLATER
:
1214 case STATUS_SIGREQUIRED
:
1215 case STATUS_UNAUTHORIZED
:
1216 plog("ocsp response: server said '%s'"
1217 , response_status_names
[rStatus
]);
1223 case OCSP_RESPONSE_TYPE
:
1224 ocspResponseType
= asn1_known_oid(object
);
1228 switch (ocspResponseType
) {
1230 success
= parse_basic_ocsp_response(object
,
1231 parser
->get_level(parser
)+1, res
);
1235 DBG_log("ocsp response is not of type BASIC");
1236 DBG_dump_chunk("ocsp response OID: ", object
);
1244 success
&= parser
->success(parser
);
1247 parser
->destroy(parser
);
1252 * Parse a basic OCSP response
1254 static bool parse_ocsp_single_response(chunk_t blob
, int level0
,
1255 single_response_t
*sres
)
1257 asn1_parser_t
*parser
;
1262 bool success
= FALSE
;
1264 parser
= asn1_parser_create(singleResponseObjects
, blob
);
1265 parser
->set_top_level(parser
, level0
);
1267 while (parser
->iterate(parser
, &objectID
, &object
))
1271 case SINGLE_RESPONSE_ALGORITHM
:
1272 sres
->hash_algorithm
= asn1_parse_algorithmIdentifier(object
,
1273 parser
->get_level(parser
)+1, NULL
);
1275 case SINGLE_RESPONSE_ISSUER_NAME_HASH
:
1276 sres
->issuer_name_hash
= object
;
1278 case SINGLE_RESPONSE_ISSUER_KEY_HASH
:
1279 sres
->issuer_key_hash
= object
;
1281 case SINGLE_RESPONSE_SERIAL_NUMBER
:
1282 sres
->serialNumber
= object
;
1284 case SINGLE_RESPONSE_CERT_STATUS_GOOD
:
1285 sres
->status
= CERT_GOOD
;
1287 case SINGLE_RESPONSE_CERT_STATUS_REVOKED
:
1288 sres
->status
= CERT_REVOKED
;
1290 case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME
:
1291 sres
->revocationTime
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
1293 case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON
:
1294 sres
->revocationReason
= (object
.len
== 1)
1295 ?
*object
.ptr
: REASON_UNSPECIFIED
;
1297 case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN
:
1298 sres
->status
= CERT_UNKNOWN
;
1300 case SINGLE_RESPONSE_THIS_UPDATE
:
1301 sres
->thisUpdate
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
1303 case SINGLE_RESPONSE_NEXT_UPDATE
:
1304 sres
->nextUpdate
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
1306 case SINGLE_RESPONSE_EXT_ID
:
1307 extn_oid
= asn1_known_oid(object
);
1309 case SINGLE_RESPONSE_CRITICAL
:
1310 critical
= object
.len
&& *object
.ptr
;
1312 DBG_log(" %s",(critical
)?
"TRUE":"FALSE");
1314 case SINGLE_RESPONSE_EXT_VALUE
:
1318 success
= parser
->success(parser
);
1319 parser
->destroy(parser
);
1324 * Add an ocsp location to a chained list
1326 ocsp_location_t
* add_ocsp_location(const ocsp_location_t
*loc
,
1327 ocsp_location_t
**chain
)
1329 ocsp_location_t
*location
= malloc_thing(ocsp_location_t
);
1331 /* unshare location fields */
1332 location
->issuer
= chunk_clone(loc
->issuer
);
1333 location
->authNameID
= chunk_clone(loc
->authNameID
);
1334 location
->authKeyID
= chunk_clone(loc
->authKeyID
);
1335 location
->authKeySerialNumber
= chunk_clone(loc
->authKeySerialNumber
);
1336 location
->uri
= chunk_clone(loc
->uri
);
1337 location
->certinfo
= NULL
;
1339 /* insert new ocsp location in front of chain */
1340 location
->next
= *chain
;
1344 DBG_log("new ocsp location added")
1351 * add a certinfo struct to a chained list
1353 void add_certinfo(ocsp_location_t
*loc
, ocsp_certinfo_t
*info
,
1354 ocsp_location_t
**chain
, bool request
)
1356 ocsp_location_t
*location
;
1357 ocsp_certinfo_t
*certinfo
, **certinfop
;
1362 location
= get_ocsp_location(loc
, *chain
);
1363 if (location
== NULL
)
1365 location
= add_ocsp_location(loc
, chain
);
1368 /* traverse list of certinfos in increasing order */
1369 certinfop
= &location
->certinfo
;
1370 certinfo
= *certinfop
;
1372 while (certinfo
!= NULL
)
1374 cmp
= chunk_compare(info
->serialNumber
, certinfo
->serialNumber
);
1377 certinfop
= &certinfo
->next
;
1378 certinfo
= *certinfop
;
1383 /* add a new certinfo entry */
1384 ocsp_certinfo_t
*cnew
= malloc_thing(ocsp_certinfo_t
);
1386 cnew
->serialNumber
= chunk_clone(info
->serialNumber
);
1387 cnew
->next
= certinfo
;
1393 datatot(info
->serialNumber
.ptr
, info
->serialNumber
.len
, ':'
1395 DBG_log("ocsp %s for serial %s %s"
1396 , request?
"fetch request":"certinfo"
1398 , (cmp
== 0)?
(request?
"already exists":"updated"):"added")
1405 certinfo
->status
= CERT_UNDEFINED
;
1409 certinfo
->thisUpdate
= now
;
1411 certinfo
->nextUpdate
= UNDEFINED_TIME
;
1415 certinfo
->status
= info
->status
;
1416 certinfo
->revocationTime
= info
->revocationTime
;
1417 certinfo
->revocationReason
= info
->revocationReason
;
1419 certinfo
->thisUpdate
= (info
->thisUpdate
!= UNDEFINED_TIME
)?
1420 info
->thisUpdate
: now
;
1422 certinfo
->once
= (info
->nextUpdate
== UNDEFINED_TIME
);
1424 certinfo
->nextUpdate
= (certinfo
->once
)?
1425 (now
+ OCSP_DEFAULT_VALID_TIME
) : info
->nextUpdate
;
1430 * Process received ocsp single response and add it to ocsp cache
1432 static void process_single_response(ocsp_location_t
*location
,
1433 single_response_t
*sres
)
1435 ocsp_certinfo_t
*certinfo
, **certinfop
;
1438 if (sres
->hash_algorithm
!= OID_SHA1
)
1440 plog("only SHA-1 hash supported in OCSP single response");
1443 if (!(chunk_equals(sres
->issuer_name_hash
, location
->authNameID
)
1444 && chunk_equals(sres
->issuer_key_hash
, location
->authKeyID
)))
1446 plog("ocsp single response has wrong issuer");
1450 /* traverse list of certinfos in increasing order */
1451 certinfop
= &location
->certinfo
;
1452 certinfo
= *certinfop
;
1454 while (certinfo
!= NULL
)
1456 cmp
= chunk_compare(sres
->serialNumber
, certinfo
->serialNumber
);
1459 certinfop
= &certinfo
->next
;
1460 certinfo
= *certinfop
;
1465 plog("received unrequested cert status from ocsp server");
1469 /* unlink cert from ocsp fetch request list */
1470 *certinfop
= certinfo
->next
;
1472 /* update certinfo using the single response information */
1473 certinfo
->thisUpdate
= sres
->thisUpdate
;
1474 certinfo
->nextUpdate
= sres
->nextUpdate
;
1475 certinfo
->status
= sres
->status
;
1476 certinfo
->revocationTime
= sres
->revocationTime
;
1477 certinfo
->revocationReason
= sres
->revocationReason
;
1479 /* add or update certinfo in ocsp cache */
1480 lock_ocsp_cache("process_single_response");
1481 add_certinfo(location
, certinfo
, &ocsp_cache
, FALSE
);
1482 unlock_ocsp_cache("process_single_response");
1484 /* free certinfo unlinked from ocsp fetch request list */
1485 free_certinfo(certinfo
);
1489 * Parse and verify ocsp response and update the ocsp cache
1491 void parse_ocsp(ocsp_location_t
*location
, chunk_t blob
)
1493 response_t res
= empty_response
;
1495 /* parse the ocsp response without looking at the single responses yet */
1496 response_status status
= parse_ocsp_response(blob
, &res
);
1498 if (status
!= STATUS_SUCCESSFUL
)
1500 plog("error in ocsp response");
1503 /* check if there was a nonce in the request */
1504 if (location
->nonce
.ptr
!= NULL
&& res
.nonce
.ptr
== NULL
)
1506 plog("ocsp response contains no nonce, replay attack possible");
1508 /* check if the nonce is identical */
1509 if (res
.nonce
.ptr
!= NULL
&& !chunk_equals(res
.nonce
, location
->nonce
))
1511 plog("invalid nonce in ocsp response");
1514 /* check if the response is signed by a trusted key */
1515 if (!valid_ocsp_response(&res
))
1517 plog("invalid ocsp response");
1521 DBG_log("valid ocsp response")
1524 /* now parse the single responses one at a time */
1526 asn1_parser_t
*parser
;
1530 parser
= asn1_parser_create(responsesObjects
, res
.responses
);
1532 while (parser
->iterate(parser
, &objectID
, &object
))
1534 if (objectID
== RESPONSES_SINGLE_RESPONSE
)
1536 single_response_t sres
= empty_single_response
;
1538 if (!parse_ocsp_single_response(object
,
1539 parser
->get_level(parser
)+1, &sres
))
1543 process_single_response(location
, &sres
);
1547 parser
->destroy(parser
);