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 CRL_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 */
129 static const chunk_t ASN1_nonce_oid
= chunk_from_chars(
130 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
132 static const chunk_t ASN1_response_oid
= chunk_from_chars(
133 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
135 static const chunk_t ASN1_response_content
= chunk_from_chars(
138 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
141 /* default OCSP uri */
142 static chunk_t ocsp_default_uri
;
144 /* ocsp cache: pointer to first element */
145 static ocsp_location_t
*ocsp_cache
= NULL
;
147 /* static temporary storage for ocsp requestor information */
148 static x509cert_t
*ocsp_requestor_cert
= NULL
;
150 static smartcard_t
*ocsp_requestor_sc
= NULL
;
152 static private_key_t
*ocsp_requestor_key
= NULL
;
155 * ASN.1 definition of ocspResponse
157 static const asn1Object_t ocspResponseObjects
[] = {
158 { 0, "OCSPResponse", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
159 { 1, "responseStatus", ASN1_ENUMERATED
, ASN1_BODY
}, /* 1 */
160 { 1, "responseBytesContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 2 */
161 { 2, "responseBytes", ASN1_SEQUENCE
, ASN1_NONE
}, /* 3 */
162 { 3, "responseType", ASN1_OID
, ASN1_BODY
}, /* 4 */
163 { 3, "response", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 5 */
164 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 6 */
165 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
167 #define OCSP_RESPONSE_STATUS 1
168 #define OCSP_RESPONSE_TYPE 4
169 #define OCSP_RESPONSE 5
172 * ASN.1 definition of basicResponse
174 static const asn1Object_t basicResponseObjects
[] = {
175 { 0, "BasicOCSPResponse", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
176 { 1, "tbsResponseData", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 1 */
177 { 2, "versionContext", ASN1_CONTEXT_C_0
, ASN1_NONE
|
179 { 3, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
180 { 2, "responderIdContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 4 */
181 { 3, "responderIdByName", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 5 */
182 { 2, "end choice", ASN1_EOC
, ASN1_END
}, /* 6 */
183 { 2, "responderIdContext", ASN1_CONTEXT_C_2
, ASN1_OPT
}, /* 7 */
184 { 3, "responderIdByKey", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 8 */
185 { 2, "end choice", ASN1_EOC
, ASN1_END
}, /* 9 */
186 { 2, "producedAt", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 10 */
187 { 2, "responses", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 11 */
188 { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 12 */
189 { 3, "responseExtensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 13 */
190 { 4, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 14 */
191 { 5, "extnID", ASN1_OID
, ASN1_BODY
}, /* 15 */
192 { 5, "critical", ASN1_BOOLEAN
, ASN1_BODY
|
194 { 5, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 17 */
195 { 4, "end loop", ASN1_EOC
, ASN1_END
}, /* 18 */
196 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 19 */
197 { 1, "signatureAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 20 */
198 { 1, "signature", ASN1_BIT_STRING
, ASN1_BODY
}, /* 21 */
199 { 1, "certsContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 22 */
200 { 2, "certs", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 23 */
201 { 3, "certificate", ASN1_SEQUENCE
, ASN1_RAW
}, /* 24 */
202 { 2, "end loop", ASN1_EOC
, ASN1_END
}, /* 25 */
203 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 26 */
204 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
206 #define BASIC_RESPONSE_TBS_DATA 1
207 #define BASIC_RESPONSE_VERSION 3
208 #define BASIC_RESPONSE_ID_BY_NAME 5
209 #define BASIC_RESPONSE_ID_BY_KEY 8
210 #define BASIC_RESPONSE_PRODUCED_AT 10
211 #define BASIC_RESPONSE_RESPONSES 11
212 #define BASIC_RESPONSE_EXT_ID 15
213 #define BASIC_RESPONSE_CRITICAL 16
214 #define BASIC_RESPONSE_EXT_VALUE 17
215 #define BASIC_RESPONSE_ALGORITHM 20
216 #define BASIC_RESPONSE_SIGNATURE 21
217 #define BASIC_RESPONSE_CERTIFICATE 24
220 * ASN.1 definition of responses
222 static const asn1Object_t responsesObjects
[] = {
223 { 0, "responses", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
224 { 1, "singleResponse", ASN1_EOC
, ASN1_RAW
}, /* 1 */
225 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 2 */
226 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
228 #define RESPONSES_SINGLE_RESPONSE 1
231 * ASN.1 definition of singleResponse
233 static const asn1Object_t singleResponseObjects
[] = {
234 { 0, "singleResponse", ASN1_SEQUENCE
, ASN1_BODY
}, /* 0 */
235 { 1, "certID", ASN1_SEQUENCE
, ASN1_NONE
}, /* 1 */
236 { 2, "algorithm", ASN1_EOC
, ASN1_RAW
}, /* 2 */
237 { 2, "issuerNameHash", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 3 */
238 { 2, "issuerKeyHash", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 4 */
239 { 2, "serialNumber", ASN1_INTEGER
, ASN1_BODY
}, /* 5 */
240 { 1, "certStatusGood", ASN1_CONTEXT_S_0
, ASN1_OPT
}, /* 6 */
241 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 7 */
242 { 1, "certStatusRevoked", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 8 */
243 { 2, "revocationTime", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 9 */
244 { 2, "revocationReason", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 10 */
245 { 3, "crlReason", ASN1_ENUMERATED
, ASN1_BODY
}, /* 11 */
246 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 12 */
247 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 13 */
248 { 1, "certStatusUnknown", ASN1_CONTEXT_S_2
, ASN1_OPT
}, /* 14 */
249 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 15 */
250 { 1, "thisUpdate", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 16 */
251 { 1, "nextUpdateContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 17 */
252 { 2, "nextUpdate", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 18 */
253 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 19 */
254 { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 20 */
255 { 2, "singleExtensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 21 */
256 { 3, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 22 */
257 { 4, "extnID", ASN1_OID
, ASN1_BODY
}, /* 23 */
258 { 4, "critical", ASN1_BOOLEAN
, ASN1_BODY
|
260 { 4, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 25 */
261 { 2, "end loop", ASN1_EOC
, ASN1_END
}, /* 26 */
262 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 27 */
263 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
265 #define SINGLE_RESPONSE_ALGORITHM 2
266 #define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
267 #define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
268 #define SINGLE_RESPONSE_SERIAL_NUMBER 5
269 #define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
270 #define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
271 #define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
272 #define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
273 #define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
274 #define SINGLE_RESPONSE_THIS_UPDATE 16
275 #define SINGLE_RESPONSE_NEXT_UPDATE 18
276 #define SINGLE_RESPONSE_EXT_ID 23
277 #define SINGLE_RESPONSE_CRITICAL 24
278 #define SINGLE_RESPONSE_EXT_VALUE 25
281 * Build an ocsp location from certificate information
282 * without unsharing its contents
284 static bool build_ocsp_location(const x509cert_t
*cert
, ocsp_location_t
*location
)
286 certificate_t
*certificate
= cert
->cert
;
287 identification_t
*issuer
= certificate
->get_issuer(certificate
);
288 x509_t
*x509
= (x509_t
*)certificate
;
289 chunk_t issuer_dn
= issuer
->get_encoding(issuer
);
290 chunk_t authKeyID
= x509
->get_authKeyIdentifier(x509
);
292 static u_char digest
[HASH_SIZE_SHA1
]; /* temporary storage */
294 enumerator_t
*enumerator
= x509
->create_ocsp_uri_enumerator(x509
);
296 location
->uri
= NULL
;
297 while (enumerator
->enumerate(enumerator
, &location
->uri
))
301 enumerator
->destroy(enumerator
);
303 if (location
->uri
== NULL
)
305 ca_info_t
*ca
= get_ca_info(issuer_dn
, authKeyID
);
306 if (ca
!= NULL
&& ca
->ocspuri
!= NULL
)
308 location
->uri
= ca
->ocspuri
;
311 { /* abort if no ocsp location uri is defined */
316 /* compute authNameID from as SHA-1 hash of issuer DN */
317 location
->authNameID
= chunk_create(digest
, HASH_SIZE_SHA1
);
318 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
323 hasher
->get_hash(hasher
, issuer_dn
, digest
);
324 hasher
->destroy(hasher
);
326 location
->next
= NULL
;
327 location
->issuer
= issuer_dn
;
328 location
->authKeyID
= authKeyID
;
330 if (authKeyID
.ptr
== NULL
)
332 x509cert_t
*authcert
= get_authcert(issuer_dn
, authKeyID
, AUTH_CA
);
334 if (authcert
!= NULL
)
336 x509_t
*x509
= (x509_t
*)authcert
->cert
;
338 location
->authKeyID
= x509
->get_subjectKeyIdentifier(x509
);
342 location
->nonce
= chunk_empty
;
343 location
->certinfo
= NULL
;
349 * Compare two ocsp locations for equality
351 static bool same_ocsp_location(const ocsp_location_t
*a
, const ocsp_location_t
*b
)
353 return ((a
->authKeyID
.ptr
!= NULL
)
354 ?
same_keyid(a
->authKeyID
, b
->authKeyID
)
355 : same_dn(a
->issuer
, b
->issuer
))
356 && streq(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 x509_t
*x509
= (x509_t
*)cert
->cert
;
424 chunk_t serialNumber
= x509
->get_serial(x509
);
425 cert_status_t status
;
426 ocsp_location_t location
;
427 time_t nextUpdate
= 0;
429 *revocationDate
= UNDEFINED_TIME
;
430 *revocationReason
= CRL_REASON_UNSPECIFIED
;
432 /* is an ocsp location defined? */
433 if (!build_ocsp_location(cert
, &location
))
435 return CERT_UNDEFINED
;
438 lock_ocsp_cache("verify_by_ocsp");
439 status
= get_ocsp_status(&location
, serialNumber
, &nextUpdate
440 , revocationDate
, revocationReason
);
441 unlock_ocsp_cache("verify_by_ocsp");
443 if (status
== CERT_UNDEFINED
|| nextUpdate
< time(NULL
))
445 plog("ocsp status is stale or not in cache");
446 add_ocsp_fetch_request(&location
, serialNumber
);
448 /* inititate fetching of ocsp status */
449 wake_fetch_thread("verify_by_ocsp");
456 * Check if an ocsp status is about to expire
458 void check_ocsp(void)
460 ocsp_location_t
*location
;
462 lock_ocsp_cache("check_ocsp");
463 location
= ocsp_cache
;
465 while (location
!= NULL
)
469 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
471 while (certinfo
!= NULL
)
475 time_t time_left
= certinfo
->nextUpdate
- time(NULL
);
480 dntoa(buf
, BUF_LEN
, location
->issuer
);
481 DBG_log("issuer: '%s'", buf
);
482 if (location
->authKeyID
.ptr
!= NULL
)
484 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
485 , ':', buf
, BUF_LEN
);
486 DBG_log("authkey: %s", buf
);
490 datatot(certinfo
->serialNumber
.ptr
, certinfo
->serialNumber
.len
491 , ':', buf
, BUF_LEN
);
492 DBG_log("serial: %s, %ld seconds left", buf
, time_left
)
495 if (time_left
< 2*crl_check_interval
)
496 add_ocsp_fetch_request(location
, certinfo
->serialNumber
);
498 certinfo
= certinfo
->next
;
500 location
= location
->next
;
502 unlock_ocsp_cache("check_ocsp");
506 * frees the allocated memory of a certinfo struct
508 static void free_certinfo(ocsp_certinfo_t
*certinfo
)
510 free(certinfo
->serialNumber
.ptr
);
515 * frees all certinfos in a chained list
517 static void free_certinfos(ocsp_certinfo_t
*chain
)
519 ocsp_certinfo_t
*certinfo
;
521 while (chain
!= NULL
)
525 free_certinfo(certinfo
);
530 * Frees the memory allocated to an ocsp location including all certinfos
532 static void free_ocsp_location(ocsp_location_t
* location
)
534 free(location
->issuer
.ptr
);
535 free(location
->authNameID
.ptr
);
536 free(location
->authKeyID
.ptr
);
538 free_certinfos(location
->certinfo
);
543 * Free a chained list of ocsp locations
545 void free_ocsp_locations(ocsp_location_t
**chain
)
547 while (*chain
!= NULL
)
549 ocsp_location_t
*location
= *chain
;
550 *chain
= location
->next
;
551 free_ocsp_location(location
);
556 * Free the ocsp cache
558 void free_ocsp_cache(void)
560 lock_ocsp_cache("free_ocsp_cache");
561 free_ocsp_locations(&ocsp_cache
);
562 unlock_ocsp_cache("free_ocsp_cache");
566 * Frees the ocsp cache and global variables
570 free(ocsp_default_uri
.ptr
);
575 * List a chained list of ocsp_locations
577 void list_ocsp_locations(ocsp_location_t
*location
, bool requests
,
578 bool utc
, bool strict
)
582 while (location
!= NULL
)
584 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
586 if (certinfo
!= NULL
)
592 whack_log(RC_COMMENT
, " ");
593 whack_log(RC_COMMENT
, "List of OCSP %s:", requests?
594 "fetch requests":"responses");
597 whack_log(RC_COMMENT
, " ");
598 if (location
->issuer
.ptr
!= NULL
)
600 dntoa(buf
, BUF_LEN
, location
->issuer
);
601 whack_log(RC_COMMENT
, " issuer: '%s'", buf
);
603 whack_log(RC_COMMENT
, " uri: '%s'", location
->uri
);
604 if (location
->authNameID
.ptr
!= NULL
)
606 datatot(location
->authNameID
.ptr
, location
->authNameID
.len
, ':'
608 whack_log(RC_COMMENT
, " authname: %s", buf
);
610 if (location
->authKeyID
.ptr
!= NULL
)
612 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
, ':'
614 whack_log(RC_COMMENT
, " authkey: %s", buf
);
616 while (certinfo
!= NULL
)
618 char thisUpdate
[BUF_LEN
];
620 snprintf(thisUpdate
, BUF_LEN
, "%T", &certinfo
->thisUpdate
, utc
);
624 whack_log(RC_COMMENT
, "%s, trials: %d", thisUpdate
627 else if (certinfo
->once
)
629 whack_log(RC_COMMENT
, "%s, onetime use%s", thisUpdate
630 , (certinfo
->nextUpdate
< time(NULL
))?
" (expired)": "");
634 whack_log(RC_COMMENT
, "%s, until %T %s", thisUpdate
635 , &certinfo
->nextUpdate
, utc
636 , check_expiry(certinfo
->nextUpdate
, OCSP_WARNING_INTERVAL
, strict
));
638 datatot(certinfo
->serialNumber
.ptr
, certinfo
->serialNumber
.len
, ':'
640 whack_log(RC_COMMENT
, " serial: %s, %s", buf
641 , cert_status_names
[certinfo
->status
]);
642 certinfo
= certinfo
->next
;
645 location
= location
->next
;
650 * List the ocsp cache
652 void list_ocsp_cache(bool utc
, bool strict
)
654 lock_ocsp_cache("list_ocsp_cache");
655 list_ocsp_locations(ocsp_cache
, FALSE
, utc
, strict
);
656 unlock_ocsp_cache("list_ocsp_cache");
659 static bool get_ocsp_requestor_cert(ocsp_location_t
*location
)
661 x509cert_t
*cert
= NULL
;
663 /* initialize temporary static storage */
664 ocsp_requestor_cert
= NULL
;
665 ocsp_requestor_sc
= NULL
;
666 ocsp_requestor_key
= NULL
;
670 certificate_t
*certificate
;
672 /* looking for a certificate from the same issuer */
673 cert
= get_x509cert(location
->issuer
, location
->authKeyID
, cert
);
678 certificate
= cert
->cert
;
680 DBG_log("candidate: '%Y'", certificate
->get_subject(certificate
));
685 /* look for a matching private key on a smartcard */
686 smartcard_t
*sc
= scx_get(cert
);
691 DBG_log("matching smartcard found")
695 ocsp_requestor_cert
= cert
;
696 ocsp_requestor_sc
= sc
;
699 plog("unable to sign ocsp request without PIN");
704 /* look for a matching private key in the chained list */
705 private_key_t
*private = get_x509_private_key(cert
);
710 DBG_log("matching private key found")
712 ocsp_requestor_cert
= cert
;
713 ocsp_requestor_key
= private;
721 static chunk_t
sc_build_sha1_signature(chunk_t tbs
, smartcard_t
*sc
)
726 chunk_t digest_info
, sigdata
;
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 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
754 hasher
->allocate_hash(hasher
, tbs
, &digest
);
755 hasher
->destroy(hasher
);
757 /* according to PKCS#1 v2.1 digest must be packaged into
758 * an ASN.1 structure for encryption
760 digest_info
= asn1_wrap(ASN1_SEQUENCE
, "mm"
761 , asn1_algorithmIdentifier(OID_SHA1
)
762 , asn1_wrap(ASN1_OCTET_STRING
, "m", digest
));
764 pos
= asn1_build_object(&sigdata
, ASN1_BIT_STRING
, 1 + siglen
);
766 scx_sign_hash(sc
, digest_info
.ptr
, digest_info
.len
, pos
, siglen
);
767 free(digest_info
.ptr
);
769 if (!pkcs11_keep_state
)
771 scx_release_context(sc
);
777 * build signature into ocsp request gets built only if a request cert
778 * with a corresponding private key is found
780 static chunk_t
build_signature(chunk_t tbsRequest
)
782 chunk_t sigdata
, cert
, certs
;
784 if (ocsp_requestor_sc
!= NULL
)
786 /* RSA signature is done on smartcard */
787 sigdata
= sc_build_sha1_signature(tbsRequest
, ocsp_requestor_sc
);
791 /* RSA signature is done in software */
792 sigdata
= x509_build_signature(tbsRequest
, OID_SHA1
, ocsp_requestor_key
,
795 if (sigdata
.ptr
== NULL
)
800 /* include our certificate */
801 cert
= ocsp_requestor_cert
->cert
->get_encoding(ocsp_requestor_cert
->cert
);
802 certs
= asn1_wrap(ASN1_CONTEXT_C_0
, "m",
803 asn1_wrap(ASN1_SEQUENCE
, "m", cert
));
805 /* build signature comprising algorithm, signature and cert */
806 return asn1_wrap(ASN1_CONTEXT_C_0
, "m"
807 , asn1_wrap(ASN1_SEQUENCE
, "mmm"
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
, "mmmm"
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 certificate_t
*certificate
= ocsp_requestor_cert
->cert
;
879 identification_t
*subject
= certificate
->get_subject(certificate
);
881 return asn1_wrap(ASN1_CONTEXT_C_1
, "m"
882 , asn1_simple_object(ASN1_CONTEXT_C_4
883 , subject
->get_encoding(subject
)));
887 * build nonce extension (into requestExtensions)
889 static chunk_t
build_nonce_extension(ocsp_location_t
*location
)
893 /* generate a random nonce */
894 location
->nonce
.ptr
= malloc(NONCE_LENGTH
),
895 location
->nonce
.len
= NONCE_LENGTH
;
896 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_STRONG
);
897 rng
->get_bytes(rng
, location
->nonce
.len
, location
->nonce
.ptr
);
900 return asn1_wrap(ASN1_SEQUENCE
, "cm"
902 , asn1_simple_object(ASN1_OCTET_STRING
, location
->nonce
));
906 * Build requestExtensions (into TBSRequest)
908 static chunk_t
build_request_ext(ocsp_location_t
*location
)
910 return asn1_wrap(ASN1_CONTEXT_C_2
, "m"
911 , asn1_wrap(ASN1_SEQUENCE
, "mm"
912 , build_nonce_extension(location
)
913 , asn1_wrap(ASN1_SEQUENCE
, "cc"
915 , ASN1_response_content
922 * Build TBSRequest (into OCSPRequest)
924 static chunk_t
build_tbs_request(ocsp_location_t
*location
, bool has_requestor_cert
)
926 /* version is skipped since the default is ok */
927 return asn1_wrap(ASN1_SEQUENCE
, "mmm"
928 , (has_requestor_cert
)
929 ?
build_requestor_name()
931 , build_request_list(location
)
932 , build_request_ext(location
));
936 * Assembles an ocsp request to given location
937 * and sets nonce field in location to the sent nonce
939 chunk_t
build_ocsp_request(ocsp_location_t
*location
)
941 bool has_requestor_cert
;
942 chunk_t tbsRequest
, signature
;
946 DBG_log("assembling ocsp request");
947 dntoa(buf
, BUF_LEN
, location
->issuer
);
948 DBG_log("issuer: '%s'", buf
);
949 if (location
->authKeyID
.ptr
!= NULL
)
951 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
, ':'
953 DBG_log("authkey: %s", buf
);
956 lock_certs_and_keys("build_ocsp_request");
958 /* looks for requestor cert and matching private key */
959 has_requestor_cert
= get_ocsp_requestor_cert(location
);
962 tbsRequest
= build_tbs_request(location
, has_requestor_cert
);
964 /* sign tbsReuqest */
965 signature
= (has_requestor_cert
)?
build_signature(tbsRequest
)
968 unlock_certs_and_keys("build_ocsp_request");
970 return asn1_wrap(ASN1_SEQUENCE
, "mm"
976 * Check if the OCSP response has a valid signature
978 static bool valid_ocsp_response(response_t
*res
)
981 x509cert_t
*authcert
;
983 lock_authcert_list("valid_ocsp_response");
985 authcert
= get_authcert(res
->responder_id_name
, res
->responder_id_key
,
986 AUTH_OCSP
| AUTH_CA
);
987 if (authcert
== NULL
)
989 plog("no matching ocsp signer cert found");
990 unlock_authcert_list("valid_ocsp_response");
994 DBG_log("ocsp signer cert found")
997 if (!x509_check_signature(res
->tbs
, res
->signature
, res
->algorithm
,
1000 plog("signature of ocsp response is invalid");
1001 unlock_authcert_list("valid_ocsp_response");
1005 DBG_log("signature of ocsp response is valid")
1009 for (pathlen
= 0; pathlen
< MAX_CA_PATH_LEN
; pathlen
++)
1014 x509cert_t
*cert
= authcert
;
1015 certificate_t
*certificate
= cert
->cert
;
1016 x509_t
*x509
= (x509_t
*)certificate
;
1017 identification_t
*subject
= certificate
->get_subject(certificate
);
1018 identification_t
*issuer
= certificate
->get_issuer(certificate
);
1019 chunk_t authKeyID
= x509
->get_authKeyIdentifier(x509
);
1022 DBG_log("subject: '%Y'", subject
);
1023 DBG_log("issuer: '%Y'", issuer
);
1024 if (authKeyID
.ptr
!= NULL
)
1026 DBG_log("authkey: %#B", &authKeyID
);
1030 ugh
= check_validity(authcert
, &until
);
1035 unlock_authcert_list("valid_ocsp_response");
1040 DBG_log("certificate is valid")
1043 authcert
= get_authcert(issuer
->get_encoding(issuer
), 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 (!certificate
->issued_by(certificate
, authcert
->cert
))
1056 plog("certificate signature is invalid");
1057 unlock_authcert_list("valid_ocsp_response");
1061 DBG_log("certificate signature is valid")
1064 /* check if cert is self-signed */
1065 if (x509
->get_flags(x509
) & X509_SELF_SIGNED
)
1068 DBG_log("reached self-signed root ca")
1070 unlock_authcert_list("valid_ocsp_response");
1074 plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN
);
1075 unlock_authcert_list("valid_ocsp_response");
1080 * Parse a basic OCSP response
1082 static bool parse_basic_ocsp_response(chunk_t blob
, int level0
, response_t
*res
)
1084 asn1_parser_t
*parser
;
1087 u_char buf
[BUF_LEN
];
1089 int extn_oid
= OID_UNKNOWN
;
1090 bool success
= FALSE
;
1093 parser
= asn1_parser_create(basicResponseObjects
, blob
);
1094 parser
->set_top_level(parser
, level0
);
1096 while (parser
->iterate(parser
, &objectID
, &object
))
1100 case BASIC_RESPONSE_TBS_DATA
:
1103 case BASIC_RESPONSE_VERSION
:
1104 version
= (object
.len
)?
(1 + (u_int
)*object
.ptr
) : 1;
1105 if (version
!= OCSP_BASIC_RESPONSE_VERSION
)
1107 plog("wrong ocsp basic response version (version= %i)", version
);
1111 case BASIC_RESPONSE_ID_BY_NAME
:
1112 res
->responder_id_name
= object
;
1114 dntoa(buf
, BUF_LEN
, object
);
1115 DBG_log(" '%s'",buf
)
1118 case BASIC_RESPONSE_ID_BY_KEY
:
1119 res
->responder_id_key
= object
;
1121 case BASIC_RESPONSE_PRODUCED_AT
:
1122 res
->produced_at
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
1124 case BASIC_RESPONSE_RESPONSES
:
1125 res
->responses
= object
;
1127 case BASIC_RESPONSE_EXT_ID
:
1128 extn_oid
= asn1_known_oid(object
);
1130 case BASIC_RESPONSE_CRITICAL
:
1131 critical
= object
.len
&& *object
.ptr
;
1133 DBG_log(" %s",(critical
)?
"TRUE":"FALSE");
1136 case BASIC_RESPONSE_EXT_VALUE
:
1137 if (extn_oid
== OID_NONCE
)
1138 res
->nonce
= object
;
1140 case BASIC_RESPONSE_ALGORITHM
:
1141 res
->algorithm
= asn1_parse_algorithmIdentifier(object
,
1142 parser
->get_level(parser
)+1, NULL
);
1144 case BASIC_RESPONSE_SIGNATURE
:
1145 res
->signature
= object
;
1147 case BASIC_RESPONSE_CERTIFICATE
:
1149 x509cert_t
*cert
= malloc_thing(x509cert_t
);
1152 *cert
= empty_x509cert
;
1153 cert
->cert
= lib
->creds
->create(lib
->creds
,
1154 CRED_CERTIFICATE
, CERT_X509
,
1155 BUILD_BLOB_ASN1_DER
, object
,
1157 if (cert
->cert
== NULL
)
1159 DBG(DBG_CONTROL
| DBG_PARSING
,
1160 DBG_log("parsing of embedded ocsp certificate failed")
1162 free_x509cert(cert
);
1165 time(&cert
->installed
);
1166 x509
= (x509_t
*)cert
->cert
;
1168 if ((x509
->get_flags(x509
) & X509_OCSP_SIGNER
) &&
1169 trust_authcert_candidate(cert
, NULL
))
1171 add_authcert(cert
, AUTH_OCSP
);
1175 DBG(DBG_CONTROL
| DBG_PARSING
,
1176 DBG_log("embedded ocsp certificate rejected")
1178 free_x509cert(cert
);
1184 success
= parser
->success(parser
);
1187 parser
->destroy(parser
);
1194 * Parse an ocsp response and return the result as a response_t struct
1196 static response_status
parse_ocsp_response(chunk_t blob
, response_t
* res
)
1198 asn1_parser_t
*parser
;
1201 int ocspResponseType
= OID_UNKNOWN
;
1202 bool success
= FALSE
;
1203 response_status rStatus
= STATUS_INTERNALERROR
;
1205 parser
= asn1_parser_create(ocspResponseObjects
, blob
);
1207 while (parser
->iterate(parser
, &objectID
, &object
))
1210 case OCSP_RESPONSE_STATUS
:
1211 rStatus
= (response_status
) *object
.ptr
;
1215 case STATUS_SUCCESSFUL
:
1217 case STATUS_MALFORMEDREQUEST
:
1218 case STATUS_INTERNALERROR
:
1219 case STATUS_TRYLATER
:
1220 case STATUS_SIGREQUIRED
:
1221 case STATUS_UNAUTHORIZED
:
1222 plog("ocsp response: server said '%s'"
1223 , response_status_names
[rStatus
]);
1229 case OCSP_RESPONSE_TYPE
:
1230 ocspResponseType
= asn1_known_oid(object
);
1234 switch (ocspResponseType
) {
1236 success
= parse_basic_ocsp_response(object
,
1237 parser
->get_level(parser
)+1, res
);
1241 DBG_log("ocsp response is not of type BASIC");
1242 DBG_dump_chunk("ocsp response OID: ", object
);
1250 success
&= parser
->success(parser
);
1253 parser
->destroy(parser
);
1258 * Parse a basic OCSP response
1260 static bool parse_ocsp_single_response(chunk_t blob
, int level0
,
1261 single_response_t
*sres
)
1263 asn1_parser_t
*parser
;
1268 bool success
= FALSE
;
1270 parser
= asn1_parser_create(singleResponseObjects
, blob
);
1271 parser
->set_top_level(parser
, level0
);
1273 while (parser
->iterate(parser
, &objectID
, &object
))
1277 case SINGLE_RESPONSE_ALGORITHM
:
1278 sres
->hash_algorithm
= asn1_parse_algorithmIdentifier(object
,
1279 parser
->get_level(parser
)+1, NULL
);
1281 case SINGLE_RESPONSE_ISSUER_NAME_HASH
:
1282 sres
->issuer_name_hash
= object
;
1284 case SINGLE_RESPONSE_ISSUER_KEY_HASH
:
1285 sres
->issuer_key_hash
= object
;
1287 case SINGLE_RESPONSE_SERIAL_NUMBER
:
1288 sres
->serialNumber
= object
;
1290 case SINGLE_RESPONSE_CERT_STATUS_GOOD
:
1291 sres
->status
= CERT_GOOD
;
1293 case SINGLE_RESPONSE_CERT_STATUS_REVOKED
:
1294 sres
->status
= CERT_REVOKED
;
1296 case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME
:
1297 sres
->revocationTime
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
1299 case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON
:
1300 sres
->revocationReason
= (object
.len
== 1)
1301 ?
*object
.ptr
: CRL_REASON_UNSPECIFIED
;
1303 case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN
:
1304 sres
->status
= CERT_UNKNOWN
;
1306 case SINGLE_RESPONSE_THIS_UPDATE
:
1307 sres
->thisUpdate
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
1309 case SINGLE_RESPONSE_NEXT_UPDATE
:
1310 sres
->nextUpdate
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
1312 case SINGLE_RESPONSE_EXT_ID
:
1313 extn_oid
= asn1_known_oid(object
);
1315 case SINGLE_RESPONSE_CRITICAL
:
1316 critical
= object
.len
&& *object
.ptr
;
1318 DBG_log(" %s",(critical
)?
"TRUE":"FALSE");
1320 case SINGLE_RESPONSE_EXT_VALUE
:
1324 success
= parser
->success(parser
);
1325 parser
->destroy(parser
);
1330 * Add an ocsp location to a chained list
1332 ocsp_location_t
* add_ocsp_location(const ocsp_location_t
*loc
,
1333 ocsp_location_t
**chain
)
1335 ocsp_location_t
*location
= malloc_thing(ocsp_location_t
);
1337 /* unshare location fields */
1338 location
->issuer
= chunk_clone(loc
->issuer
);
1339 location
->authNameID
= chunk_clone(loc
->authNameID
);
1340 location
->authKeyID
= chunk_clone(loc
->authKeyID
);
1341 location
->uri
= strdup(loc
->uri
);
1342 location
->certinfo
= NULL
;
1344 /* insert new ocsp location in front of chain */
1345 location
->next
= *chain
;
1349 DBG_log("new ocsp location added")
1356 * add a certinfo struct to a chained list
1358 void add_certinfo(ocsp_location_t
*loc
, ocsp_certinfo_t
*info
,
1359 ocsp_location_t
**chain
, bool request
)
1361 ocsp_location_t
*location
;
1362 ocsp_certinfo_t
*certinfo
, **certinfop
;
1367 location
= get_ocsp_location(loc
, *chain
);
1368 if (location
== NULL
)
1370 location
= add_ocsp_location(loc
, chain
);
1373 /* traverse list of certinfos in increasing order */
1374 certinfop
= &location
->certinfo
;
1375 certinfo
= *certinfop
;
1377 while (certinfo
!= NULL
)
1379 cmp
= chunk_compare(info
->serialNumber
, certinfo
->serialNumber
);
1382 certinfop
= &certinfo
->next
;
1383 certinfo
= *certinfop
;
1388 /* add a new certinfo entry */
1389 ocsp_certinfo_t
*cnew
= malloc_thing(ocsp_certinfo_t
);
1391 cnew
->serialNumber
= chunk_clone(info
->serialNumber
);
1392 cnew
->next
= certinfo
;
1398 datatot(info
->serialNumber
.ptr
, info
->serialNumber
.len
, ':'
1400 DBG_log("ocsp %s for serial %s %s"
1401 , request?
"fetch request":"certinfo"
1403 , (cmp
== 0)?
(request?
"already exists":"updated"):"added")
1410 certinfo
->status
= CERT_UNDEFINED
;
1414 certinfo
->thisUpdate
= now
;
1416 certinfo
->nextUpdate
= UNDEFINED_TIME
;
1420 certinfo
->status
= info
->status
;
1421 certinfo
->revocationTime
= info
->revocationTime
;
1422 certinfo
->revocationReason
= info
->revocationReason
;
1424 certinfo
->thisUpdate
= (info
->thisUpdate
!= UNDEFINED_TIME
)?
1425 info
->thisUpdate
: now
;
1427 certinfo
->once
= (info
->nextUpdate
== UNDEFINED_TIME
);
1429 certinfo
->nextUpdate
= (certinfo
->once
)?
1430 (now
+ OCSP_DEFAULT_VALID_TIME
) : info
->nextUpdate
;
1435 * Process received ocsp single response and add it to ocsp cache
1437 static void process_single_response(ocsp_location_t
*location
,
1438 single_response_t
*sres
)
1440 ocsp_certinfo_t
*certinfo
, **certinfop
;
1443 if (sres
->hash_algorithm
!= OID_SHA1
)
1445 plog("only SHA-1 hash supported in OCSP single response");
1448 if (!(chunk_equals(sres
->issuer_name_hash
, location
->authNameID
)
1449 && chunk_equals(sres
->issuer_key_hash
, location
->authKeyID
)))
1451 plog("ocsp single response has wrong issuer");
1455 /* traverse list of certinfos in increasing order */
1456 certinfop
= &location
->certinfo
;
1457 certinfo
= *certinfop
;
1459 while (certinfo
!= NULL
)
1461 cmp
= chunk_compare(sres
->serialNumber
, certinfo
->serialNumber
);
1464 certinfop
= &certinfo
->next
;
1465 certinfo
= *certinfop
;
1470 plog("received unrequested cert status from ocsp server");
1474 /* unlink cert from ocsp fetch request list */
1475 *certinfop
= certinfo
->next
;
1477 /* update certinfo using the single response information */
1478 certinfo
->thisUpdate
= sres
->thisUpdate
;
1479 certinfo
->nextUpdate
= sres
->nextUpdate
;
1480 certinfo
->status
= sres
->status
;
1481 certinfo
->revocationTime
= sres
->revocationTime
;
1482 certinfo
->revocationReason
= sres
->revocationReason
;
1484 /* add or update certinfo in ocsp cache */
1485 lock_ocsp_cache("process_single_response");
1486 add_certinfo(location
, certinfo
, &ocsp_cache
, FALSE
);
1487 unlock_ocsp_cache("process_single_response");
1489 /* free certinfo unlinked from ocsp fetch request list */
1490 free_certinfo(certinfo
);
1494 * Parse and verify ocsp response and update the ocsp cache
1496 void parse_ocsp(ocsp_location_t
*location
, chunk_t blob
)
1498 response_t res
= empty_response
;
1500 /* parse the ocsp response without looking at the single responses yet */
1501 response_status status
= parse_ocsp_response(blob
, &res
);
1503 if (status
!= STATUS_SUCCESSFUL
)
1505 plog("error in ocsp response");
1508 /* check if there was a nonce in the request */
1509 if (location
->nonce
.ptr
!= NULL
&& res
.nonce
.ptr
== NULL
)
1511 plog("ocsp response contains no nonce, replay attack possible");
1513 /* check if the nonce is identical */
1514 if (res
.nonce
.ptr
!= NULL
&& !chunk_equals(res
.nonce
, location
->nonce
))
1516 plog("invalid nonce in ocsp response");
1519 /* check if the response is signed by a trusted key */
1520 if (!valid_ocsp_response(&res
))
1522 plog("invalid ocsp response");
1526 DBG_log("valid ocsp response")
1529 /* now parse the single responses one at a time */
1531 asn1_parser_t
*parser
;
1535 parser
= asn1_parser_create(responsesObjects
, res
.responses
);
1537 while (parser
->iterate(parser
, &objectID
, &object
))
1539 if (objectID
== RESPONSES_SINGLE_RESPONSE
)
1541 single_response_t sres
= empty_single_response
;
1543 if (!parse_ocsp_single_response(object
,
1544 parser
->get_level(parser
)+1, &sres
))
1548 process_single_response(location
, &sres
);
1552 parser
->destroy(parser
);