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
21 #include <sys/types.h>
26 #include <ipsec_policy.h>
28 #include "constants.h"
37 #include "smartcard.h"
45 #define NONCE_LENGTH 16
47 static const char *const cert_status_names
[] = {
55 static const char *const response_status_names
[] = {
64 /* response container */
65 typedef struct response response_t
;
69 chunk_t responder_id_name
;
70 chunk_t responder_id_key
;
78 const response_t empty_response
= {
79 { NULL
, 0 } , /* tbs */
80 { NULL
, 0 } , /* responder_id_name */
81 { NULL
, 0 } , /* responder_id_key */
82 UNDEFINED_TIME
, /* produced_at */
83 { NULL
, 0 } , /* single_response */
84 { NULL
, 0 } , /* nonce */
85 OID_UNKNOWN
, /* signature_algorithm */
86 { NULL
, 0 } /* signature */
89 /* single response container */
90 typedef struct single_response single_response_t
;
92 struct single_response
{
93 single_response_t
*next
;
95 chunk_t issuer_name_hash
;
96 chunk_t issuer_key_hash
;
99 time_t revocationTime
;
100 crl_reason_t revocationReason
;
105 const single_response_t empty_single_response
= {
107 OID_UNKNOWN
, /* hash_algorithm */
108 { NULL
, 0 } , /* issuer_name_hash */
109 { NULL
, 0 } , /* issuer_key_hash */
110 { NULL
, 0 } , /* serial_number */
111 CERT_UNDEFINED
, /* status */
112 UNDEFINED_TIME
, /* revocationTime */
113 REASON_UNSPECIFIED
, /* revocationReason */
114 UNDEFINED_TIME
, /* this_update */
115 UNDEFINED_TIME
/* next_update */
119 /* list of single requests */
120 typedef struct request_list request_list_t
;
121 struct request_list
{
123 request_list_t
*next
;
126 /* some OCSP specific prefabricated ASN.1 constants */
128 static u_char ASN1_nonce_oid_str
[] = {
129 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
132 static const chunk_t ASN1_nonce_oid
= strchunk(ASN1_nonce_oid_str
);
134 static u_char ASN1_response_oid_str
[] = {
135 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
138 static const chunk_t ASN1_response_oid
= strchunk(ASN1_response_oid_str
);
140 static u_char ASN1_response_content_str
[] = {
143 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
146 static const chunk_t ASN1_response_content
= strchunk(ASN1_response_content_str
);
148 /* default OCSP uri */
149 static chunk_t ocsp_default_uri
;
151 /* ocsp cache: pointer to first element */
152 static ocsp_location_t
*ocsp_cache
= NULL
;
154 /* static temporary storage for ocsp requestor information */
155 static x509cert_t
*ocsp_requestor_cert
= NULL
;
157 static smartcard_t
*ocsp_requestor_sc
= NULL
;
159 static const struct RSA_private_key
*ocsp_requestor_pri
= NULL
;
161 /* asn.1 definitions for parsing */
163 static const asn1Object_t ocspResponseObjects
[] = {
164 { 0, "OCSPResponse", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
165 { 1, "responseStatus", ASN1_ENUMERATED
, ASN1_BODY
}, /* 1 */
166 { 1, "responseBytesContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 2 */
167 { 2, "responseBytes", ASN1_SEQUENCE
, ASN1_NONE
}, /* 3 */
168 { 3, "responseType", ASN1_OID
, ASN1_BODY
}, /* 4 */
169 { 3, "response", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 5 */
170 { 1, "end opt", ASN1_EOC
, ASN1_END
} /* 6 */
173 #define OCSP_RESPONSE_STATUS 1
174 #define OCSP_RESPONSE_TYPE 4
175 #define OCSP_RESPONSE 5
176 #define OCSP_RESPONSE_ROOF 7
178 static const asn1Object_t basicResponseObjects
[] = {
179 { 0, "BasicOCSPResponse", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
180 { 1, "tbsResponseData", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 1 */
181 { 2, "versionContext", ASN1_CONTEXT_C_0
, ASN1_NONE
|
183 { 3, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
184 { 2, "responderIdContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 4 */
185 { 3, "responderIdByName", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 5 */
186 { 2, "end choice", ASN1_EOC
, ASN1_END
}, /* 6 */
187 { 2, "responderIdContext", ASN1_CONTEXT_C_2
, ASN1_OPT
}, /* 7 */
188 { 3, "responderIdByKey", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 8 */
189 { 2, "end choice", ASN1_EOC
, ASN1_END
}, /* 9 */
190 { 2, "producedAt", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 10 */
191 { 2, "responses", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 11 */
192 { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 12 */
193 { 3, "responseExtensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 13 */
194 { 4, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 14 */
195 { 5, "extnID", ASN1_OID
, ASN1_BODY
}, /* 15 */
196 { 5, "critical", ASN1_BOOLEAN
, ASN1_BODY
|
198 { 5, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 17 */
199 { 4, "end loop", ASN1_EOC
, ASN1_END
}, /* 18 */
200 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 19 */
201 { 1, "signatureAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 20 */
202 { 1, "signature", ASN1_BIT_STRING
, ASN1_BODY
}, /* 21 */
203 { 1, "certsContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 22 */
204 { 2, "certs", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 23 */
205 { 3, "certificate", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 24 */
206 { 2, "end loop", ASN1_EOC
, ASN1_END
}, /* 25 */
207 { 1, "end opt", ASN1_EOC
, ASN1_END
} /* 26 */
210 #define BASIC_RESPONSE_TBS_DATA 1
211 #define BASIC_RESPONSE_VERSION 3
212 #define BASIC_RESPONSE_ID_BY_NAME 5
213 #define BASIC_RESPONSE_ID_BY_KEY 8
214 #define BASIC_RESPONSE_PRODUCED_AT 10
215 #define BASIC_RESPONSE_RESPONSES 11
216 #define BASIC_RESPONSE_EXT_ID 15
217 #define BASIC_RESPONSE_CRITICAL 16
218 #define BASIC_RESPONSE_EXT_VALUE 17
219 #define BASIC_RESPONSE_ALGORITHM 20
220 #define BASIC_RESPONSE_SIGNATURE 21
221 #define BASIC_RESPONSE_CERTIFICATE 24
222 #define BASIC_RESPONSE_ROOF 27
224 static const asn1Object_t responsesObjects
[] = {
225 { 0, "responses", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
226 { 1, "singleResponse", ASN1_EOC
, ASN1_RAW
}, /* 1 */
227 { 0, "end loop", ASN1_EOC
, ASN1_END
} /* 2 */
230 #define RESPONSES_SINGLE_RESPONSE 1
231 #define RESPONSES_ROOF 3
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 */
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
279 #define SINGLE_RESPONSE_ROOF 28
281 /* build an ocsp location from certificate information
282 * without unsharing its contents
285 build_ocsp_location(const x509cert_t
*cert
, ocsp_location_t
*location
)
287 static u_char digest
[SHA1_DIGEST_SIZE
]; /* temporary storage */
289 location
->uri
= cert
->accessLocation
;
291 if (location
->uri
.ptr
== NULL
)
293 ca_info_t
*ca
= get_ca_info(cert
->issuer
, cert
->authKeySerialNumber
295 if (ca
!= NULL
&& ca
->ocspuri
!= NULL
)
296 setchunk(location
->uri
, ca
->ocspuri
, strlen(ca
->ocspuri
))
298 /* abort if no ocsp location uri is defined */
302 setchunk(location
->authNameID
, digest
, SHA1_DIGEST_SIZE
);
303 compute_digest(cert
->issuer
, OID_SHA1
, &location
->authNameID
);
305 location
->next
= NULL
;
306 location
->issuer
= cert
->issuer
;
307 location
->authKeyID
= cert
->authKeyID
;
308 location
->authKeySerialNumber
= cert
->authKeySerialNumber
;
310 if (cert
->authKeyID
.ptr
== NULL
)
312 x509cert_t
*authcert
= get_authcert(cert
->issuer
313 , cert
->authKeySerialNumber
, cert
->authKeyID
, AUTH_CA
);
315 if (authcert
!= NULL
)
317 location
->authKeyID
= authcert
->subjectKeyID
;
318 location
->authKeySerialNumber
= authcert
->serialNumber
;
322 location
->nonce
= empty_chunk
;
323 location
->certinfo
= NULL
;
329 * compare two ocsp locations for equality
332 same_ocsp_location(const ocsp_location_t
*a
, const ocsp_location_t
*b
)
334 return ((a
->authKeyID
.ptr
!= NULL
)
335 ?
same_keyid(a
->authKeyID
, b
->authKeyID
)
336 : (same_dn(a
->issuer
, b
->issuer
)
337 && same_serial(a
->authKeySerialNumber
, b
->authKeySerialNumber
)))
338 && same_chunk(a
->uri
, b
->uri
);
342 * find an existing ocsp location in a chained list
345 get_ocsp_location(const ocsp_location_t
* loc
, ocsp_location_t
*chain
)
348 while (chain
!= NULL
)
350 if (same_ocsp_location(loc
, chain
))
357 /* retrieves the status of a cert from the ocsp cache
358 * returns CERT_UNDEFINED if no status is found
361 get_ocsp_status(const ocsp_location_t
*loc
, chunk_t serialNumber
362 ,time_t *nextUpdate
, time_t *revocationTime
, crl_reason_t
*revocationReason
)
364 ocsp_certinfo_t
*certinfo
, **certinfop
;
368 ocsp_location_t
*location
= get_ocsp_location(loc
, ocsp_cache
);
370 if (location
== NULL
)
371 return CERT_UNDEFINED
;
373 /* traverse list of certinfos in increasing order */
374 certinfop
= &location
->certinfo
;
375 certinfo
= *certinfop
;
377 while (certinfo
!= NULL
)
379 cmp
= cmp_chunk(serialNumber
, certinfo
->serialNumber
);
382 certinfop
= &certinfo
->next
;
383 certinfo
= *certinfop
;
388 *nextUpdate
= certinfo
->nextUpdate
;
389 *revocationTime
= certinfo
->revocationTime
;
390 *revocationReason
= certinfo
->revocationReason
;
391 return certinfo
->status
;
394 return CERT_UNDEFINED
;
398 * verify the ocsp status of a certificate
401 verify_by_ocsp(const x509cert_t
*cert
, time_t *until
402 , time_t *revocationDate
, crl_reason_t
*revocationReason
)
404 cert_status_t status
;
405 ocsp_location_t location
;
406 time_t nextUpdate
= 0;
408 *revocationDate
= UNDEFINED_TIME
;
409 *revocationReason
= REASON_UNSPECIFIED
;
411 /* is an ocsp location defined? */
412 if (!build_ocsp_location(cert
, &location
))
413 return CERT_UNDEFINED
;
415 lock_ocsp_cache("verify_by_ocsp");
416 status
= get_ocsp_status(&location
, cert
->serialNumber
, &nextUpdate
417 , revocationDate
, revocationReason
);
418 unlock_ocsp_cache("verify_by_ocsp");
420 if (status
== CERT_UNDEFINED
|| nextUpdate
< time(NULL
))
422 plog("ocsp status is stale or not in cache");
423 add_ocsp_fetch_request(&location
, cert
->serialNumber
);
425 /* inititate fetching of ocsp status */
426 wake_fetch_thread("verify_by_ocsp");
433 * check if an ocsp status is about to expire
438 ocsp_location_t
*location
;
440 lock_ocsp_cache("check_ocsp");
441 location
= ocsp_cache
;
443 while (location
!= NULL
)
447 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
449 while (certinfo
!= NULL
)
453 time_t time_left
= certinfo
->nextUpdate
- time(NULL
);
458 dntoa(buf
, BUF_LEN
, location
->issuer
);
459 DBG_log("issuer: '%s'", buf
);
460 if (location
->authKeyID
.ptr
!= NULL
)
462 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
463 , ':', buf
, BUF_LEN
);
464 DBG_log("authkey: %s", buf
);
468 datatot(certinfo
->serialNumber
.ptr
, certinfo
->serialNumber
.len
469 , ':', buf
, BUF_LEN
);
470 DBG_log("serial: %s, %ld seconds left", buf
, time_left
)
473 if (time_left
< 2*crl_check_interval
)
474 add_ocsp_fetch_request(location
, certinfo
->serialNumber
);
476 certinfo
= certinfo
->next
;
478 location
= location
->next
;
480 unlock_ocsp_cache("check_ocsp");
484 * frees the allocated memory of a certinfo struct
487 free_certinfo(ocsp_certinfo_t
*certinfo
)
489 freeanychunk(certinfo
->serialNumber
);
494 * frees all certinfos in a chained list
497 free_certinfos(ocsp_certinfo_t
*chain
)
499 ocsp_certinfo_t
*certinfo
;
501 while (chain
!= NULL
)
505 free_certinfo(certinfo
);
510 * frees the memory allocated to an ocsp location including all certinfos
513 free_ocsp_location(ocsp_location_t
* location
)
515 freeanychunk(location
->issuer
);
516 freeanychunk(location
->authNameID
);
517 freeanychunk(location
->authKeyID
);
518 freeanychunk(location
->authKeySerialNumber
);
519 freeanychunk(location
->uri
);
520 free_certinfos(location
->certinfo
);
525 * free a chained list of ocsp locations
528 free_ocsp_locations(ocsp_location_t
**chain
)
530 while (*chain
!= NULL
)
532 ocsp_location_t
*location
= *chain
;
533 *chain
= location
->next
;
534 free_ocsp_location(location
);
539 * free the ocsp cache
542 free_ocsp_cache(void)
544 lock_ocsp_cache("free_ocsp_cache");
545 free_ocsp_locations(&ocsp_cache
);
546 unlock_ocsp_cache("free_ocsp_cache");
550 * frees the ocsp cache and global variables
555 pfreeany(ocsp_default_uri
.ptr
);
560 * list a chained list of ocsp_locations
563 list_ocsp_locations(ocsp_location_t
*location
, bool requests
, bool utc
568 while (location
!= NULL
)
570 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
572 if (certinfo
!= NULL
)
578 whack_log(RC_COMMENT
, " ");
579 whack_log(RC_COMMENT
, "List of OCSP %s:", requests?
580 "fetch requests":"responses");
583 whack_log(RC_COMMENT
, " ");
584 if (location
->issuer
.ptr
!= NULL
)
586 dntoa(buf
, BUF_LEN
, location
->issuer
);
587 whack_log(RC_COMMENT
, " issuer: '%s'", buf
);
589 whack_log(RC_COMMENT
, " uri: '%.*s'", (int)location
->uri
.len
590 , location
->uri
.ptr
);
591 if (location
->authNameID
.ptr
!= NULL
)
593 datatot(location
->authNameID
.ptr
, location
->authNameID
.len
, ':'
595 whack_log(RC_COMMENT
, " authname: %s", buf
);
597 if (location
->authKeyID
.ptr
!= NULL
)
599 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
, ':'
601 whack_log(RC_COMMENT
, " authkey: %s", buf
);
603 if (location
->authKeySerialNumber
.ptr
!= NULL
)
605 datatot(location
->authKeySerialNumber
.ptr
606 , location
->authKeySerialNumber
.len
, ':', buf
, BUF_LEN
);
607 whack_log(RC_COMMENT
, " aserial: %s", buf
);
609 while (certinfo
!= NULL
)
611 char thisUpdate
[TIMETOA_BUF
];
613 strcpy(thisUpdate
, timetoa(&certinfo
->thisUpdate
, utc
));
617 whack_log(RC_COMMENT
, "%s, trials: %d", thisUpdate
620 else if (certinfo
->once
)
622 whack_log(RC_COMMENT
, "%s, onetime use%s", thisUpdate
623 , (certinfo
->nextUpdate
< time(NULL
))?
" (expired)": "");
627 whack_log(RC_COMMENT
, "%s, until %s %s", thisUpdate
628 , timetoa(&certinfo
->nextUpdate
, utc
)
629 , check_expiry(certinfo
->nextUpdate
, OCSP_WARNING_INTERVAL
, strict
));
631 datatot(certinfo
->serialNumber
.ptr
, certinfo
->serialNumber
.len
, ':'
633 whack_log(RC_COMMENT
, " serial: %s, %s", buf
634 , cert_status_names
[certinfo
->status
]);
635 certinfo
= certinfo
->next
;
638 location
= location
->next
;
643 * list the ocsp cache
646 list_ocsp_cache(bool utc
, bool strict
)
648 lock_ocsp_cache("list_ocsp_cache");
649 list_ocsp_locations(ocsp_cache
, FALSE
, utc
, strict
);
650 unlock_ocsp_cache("list_ocsp_cache");
654 get_ocsp_requestor_cert(ocsp_location_t
*location
)
656 x509cert_t
*cert
= NULL
;
658 /* initialize temporary static storage */
659 ocsp_requestor_cert
= NULL
;
660 ocsp_requestor_sc
= NULL
;
661 ocsp_requestor_pri
= NULL
;
667 /* looking for a certificate from the same issuer */
668 cert
= get_x509cert(location
->issuer
, location
->authKeySerialNumber
669 ,location
->authKeyID
, cert
);
674 dntoa(buf
, BUF_LEN
, cert
->subject
);
675 DBG_log("candidate: '%s'", buf
);
680 /* look for a matching private key on a smartcard */
681 smartcard_t
*sc
= scx_get(cert
);
686 DBG_log("matching smartcard found")
690 ocsp_requestor_cert
= cert
;
691 ocsp_requestor_sc
= sc
;
694 plog("unable to sign ocsp request without PIN");
699 /* look for a matching private key in the chained list */
700 const struct RSA_private_key
*pri
= get_x509_private_key(cert
);
705 DBG_log("matching private key found")
707 ocsp_requestor_cert
= cert
;
708 ocsp_requestor_pri
= pri
;
717 generate_signature(chunk_t digest
, smartcard_t
*sc
718 , const RSA_private_key_t
*pri
)
726 /* RSA signature is done on smartcard */
728 if (!scx_establish_context(sc
) || !scx_login(sc
))
730 scx_release_context(sc
);
734 siglen
= scx_get_keylength(sc
);
738 plog("failed to get keylength from smartcard");
739 scx_release_context(sc
);
743 DBG(DBG_CONTROL
| DBG_CRYPT
,
744 DBG_log("signing hash with RSA key from smartcard (slot: %d, id: %s)"
745 , (int)sc
->slot
, sc
->id
)
748 pos
= build_asn1_object(&sigdata
, ASN1_BIT_STRING
, 1 + siglen
);
750 scx_sign_hash(sc
, digest
.ptr
, digest
.len
, pos
, siglen
);
751 if (!pkcs11_keep_state
)
752 scx_release_context(sc
);
756 /* RSA signature is done in software */
758 pos
= build_asn1_object(&sigdata
, ASN1_BIT_STRING
, 1 + siglen
);
760 sign_hash(pri
, digest
.ptr
, digest
.len
, pos
, siglen
);
766 * build signature into ocsp request
767 * gets built only if a request cert with
768 * a corresponding private key is found
771 build_signature(chunk_t tbsRequest
)
773 chunk_t sigdata
, certs
;
776 u_char digest_buf
[MAX_DIGEST_LEN
];
777 chunk_t digest_raw
= { digest_buf
, MAX_DIGEST_LEN
};
779 if (!compute_digest(tbsRequest
, OID_SHA1
, &digest_raw
))
782 /* according to PKCS#1 v2.1 digest must be packaged into
783 * an ASN.1 structure for encryption
785 digest_info
= asn1_wrap(ASN1_SEQUENCE
, "cm"
787 , asn1_simple_object(ASN1_OCTET_STRING
, digest_raw
));
789 /* generate the RSA signature */
790 sigdata
= generate_signature(digest_info
792 , ocsp_requestor_pri
);
793 freeanychunk(digest_info
);
795 /* has the RSA signature generation been successful? */
796 if (sigdata
.ptr
== NULL
)
799 /* include our certificate */
800 certs
= asn1_wrap(ASN1_CONTEXT_C_0
, "m"
801 , asn1_simple_object(ASN1_SEQUENCE
802 , ocsp_requestor_cert
->certificate
806 /* build signature comprising algorithm, signature and cert */
807 return asn1_wrap(ASN1_CONTEXT_C_0
, "m"
808 , asn1_wrap(ASN1_SEQUENCE
, "cmm"
809 , ASN1_sha1WithRSA_id
816 /* build request (into requestList)
817 * no singleRequestExtensions used
820 build_request(ocsp_location_t
*location
, ocsp_certinfo_t
*certinfo
)
822 chunk_t reqCert
= asn1_wrap(ASN1_SEQUENCE
, "cmmm"
824 , asn1_simple_object(ASN1_OCTET_STRING
, location
->authNameID
)
825 , asn1_simple_object(ASN1_OCTET_STRING
, location
->authKeyID
)
826 , asn1_simple_object(ASN1_INTEGER
, certinfo
->serialNumber
));
828 return asn1_wrap(ASN1_SEQUENCE
, "m", reqCert
);
832 * build requestList (into TBSRequest)
835 build_request_list(ocsp_location_t
*location
)
838 request_list_t
*reqs
= NULL
;
839 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
845 while (certinfo
!= NULL
)
847 /* build request for every certificate in list
848 * and store them in a chained list
850 request_list_t
*req
= alloc_thing(request_list_t
, "ocsp request");
852 req
->request
= build_request(location
, certinfo
);
856 datalen
+= req
->request
.len
;
857 certinfo
= certinfo
->next
;
860 pos
= build_asn1_object(&requestList
, ASN1_SEQUENCE
863 /* copy all in chained list, free list afterwards */
866 request_list_t
*req
= reqs
;
868 mv_chunk(&pos
, req
->request
);
877 * build requestorName (into TBSRequest)
880 build_requestor_name(void)
882 return asn1_wrap(ASN1_CONTEXT_C_1
, "m"
883 , asn1_simple_object(ASN1_CONTEXT_C_4
884 , ocsp_requestor_cert
->subject
));
888 * build nonce extension (into requestExtensions)
891 build_nonce_extension(ocsp_location_t
*location
)
893 /* generate a random nonce */
894 location
->nonce
.ptr
= alloc_bytes(NONCE_LENGTH
, "ocsp nonce"),
895 location
->nonce
.len
= NONCE_LENGTH
;
896 get_rnd_bytes(location
->nonce
.ptr
, NONCE_LENGTH
);
898 return asn1_wrap(ASN1_SEQUENCE
, "cm"
900 , asn1_simple_object(ASN1_OCTET_STRING
, location
->nonce
));
904 * build requestExtensions (into TBSRequest)
907 build_request_ext(ocsp_location_t
*location
)
909 return asn1_wrap(ASN1_CONTEXT_C_2
, "m"
910 , asn1_wrap(ASN1_SEQUENCE
, "mm"
911 , build_nonce_extension(location
)
912 , asn1_wrap(ASN1_SEQUENCE
, "cc"
914 , ASN1_response_content
921 * build TBSRequest (into OCSPRequest)
924 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
));
935 /* assembles an ocsp request to given location
936 * and sets nonce field in location to the sent nonce
939 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
979 valid_ocsp_response(response_t
*res
)
982 x509cert_t
*authcert
;
984 lock_authcert_list("valid_ocsp_response");
986 authcert
= get_authcert(res
->responder_id_name
, empty_chunk
987 , res
->responder_id_key
, AUTH_OCSP
| AUTH_CA
);
989 if (authcert
== NULL
)
991 plog("no matching ocsp signer cert found");
992 unlock_authcert_list("valid_ocsp_response");
996 DBG_log("ocsp signer cert found")
999 if (!check_signature(res
->tbs
, res
->signature
, res
->algorithm
1000 , res
->algorithm
, authcert
))
1002 plog("signature of ocsp response is invalid");
1003 unlock_authcert_list("valid_ocsp_response");
1007 DBG_log("signature of ocsp response is valid")
1011 for (pathlen
= 0; pathlen
< MAX_CA_PATH_LEN
; pathlen
++)
1013 u_char buf
[BUF_LEN
];
1017 x509cert_t
*cert
= authcert
;
1020 dntoa(buf
, BUF_LEN
, cert
->subject
);
1021 DBG_log("subject: '%s'",buf
);
1022 dntoa(buf
, BUF_LEN
, cert
->issuer
);
1023 DBG_log("issuer: '%s'",buf
);
1024 if (cert
->authKeyID
.ptr
!= NULL
)
1026 datatot(cert
->authKeyID
.ptr
, cert
->authKeyID
.len
, ':'
1028 DBG_log("authkey: %s", buf
);
1032 ugh
= check_validity(authcert
, &until
);
1037 unlock_authcert_list("valid_ocsp_response");
1042 DBG_log("certificate is valid")
1045 authcert
= get_authcert(cert
->issuer
, cert
->authKeySerialNumber
1046 , cert
->authKeyID
, AUTH_CA
);
1048 if (authcert
== NULL
)
1050 plog("issuer cacert not found");
1051 unlock_authcert_list("valid_ocsp_response");
1055 DBG_log("issuer cacert found")
1058 if (!check_signature(cert
->tbsCertificate
, cert
->signature
1059 , cert
->algorithm
, cert
->algorithm
, authcert
))
1061 plog("certificate signature is invalid");
1062 unlock_authcert_list("valid_ocsp_response");
1066 DBG_log("certificate signature is valid")
1069 /* check if cert is self-signed */
1070 if (same_dn(cert
->issuer
, cert
->subject
))
1073 DBG_log("reached self-signed root ca")
1075 unlock_authcert_list("valid_ocsp_response");
1079 plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN
);
1080 unlock_authcert_list("valid_ocsp_response");
1085 * parse a basic OCSP response
1088 parse_basic_ocsp_response(chunk_t blob
, int level0
, response_t
*res
)
1093 u_int level
, version
;
1094 u_char buf
[BUF_LEN
];
1096 int extn_oid
= OID_UNKNOWN
;
1098 asn1_init(&ctx
, blob
, level0
, FALSE
, DBG_RAW
);
1100 while (objectID
< BASIC_RESPONSE_ROOF
)
1102 if (!extract_object(basicResponseObjects
, &objectID
, &object
, &level
, &ctx
))
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
= asn1totime(&object
, ASN1_GENERALIZEDTIME
);
1131 case BASIC_RESPONSE_RESPONSES
:
1132 res
->responses
= object
;
1134 case BASIC_RESPONSE_EXT_ID
:
1135 extn_oid
= 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
= parse_algorithmIdentifier(object
, level
+1, NULL
);
1150 case BASIC_RESPONSE_SIGNATURE
:
1151 res
->signature
= object
;
1153 case BASIC_RESPONSE_CERTIFICATE
:
1156 x509cert_t
*cert
= alloc_thing(x509cert_t
, "ocspcert");
1158 clonetochunk(blob
, object
.ptr
, object
.len
, "ocspcert blob");
1159 *cert
= empty_x509cert
;
1161 if (parse_x509cert(blob
, level
+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
);
1184 * parse an ocsp response and return the result as a response_t struct
1186 static response_status
1187 parse_ocsp_response(chunk_t blob
, response_t
* res
)
1193 int ocspResponseType
= OID_UNKNOWN
;
1194 response_status rStatus
= STATUS_INTERNALERROR
;
1196 asn1_init(&ctx
, blob
, 0, FALSE
, DBG_RAW
);
1198 while (objectID
< OCSP_RESPONSE_ROOF
)
1200 if (!extract_object(ocspResponseObjects
, &objectID
, &object
, &level
, &ctx
))
1201 return STATUS_INTERNALERROR
;
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
]);
1220 return STATUS_INTERNALERROR
;
1223 case OCSP_RESPONSE_TYPE
:
1224 ocspResponseType
= known_oid(object
);
1228 switch (ocspResponseType
) {
1230 if (!parse_basic_ocsp_response(object
, level
+1, res
))
1231 return STATUS_INTERNALERROR
;
1235 DBG_log("ocsp response is not of type BASIC");
1236 DBG_dump_chunk("ocsp response OID: ", object
);
1238 return STATUS_INTERNALERROR
;
1249 * parse a basic OCSP response
1252 parse_ocsp_single_response(chunk_t blob
, int level0
, single_response_t
*sres
)
1254 u_int level
, extn_oid
;
1260 asn1_init(&ctx
, blob
, level0
, FALSE
, DBG_RAW
);
1262 while (objectID
< SINGLE_RESPONSE_ROOF
)
1264 if (!extract_object(singleResponseObjects
, &objectID
, &object
, &level
, &ctx
))
1269 case SINGLE_RESPONSE_ALGORITHM
:
1270 sres
->hash_algorithm
= parse_algorithmIdentifier(object
, level
+1, NULL
);
1272 case SINGLE_RESPONSE_ISSUER_NAME_HASH
:
1273 sres
->issuer_name_hash
= object
;
1275 case SINGLE_RESPONSE_ISSUER_KEY_HASH
:
1276 sres
->issuer_key_hash
= object
;
1278 case SINGLE_RESPONSE_SERIAL_NUMBER
:
1279 sres
->serialNumber
= object
;
1281 case SINGLE_RESPONSE_CERT_STATUS_GOOD
:
1282 sres
->status
= CERT_GOOD
;
1284 case SINGLE_RESPONSE_CERT_STATUS_REVOKED
:
1285 sres
->status
= CERT_REVOKED
;
1287 case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME
:
1288 sres
->revocationTime
= asn1totime(&object
, ASN1_GENERALIZEDTIME
);
1290 case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON
:
1291 sres
->revocationReason
= (object
.len
== 1)
1292 ?
*object
.ptr
: REASON_UNSPECIFIED
;
1294 case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN
:
1295 sres
->status
= CERT_UNKNOWN
;
1297 case SINGLE_RESPONSE_THIS_UPDATE
:
1298 sres
->thisUpdate
= asn1totime(&object
, ASN1_GENERALIZEDTIME
);
1300 case SINGLE_RESPONSE_NEXT_UPDATE
:
1301 sres
->nextUpdate
= asn1totime(&object
, ASN1_GENERALIZEDTIME
);
1303 case SINGLE_RESPONSE_EXT_ID
:
1304 extn_oid
= known_oid(object
);
1306 case SINGLE_RESPONSE_CRITICAL
:
1307 critical
= object
.len
&& *object
.ptr
;
1309 DBG_log(" %s",(critical
)?
"TRUE":"FALSE");
1311 case SINGLE_RESPONSE_EXT_VALUE
:
1320 * add an ocsp location to a chained list
1323 add_ocsp_location(const ocsp_location_t
*loc
, ocsp_location_t
**chain
)
1325 ocsp_location_t
*location
= alloc_thing(ocsp_location_t
, "ocsp location");
1327 /* unshare location fields */
1328 clonetochunk(location
->issuer
1329 , loc
->issuer
.ptr
, loc
->issuer
.len
1332 clonetochunk(location
->authNameID
1333 , loc
->authNameID
.ptr
, loc
->authNameID
.len
1334 , "ocsp authNameID");
1336 if (loc
->authKeyID
.ptr
== NULL
)
1337 location
->authKeyID
= empty_chunk
;
1339 clonetochunk(location
->authKeyID
1340 , loc
->authKeyID
.ptr
, loc
->authKeyID
.len
1341 , "ocsp authKeyID");
1343 if (loc
->authKeySerialNumber
.ptr
== NULL
)
1344 location
->authKeySerialNumber
= empty_chunk
;
1346 clonetochunk(location
->authKeySerialNumber
1347 , loc
->authKeySerialNumber
.ptr
, loc
->authKeySerialNumber
.len
1348 , "ocsp authKeySerialNumber");
1350 clonetochunk(location
->uri
1351 , loc
->uri
.ptr
, loc
->uri
.len
1354 location
->certinfo
= NULL
;
1356 /* insert new ocsp location in front of chain */
1357 location
->next
= *chain
;
1361 DBG_log("new ocsp location added")
1368 * add a certinfo struct to a chained list
1371 add_certinfo(ocsp_location_t
*loc
, ocsp_certinfo_t
*info
, ocsp_location_t
**chain
1374 ocsp_location_t
*location
;
1375 ocsp_certinfo_t
*certinfo
, **certinfop
;
1380 location
= get_ocsp_location(loc
, *chain
);
1381 if (location
== NULL
)
1382 location
= add_ocsp_location(loc
, chain
);
1384 /* traverse list of certinfos in increasing order */
1385 certinfop
= &location
->certinfo
;
1386 certinfo
= *certinfop
;
1388 while (certinfo
!= NULL
)
1390 cmp
= cmp_chunk(info
->serialNumber
, certinfo
->serialNumber
);
1393 certinfop
= &certinfo
->next
;
1394 certinfo
= *certinfop
;
1399 /* add a new certinfo entry */
1400 ocsp_certinfo_t
*cnew
= alloc_thing(ocsp_certinfo_t
, "ocsp certinfo");
1401 clonetochunk(cnew
->serialNumber
, info
->serialNumber
.ptr
1402 , info
->serialNumber
.len
, "serialNumber");
1403 cnew
->next
= certinfo
;
1409 datatot(info
->serialNumber
.ptr
, info
->serialNumber
.len
, ':'
1411 DBG_log("ocsp %s for serial %s %s"
1412 , request?
"fetch request":"certinfo"
1414 , (cmp
== 0)?
(request?
"already exists":"updated"):"added")
1421 certinfo
->status
= CERT_UNDEFINED
;
1424 certinfo
->thisUpdate
= now
;
1426 certinfo
->nextUpdate
= UNDEFINED_TIME
;
1430 certinfo
->status
= info
->status
;
1431 certinfo
->revocationTime
= info
->revocationTime
;
1432 certinfo
->revocationReason
= info
->revocationReason
;
1434 certinfo
->thisUpdate
= (info
->thisUpdate
!= UNDEFINED_TIME
)?
1435 info
->thisUpdate
: now
;
1437 certinfo
->once
= (info
->nextUpdate
== UNDEFINED_TIME
);
1439 certinfo
->nextUpdate
= (certinfo
->once
)?
1440 (now
+ OCSP_DEFAULT_VALID_TIME
) : info
->nextUpdate
;
1445 * process received ocsp single response and add it to ocsp cache
1448 process_single_response(ocsp_location_t
*location
, single_response_t
*sres
)
1450 ocsp_certinfo_t
*certinfo
, **certinfop
;
1453 if (sres
->hash_algorithm
!= OID_SHA1
)
1455 plog("only SHA-1 hash supported in OCSP single response");
1458 if (!(same_chunk(sres
->issuer_name_hash
, location
->authNameID
)
1459 && same_chunk(sres
->issuer_key_hash
, location
->authKeyID
)))
1461 plog("ocsp single response has wrong issuer");
1465 /* traverse list of certinfos in increasing order */
1466 certinfop
= &location
->certinfo
;
1467 certinfo
= *certinfop
;
1469 while (certinfo
!= NULL
)
1471 cmp
= cmp_chunk(sres
->serialNumber
, certinfo
->serialNumber
);
1474 certinfop
= &certinfo
->next
;
1475 certinfo
= *certinfop
;
1480 plog("received unrequested cert status from ocsp server");
1484 /* unlink cert from ocsp fetch request list */
1485 *certinfop
= certinfo
->next
;
1487 /* update certinfo using the single response information */
1488 certinfo
->thisUpdate
= sres
->thisUpdate
;
1489 certinfo
->nextUpdate
= sres
->nextUpdate
;
1490 certinfo
->status
= sres
->status
;
1491 certinfo
->revocationTime
= sres
->revocationTime
;
1492 certinfo
->revocationReason
= sres
->revocationReason
;
1494 /* add or update certinfo in ocsp cache */
1495 lock_ocsp_cache("process_single_response");
1496 add_certinfo(location
, certinfo
, &ocsp_cache
, FALSE
);
1497 unlock_ocsp_cache("process_single_response");
1499 /* free certinfo unlinked from ocsp fetch request list */
1500 free_certinfo(certinfo
);
1505 * parse and verify ocsp response and update the ocsp cache
1508 parse_ocsp(ocsp_location_t
*location
, chunk_t blob
)
1510 response_t res
= empty_response
;
1512 /* parse the ocsp response without looking at the single responses yet */
1513 response_status status
= parse_ocsp_response(blob
, &res
);
1515 if (status
!= STATUS_SUCCESSFUL
)
1517 plog("error in ocsp response");
1520 /* check if there was a nonce in the request */
1521 if (location
->nonce
.ptr
!= NULL
&& res
.nonce
.ptr
== NULL
)
1523 plog("ocsp response contains no nonce, replay attack possible");
1525 /* check if the nonce is identical */
1526 if (res
.nonce
.ptr
!= NULL
&& !same_chunk(res
.nonce
, location
->nonce
))
1528 plog("invalid nonce in ocsp response");
1531 /* check if the response is signed by a trusted key */
1532 if (!valid_ocsp_response(&res
))
1534 plog("invalid ocsp response");
1538 DBG_log("valid ocsp response")
1541 /* now parse the single responses one at a time */
1548 asn1_init(&ctx
, res
.responses
, 0, FALSE
, DBG_RAW
);
1550 while (objectID
< RESPONSES_ROOF
)
1552 if (!extract_object(responsesObjects
, &objectID
, &object
, &level
, &ctx
))
1555 if (objectID
== RESPONSES_SINGLE_RESPONSE
)
1557 single_response_t sres
= empty_single_response
;
1559 if (parse_ocsp_single_response(object
, level
+1, &sres
))
1561 process_single_response(location
, &sres
);