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
22 #include <sys/types.h>
27 #include <ipsec_policy.h>
29 #include "constants.h"
38 #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
= strchunk(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
= strchunk(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
= strchunk(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 const struct RSA_private_key
*ocsp_requestor_pri
= NULL
;
163 /* asn.1 definitions for parsing */
165 static const asn1Object_t ocspResponseObjects
[] = {
166 { 0, "OCSPResponse", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
167 { 1, "responseStatus", ASN1_ENUMERATED
, ASN1_BODY
}, /* 1 */
168 { 1, "responseBytesContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 2 */
169 { 2, "responseBytes", ASN1_SEQUENCE
, ASN1_NONE
}, /* 3 */
170 { 3, "responseType", ASN1_OID
, ASN1_BODY
}, /* 4 */
171 { 3, "response", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 5 */
172 { 1, "end opt", ASN1_EOC
, ASN1_END
} /* 6 */
175 #define OCSP_RESPONSE_STATUS 1
176 #define OCSP_RESPONSE_TYPE 4
177 #define OCSP_RESPONSE 5
178 #define OCSP_RESPONSE_ROOF 7
180 static const asn1Object_t basicResponseObjects
[] = {
181 { 0, "BasicOCSPResponse", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
182 { 1, "tbsResponseData", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 1 */
183 { 2, "versionContext", ASN1_CONTEXT_C_0
, ASN1_NONE
|
185 { 3, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
186 { 2, "responderIdContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 4 */
187 { 3, "responderIdByName", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 5 */
188 { 2, "end choice", ASN1_EOC
, ASN1_END
}, /* 6 */
189 { 2, "responderIdContext", ASN1_CONTEXT_C_2
, ASN1_OPT
}, /* 7 */
190 { 3, "responderIdByKey", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 8 */
191 { 2, "end choice", ASN1_EOC
, ASN1_END
}, /* 9 */
192 { 2, "producedAt", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 10 */
193 { 2, "responses", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 11 */
194 { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 12 */
195 { 3, "responseExtensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 13 */
196 { 4, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 14 */
197 { 5, "extnID", ASN1_OID
, ASN1_BODY
}, /* 15 */
198 { 5, "critical", ASN1_BOOLEAN
, ASN1_BODY
|
200 { 5, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 17 */
201 { 4, "end loop", ASN1_EOC
, ASN1_END
}, /* 18 */
202 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 19 */
203 { 1, "signatureAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 20 */
204 { 1, "signature", ASN1_BIT_STRING
, ASN1_BODY
}, /* 21 */
205 { 1, "certsContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 22 */
206 { 2, "certs", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 23 */
207 { 3, "certificate", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 24 */
208 { 2, "end loop", ASN1_EOC
, ASN1_END
}, /* 25 */
209 { 1, "end opt", ASN1_EOC
, ASN1_END
} /* 26 */
212 #define BASIC_RESPONSE_TBS_DATA 1
213 #define BASIC_RESPONSE_VERSION 3
214 #define BASIC_RESPONSE_ID_BY_NAME 5
215 #define BASIC_RESPONSE_ID_BY_KEY 8
216 #define BASIC_RESPONSE_PRODUCED_AT 10
217 #define BASIC_RESPONSE_RESPONSES 11
218 #define BASIC_RESPONSE_EXT_ID 15
219 #define BASIC_RESPONSE_CRITICAL 16
220 #define BASIC_RESPONSE_EXT_VALUE 17
221 #define BASIC_RESPONSE_ALGORITHM 20
222 #define BASIC_RESPONSE_SIGNATURE 21
223 #define BASIC_RESPONSE_CERTIFICATE 24
224 #define BASIC_RESPONSE_ROOF 27
226 static const asn1Object_t responsesObjects
[] = {
227 { 0, "responses", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
228 { 1, "singleResponse", ASN1_EOC
, ASN1_RAW
}, /* 1 */
229 { 0, "end loop", ASN1_EOC
, ASN1_END
} /* 2 */
232 #define RESPONSES_SINGLE_RESPONSE 1
233 #define RESPONSES_ROOF 3
235 static const asn1Object_t singleResponseObjects
[] = {
236 { 0, "singleResponse", ASN1_SEQUENCE
, ASN1_BODY
}, /* 0 */
237 { 1, "certID", ASN1_SEQUENCE
, ASN1_NONE
}, /* 1 */
238 { 2, "algorithm", ASN1_EOC
, ASN1_RAW
}, /* 2 */
239 { 2, "issuerNameHash", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 3 */
240 { 2, "issuerKeyHash", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 4 */
241 { 2, "serialNumber", ASN1_INTEGER
, ASN1_BODY
}, /* 5 */
242 { 1, "certStatusGood", ASN1_CONTEXT_S_0
, ASN1_OPT
}, /* 6 */
243 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 7 */
244 { 1, "certStatusRevoked", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 8 */
245 { 2, "revocationTime", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 9 */
246 { 2, "revocationReason", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 10 */
247 { 3, "crlReason", ASN1_ENUMERATED
, ASN1_BODY
}, /* 11 */
248 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 12 */
249 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 13 */
250 { 1, "certStatusUnknown", ASN1_CONTEXT_S_2
, ASN1_OPT
}, /* 14 */
251 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 15 */
252 { 1, "thisUpdate", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 16 */
253 { 1, "nextUpdateContext", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 17 */
254 { 2, "nextUpdate", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 18 */
255 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 19 */
256 { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 20 */
257 { 2, "singleExtensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 21 */
258 { 3, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 22 */
259 { 4, "extnID", ASN1_OID
, ASN1_BODY
}, /* 23 */
260 { 4, "critical", ASN1_BOOLEAN
, ASN1_BODY
|
262 { 4, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 25 */
263 { 2, "end loop", ASN1_EOC
, ASN1_END
}, /* 26 */
264 { 1, "end opt", ASN1_EOC
, ASN1_END
} /* 27 */
267 #define SINGLE_RESPONSE_ALGORITHM 2
268 #define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
269 #define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
270 #define SINGLE_RESPONSE_SERIAL_NUMBER 5
271 #define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
272 #define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
273 #define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
274 #define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
275 #define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
276 #define SINGLE_RESPONSE_THIS_UPDATE 16
277 #define SINGLE_RESPONSE_NEXT_UPDATE 18
278 #define SINGLE_RESPONSE_EXT_ID 23
279 #define SINGLE_RESPONSE_CRITICAL 24
280 #define SINGLE_RESPONSE_EXT_VALUE 25
281 #define SINGLE_RESPONSE_ROOF 28
283 /* build an ocsp location from certificate information
284 * without unsharing its contents
287 build_ocsp_location(const x509cert_t
*cert
, ocsp_location_t
*location
)
289 static u_char digest
[SHA1_DIGEST_SIZE
]; /* temporary storage */
291 location
->uri
= cert
->accessLocation
;
293 if (location
->uri
.ptr
== NULL
)
295 ca_info_t
*ca
= get_ca_info(cert
->issuer
, cert
->authKeySerialNumber
297 if (ca
!= NULL
&& ca
->ocspuri
!= NULL
)
298 setchunk(location
->uri
, ca
->ocspuri
, strlen(ca
->ocspuri
))
300 /* abort if no ocsp location uri is defined */
304 setchunk(location
->authNameID
, digest
, SHA1_DIGEST_SIZE
);
305 compute_digest(cert
->issuer
, OID_SHA1
, &location
->authNameID
);
307 location
->next
= NULL
;
308 location
->issuer
= cert
->issuer
;
309 location
->authKeyID
= cert
->authKeyID
;
310 location
->authKeySerialNumber
= cert
->authKeySerialNumber
;
312 if (cert
->authKeyID
.ptr
== NULL
)
314 x509cert_t
*authcert
= get_authcert(cert
->issuer
315 , cert
->authKeySerialNumber
, cert
->authKeyID
, AUTH_CA
);
317 if (authcert
!= NULL
)
319 location
->authKeyID
= authcert
->subjectKeyID
;
320 location
->authKeySerialNumber
= authcert
->serialNumber
;
324 location
->nonce
= empty_chunk
;
325 location
->certinfo
= NULL
;
331 * compare two ocsp locations for equality
334 same_ocsp_location(const ocsp_location_t
*a
, const ocsp_location_t
*b
)
336 return ((a
->authKeyID
.ptr
!= NULL
)
337 ?
same_keyid(a
->authKeyID
, b
->authKeyID
)
338 : (same_dn(a
->issuer
, b
->issuer
)
339 && same_serial(a
->authKeySerialNumber
, b
->authKeySerialNumber
)))
340 && same_chunk(a
->uri
, b
->uri
);
344 * find an existing ocsp location in a chained list
347 get_ocsp_location(const ocsp_location_t
* loc
, ocsp_location_t
*chain
)
350 while (chain
!= NULL
)
352 if (same_ocsp_location(loc
, chain
))
359 /* retrieves the status of a cert from the ocsp cache
360 * returns CERT_UNDEFINED if no status is found
363 get_ocsp_status(const ocsp_location_t
*loc
, chunk_t serialNumber
364 ,time_t *nextUpdate
, time_t *revocationTime
, crl_reason_t
*revocationReason
)
366 ocsp_certinfo_t
*certinfo
, **certinfop
;
370 ocsp_location_t
*location
= get_ocsp_location(loc
, ocsp_cache
);
372 if (location
== NULL
)
373 return CERT_UNDEFINED
;
375 /* traverse list of certinfos in increasing order */
376 certinfop
= &location
->certinfo
;
377 certinfo
= *certinfop
;
379 while (certinfo
!= NULL
)
381 cmp
= cmp_chunk(serialNumber
, certinfo
->serialNumber
);
384 certinfop
= &certinfo
->next
;
385 certinfo
= *certinfop
;
390 *nextUpdate
= certinfo
->nextUpdate
;
391 *revocationTime
= certinfo
->revocationTime
;
392 *revocationReason
= certinfo
->revocationReason
;
393 return certinfo
->status
;
396 return CERT_UNDEFINED
;
400 * verify the ocsp status of a certificate
403 verify_by_ocsp(const x509cert_t
*cert
, time_t *until
404 , time_t *revocationDate
, crl_reason_t
*revocationReason
)
406 cert_status_t status
;
407 ocsp_location_t location
;
408 time_t nextUpdate
= 0;
410 *revocationDate
= UNDEFINED_TIME
;
411 *revocationReason
= REASON_UNSPECIFIED
;
413 /* is an ocsp location defined? */
414 if (!build_ocsp_location(cert
, &location
))
415 return CERT_UNDEFINED
;
417 lock_ocsp_cache("verify_by_ocsp");
418 status
= get_ocsp_status(&location
, cert
->serialNumber
, &nextUpdate
419 , revocationDate
, revocationReason
);
420 unlock_ocsp_cache("verify_by_ocsp");
422 if (status
== CERT_UNDEFINED
|| nextUpdate
< time(NULL
))
424 plog("ocsp status is stale or not in cache");
425 add_ocsp_fetch_request(&location
, cert
->serialNumber
);
427 /* inititate fetching of ocsp status */
428 wake_fetch_thread("verify_by_ocsp");
435 * check if an ocsp status is about to expire
440 ocsp_location_t
*location
;
442 lock_ocsp_cache("check_ocsp");
443 location
= ocsp_cache
;
445 while (location
!= NULL
)
449 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
451 while (certinfo
!= NULL
)
455 time_t time_left
= certinfo
->nextUpdate
- time(NULL
);
460 dntoa(buf
, BUF_LEN
, location
->issuer
);
461 DBG_log("issuer: '%s'", buf
);
462 if (location
->authKeyID
.ptr
!= NULL
)
464 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
465 , ':', buf
, BUF_LEN
);
466 DBG_log("authkey: %s", buf
);
470 datatot(certinfo
->serialNumber
.ptr
, certinfo
->serialNumber
.len
471 , ':', buf
, BUF_LEN
);
472 DBG_log("serial: %s, %ld seconds left", buf
, time_left
)
475 if (time_left
< 2*crl_check_interval
)
476 add_ocsp_fetch_request(location
, certinfo
->serialNumber
);
478 certinfo
= certinfo
->next
;
480 location
= location
->next
;
482 unlock_ocsp_cache("check_ocsp");
486 * frees the allocated memory of a certinfo struct
489 free_certinfo(ocsp_certinfo_t
*certinfo
)
491 freeanychunk(certinfo
->serialNumber
);
496 * frees all certinfos in a chained list
499 free_certinfos(ocsp_certinfo_t
*chain
)
501 ocsp_certinfo_t
*certinfo
;
503 while (chain
!= NULL
)
507 free_certinfo(certinfo
);
512 * frees the memory allocated to an ocsp location including all certinfos
515 free_ocsp_location(ocsp_location_t
* location
)
517 freeanychunk(location
->issuer
);
518 freeanychunk(location
->authNameID
);
519 freeanychunk(location
->authKeyID
);
520 freeanychunk(location
->authKeySerialNumber
);
521 freeanychunk(location
->uri
);
522 free_certinfos(location
->certinfo
);
527 * free a chained list of ocsp locations
530 free_ocsp_locations(ocsp_location_t
**chain
)
532 while (*chain
!= NULL
)
534 ocsp_location_t
*location
= *chain
;
535 *chain
= location
->next
;
536 free_ocsp_location(location
);
541 * free the ocsp cache
544 free_ocsp_cache(void)
546 lock_ocsp_cache("free_ocsp_cache");
547 free_ocsp_locations(&ocsp_cache
);
548 unlock_ocsp_cache("free_ocsp_cache");
552 * frees the ocsp cache and global variables
557 free(ocsp_default_uri
.ptr
);
562 * list a chained list of ocsp_locations
565 list_ocsp_locations(ocsp_location_t
*location
, bool requests
, bool utc
570 while (location
!= NULL
)
572 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
574 if (certinfo
!= NULL
)
580 whack_log(RC_COMMENT
, " ");
581 whack_log(RC_COMMENT
, "List of OCSP %s:", requests?
582 "fetch requests":"responses");
585 whack_log(RC_COMMENT
, " ");
586 if (location
->issuer
.ptr
!= NULL
)
588 dntoa(buf
, BUF_LEN
, location
->issuer
);
589 whack_log(RC_COMMENT
, " issuer: '%s'", buf
);
591 whack_log(RC_COMMENT
, " uri: '%.*s'", (int)location
->uri
.len
592 , location
->uri
.ptr
);
593 if (location
->authNameID
.ptr
!= NULL
)
595 datatot(location
->authNameID
.ptr
, location
->authNameID
.len
, ':'
597 whack_log(RC_COMMENT
, " authname: %s", buf
);
599 if (location
->authKeyID
.ptr
!= NULL
)
601 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
, ':'
603 whack_log(RC_COMMENT
, " authkey: %s", buf
);
605 if (location
->authKeySerialNumber
.ptr
!= NULL
)
607 datatot(location
->authKeySerialNumber
.ptr
608 , location
->authKeySerialNumber
.len
, ':', buf
, BUF_LEN
);
609 whack_log(RC_COMMENT
, " aserial: %s", buf
);
611 while (certinfo
!= NULL
)
613 char thisUpdate
[TIMETOA_BUF
];
615 strcpy(thisUpdate
, timetoa(&certinfo
->thisUpdate
, utc
));
619 whack_log(RC_COMMENT
, "%s, trials: %d", thisUpdate
622 else if (certinfo
->once
)
624 whack_log(RC_COMMENT
, "%s, onetime use%s", thisUpdate
625 , (certinfo
->nextUpdate
< time(NULL
))?
" (expired)": "");
629 whack_log(RC_COMMENT
, "%s, until %s %s", thisUpdate
630 , timetoa(&certinfo
->nextUpdate
, utc
)
631 , check_expiry(certinfo
->nextUpdate
, OCSP_WARNING_INTERVAL
, strict
));
633 datatot(certinfo
->serialNumber
.ptr
, certinfo
->serialNumber
.len
, ':'
635 whack_log(RC_COMMENT
, " serial: %s, %s", buf
636 , cert_status_names
[certinfo
->status
]);
637 certinfo
= certinfo
->next
;
640 location
= location
->next
;
645 * list the ocsp cache
648 list_ocsp_cache(bool utc
, bool strict
)
650 lock_ocsp_cache("list_ocsp_cache");
651 list_ocsp_locations(ocsp_cache
, FALSE
, utc
, strict
);
652 unlock_ocsp_cache("list_ocsp_cache");
656 get_ocsp_requestor_cert(ocsp_location_t
*location
)
658 x509cert_t
*cert
= NULL
;
660 /* initialize temporary static storage */
661 ocsp_requestor_cert
= NULL
;
662 ocsp_requestor_sc
= NULL
;
663 ocsp_requestor_pri
= NULL
;
669 /* looking for a certificate from the same issuer */
670 cert
= get_x509cert(location
->issuer
, location
->authKeySerialNumber
671 ,location
->authKeyID
, cert
);
676 dntoa(buf
, BUF_LEN
, cert
->subject
);
677 DBG_log("candidate: '%s'", buf
);
682 /* look for a matching private key on a smartcard */
683 smartcard_t
*sc
= scx_get(cert
);
688 DBG_log("matching smartcard found")
692 ocsp_requestor_cert
= cert
;
693 ocsp_requestor_sc
= sc
;
696 plog("unable to sign ocsp request without PIN");
701 /* look for a matching private key in the chained list */
702 const struct RSA_private_key
*pri
= get_x509_private_key(cert
);
707 DBG_log("matching private key found")
709 ocsp_requestor_cert
= cert
;
710 ocsp_requestor_pri
= pri
;
719 generate_signature(chunk_t digest
, smartcard_t
*sc
720 , const RSA_private_key_t
*pri
)
728 /* RSA signature is done on smartcard */
730 if (!scx_establish_context(sc
) || !scx_login(sc
))
732 scx_release_context(sc
);
736 siglen
= scx_get_keylength(sc
);
740 plog("failed to get keylength from smartcard");
741 scx_release_context(sc
);
745 DBG(DBG_CONTROL
| DBG_CRYPT
,
746 DBG_log("signing hash with RSA key from smartcard (slot: %d, id: %s)"
747 , (int)sc
->slot
, sc
->id
)
750 pos
= build_asn1_object(&sigdata
, ASN1_BIT_STRING
, 1 + siglen
);
752 scx_sign_hash(sc
, digest
.ptr
, digest
.len
, pos
, siglen
);
753 if (!pkcs11_keep_state
)
754 scx_release_context(sc
);
758 /* RSA signature is done in software */
760 pos
= build_asn1_object(&sigdata
, ASN1_BIT_STRING
, 1 + siglen
);
762 sign_hash(pri
, digest
.ptr
, digest
.len
, pos
, siglen
);
768 * build signature into ocsp request
769 * gets built only if a request cert with
770 * a corresponding private key is found
773 build_signature(chunk_t tbsRequest
)
775 chunk_t sigdata
, certs
;
778 u_char digest_buf
[MAX_DIGEST_LEN
];
779 chunk_t digest_raw
= { digest_buf
, MAX_DIGEST_LEN
};
781 if (!compute_digest(tbsRequest
, OID_SHA1
, &digest_raw
))
784 /* according to PKCS#1 v2.1 digest must be packaged into
785 * an ASN.1 structure for encryption
787 digest_info
= asn1_wrap(ASN1_SEQUENCE
, "cm"
789 , asn1_simple_object(ASN1_OCTET_STRING
, digest_raw
));
791 /* generate the RSA signature */
792 sigdata
= generate_signature(digest_info
794 , ocsp_requestor_pri
);
795 freeanychunk(digest_info
);
797 /* has the RSA signature generation been successful? */
798 if (sigdata
.ptr
== NULL
)
801 /* include our certificate */
802 certs
= asn1_wrap(ASN1_CONTEXT_C_0
, "m"
803 , asn1_simple_object(ASN1_SEQUENCE
804 , ocsp_requestor_cert
->certificate
808 /* build signature comprising algorithm, signature and cert */
809 return asn1_wrap(ASN1_CONTEXT_C_0
, "m"
810 , asn1_wrap(ASN1_SEQUENCE
, "cmm"
811 , ASN1_sha1WithRSA_id
818 /* build request (into requestList)
819 * no singleRequestExtensions used
822 build_request(ocsp_location_t
*location
, ocsp_certinfo_t
*certinfo
)
824 chunk_t reqCert
= asn1_wrap(ASN1_SEQUENCE
, "cmmm"
826 , asn1_simple_object(ASN1_OCTET_STRING
, location
->authNameID
)
827 , asn1_simple_object(ASN1_OCTET_STRING
, location
->authKeyID
)
828 , asn1_simple_object(ASN1_INTEGER
, certinfo
->serialNumber
));
830 return asn1_wrap(ASN1_SEQUENCE
, "m", reqCert
);
834 * build requestList (into TBSRequest)
837 build_request_list(ocsp_location_t
*location
)
840 request_list_t
*reqs
= NULL
;
841 ocsp_certinfo_t
*certinfo
= location
->certinfo
;
847 while (certinfo
!= NULL
)
849 /* build request for every certificate in list
850 * and store them in a chained list
852 request_list_t
*req
= malloc_thing(request_list_t
);
854 req
->request
= build_request(location
, certinfo
);
858 datalen
+= req
->request
.len
;
859 certinfo
= certinfo
->next
;
862 pos
= build_asn1_object(&requestList
, ASN1_SEQUENCE
865 /* copy all in chained list, free list afterwards */
868 request_list_t
*req
= reqs
;
870 mv_chunk(&pos
, req
->request
);
879 * build requestorName (into TBSRequest)
882 build_requestor_name(void)
884 return asn1_wrap(ASN1_CONTEXT_C_1
, "m"
885 , asn1_simple_object(ASN1_CONTEXT_C_4
886 , ocsp_requestor_cert
->subject
));
890 * build nonce extension (into requestExtensions)
893 build_nonce_extension(ocsp_location_t
*location
)
895 /* generate a random nonce */
896 location
->nonce
.ptr
= malloc(NONCE_LENGTH
),
897 location
->nonce
.len
= NONCE_LENGTH
;
898 get_rnd_bytes(location
->nonce
.ptr
, NONCE_LENGTH
);
900 return asn1_wrap(ASN1_SEQUENCE
, "cm"
902 , asn1_simple_object(ASN1_OCTET_STRING
, location
->nonce
));
906 * build requestExtensions (into TBSRequest)
909 build_request_ext(ocsp_location_t
*location
)
911 return asn1_wrap(ASN1_CONTEXT_C_2
, "m"
912 , asn1_wrap(ASN1_SEQUENCE
, "mm"
913 , build_nonce_extension(location
)
914 , asn1_wrap(ASN1_SEQUENCE
, "cc"
916 , ASN1_response_content
923 * build TBSRequest (into OCSPRequest)
926 build_tbs_request(ocsp_location_t
*location
, bool has_requestor_cert
)
928 /* version is skipped since the default is ok */
929 return asn1_wrap(ASN1_SEQUENCE
, "mmm"
930 , (has_requestor_cert
)
931 ?
build_requestor_name()
933 , build_request_list(location
)
934 , build_request_ext(location
));
937 /* assembles an ocsp request to given location
938 * and sets nonce field in location to the sent nonce
941 build_ocsp_request(ocsp_location_t
*location
)
943 bool has_requestor_cert
;
944 chunk_t tbsRequest
, signature
;
948 DBG_log("assembling ocsp request");
949 dntoa(buf
, BUF_LEN
, location
->issuer
);
950 DBG_log("issuer: '%s'", buf
);
951 if (location
->authKeyID
.ptr
!= NULL
)
953 datatot(location
->authKeyID
.ptr
, location
->authKeyID
.len
, ':'
955 DBG_log("authkey: %s", buf
);
958 lock_certs_and_keys("build_ocsp_request");
960 /* looks for requestor cert and matching private key */
961 has_requestor_cert
= get_ocsp_requestor_cert(location
);
964 tbsRequest
= build_tbs_request(location
, has_requestor_cert
);
966 /* sign tbsReuqest */
967 signature
= (has_requestor_cert
)?
build_signature(tbsRequest
)
970 unlock_certs_and_keys("build_ocsp_request");
972 return asn1_wrap(ASN1_SEQUENCE
, "mm"
978 * check if the OCSP response has a valid signature
981 valid_ocsp_response(response_t
*res
)
984 x509cert_t
*authcert
;
986 lock_authcert_list("valid_ocsp_response");
988 authcert
= get_authcert(res
->responder_id_name
, empty_chunk
989 , res
->responder_id_key
, AUTH_OCSP
| AUTH_CA
);
991 if (authcert
== NULL
)
993 plog("no matching ocsp signer cert found");
994 unlock_authcert_list("valid_ocsp_response");
998 DBG_log("ocsp signer cert found")
1001 if (!check_signature(res
->tbs
, res
->signature
, res
->algorithm
1002 , 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 (!check_signature(cert
->tbsCertificate
, cert
->signature
1061 , cert
->algorithm
, 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
1090 parse_basic_ocsp_response(chunk_t blob
, int level0
, response_t
*res
)
1095 u_int level
, version
;
1096 u_char buf
[BUF_LEN
];
1098 int extn_oid
= OID_UNKNOWN
;
1100 asn1_init(&ctx
, blob
, level0
, FALSE
, DBG_RAW
);
1102 while (objectID
< BASIC_RESPONSE_ROOF
)
1104 if (!extract_object(basicResponseObjects
, &objectID
, &object
, &level
, &ctx
))
1109 case BASIC_RESPONSE_TBS_DATA
:
1112 case BASIC_RESPONSE_VERSION
:
1113 version
= (object
.len
)?
(1 + (u_int
)*object
.ptr
) : 1;
1114 if (version
!= OCSP_BASIC_RESPONSE_VERSION
)
1116 plog("wrong ocsp basic response version (version= %i)", version
);
1120 case BASIC_RESPONSE_ID_BY_NAME
:
1121 res
->responder_id_name
= object
;
1123 dntoa(buf
, BUF_LEN
, object
);
1124 DBG_log(" '%s'",buf
)
1127 case BASIC_RESPONSE_ID_BY_KEY
:
1128 res
->responder_id_key
= object
;
1130 case BASIC_RESPONSE_PRODUCED_AT
:
1131 res
->produced_at
= asn1totime(&object
, ASN1_GENERALIZEDTIME
);
1133 case BASIC_RESPONSE_RESPONSES
:
1134 res
->responses
= object
;
1136 case BASIC_RESPONSE_EXT_ID
:
1137 extn_oid
= asn1_known_oid(object
);
1139 case BASIC_RESPONSE_CRITICAL
:
1140 critical
= object
.len
&& *object
.ptr
;
1142 DBG_log(" %s",(critical
)?
"TRUE":"FALSE");
1145 case BASIC_RESPONSE_EXT_VALUE
:
1146 if (extn_oid
== OID_NONCE
)
1147 res
->nonce
= object
;
1149 case BASIC_RESPONSE_ALGORITHM
:
1150 res
->algorithm
= parse_algorithmIdentifier(object
, level
+1, NULL
);
1152 case BASIC_RESPONSE_SIGNATURE
:
1153 res
->signature
= object
;
1155 case BASIC_RESPONSE_CERTIFICATE
:
1158 x509cert_t
*cert
= malloc_thing(x509cert_t
);
1160 clonetochunk(blob
, object
.ptr
, object
.len
);
1161 *cert
= empty_x509cert
;
1163 if (parse_x509cert(blob
, level
+1, cert
)
1164 && cert
->isOcspSigner
1165 && trust_authcert_candidate(cert
, NULL
))
1167 add_authcert(cert
, AUTH_OCSP
);
1171 DBG(DBG_CONTROL
| DBG_PARSING
,
1172 DBG_log("embedded ocsp certificate rejected")
1174 free_x509cert(cert
);
1186 * parse an ocsp response and return the result as a response_t struct
1188 static response_status
1189 parse_ocsp_response(chunk_t blob
, response_t
* res
)
1195 int ocspResponseType
= OID_UNKNOWN
;
1196 response_status rStatus
= STATUS_INTERNALERROR
;
1198 asn1_init(&ctx
, blob
, 0, FALSE
, DBG_RAW
);
1200 while (objectID
< OCSP_RESPONSE_ROOF
)
1202 if (!extract_object(ocspResponseObjects
, &objectID
, &object
, &level
, &ctx
))
1203 return STATUS_INTERNALERROR
;
1206 case OCSP_RESPONSE_STATUS
:
1207 rStatus
= (response_status
) *object
.ptr
;
1211 case STATUS_SUCCESSFUL
:
1213 case STATUS_MALFORMEDREQUEST
:
1214 case STATUS_INTERNALERROR
:
1215 case STATUS_TRYLATER
:
1216 case STATUS_SIGREQUIRED
:
1217 case STATUS_UNAUTHORIZED
:
1218 plog("ocsp response: server said '%s'"
1219 , response_status_names
[rStatus
]);
1222 return STATUS_INTERNALERROR
;
1225 case OCSP_RESPONSE_TYPE
:
1226 ocspResponseType
= asn1_known_oid(object
);
1230 switch (ocspResponseType
) {
1232 if (!parse_basic_ocsp_response(object
, level
+1, res
))
1233 return STATUS_INTERNALERROR
;
1237 DBG_log("ocsp response is not of type BASIC");
1238 DBG_dump_chunk("ocsp response OID: ", object
);
1240 return STATUS_INTERNALERROR
;
1251 * parse a basic OCSP response
1254 parse_ocsp_single_response(chunk_t blob
, int level0
, single_response_t
*sres
)
1256 u_int level
, extn_oid
;
1262 asn1_init(&ctx
, blob
, level0
, FALSE
, DBG_RAW
);
1264 while (objectID
< SINGLE_RESPONSE_ROOF
)
1266 if (!extract_object(singleResponseObjects
, &objectID
, &object
, &level
, &ctx
))
1271 case SINGLE_RESPONSE_ALGORITHM
:
1272 sres
->hash_algorithm
= parse_algorithmIdentifier(object
, level
+1, NULL
);
1274 case SINGLE_RESPONSE_ISSUER_NAME_HASH
:
1275 sres
->issuer_name_hash
= object
;
1277 case SINGLE_RESPONSE_ISSUER_KEY_HASH
:
1278 sres
->issuer_key_hash
= object
;
1280 case SINGLE_RESPONSE_SERIAL_NUMBER
:
1281 sres
->serialNumber
= object
;
1283 case SINGLE_RESPONSE_CERT_STATUS_GOOD
:
1284 sres
->status
= CERT_GOOD
;
1286 case SINGLE_RESPONSE_CERT_STATUS_REVOKED
:
1287 sres
->status
= CERT_REVOKED
;
1289 case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME
:
1290 sres
->revocationTime
= asn1totime(&object
, ASN1_GENERALIZEDTIME
);
1292 case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON
:
1293 sres
->revocationReason
= (object
.len
== 1)
1294 ?
*object
.ptr
: REASON_UNSPECIFIED
;
1296 case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN
:
1297 sres
->status
= CERT_UNKNOWN
;
1299 case SINGLE_RESPONSE_THIS_UPDATE
:
1300 sres
->thisUpdate
= asn1totime(&object
, ASN1_GENERALIZEDTIME
);
1302 case SINGLE_RESPONSE_NEXT_UPDATE
:
1303 sres
->nextUpdate
= asn1totime(&object
, ASN1_GENERALIZEDTIME
);
1305 case SINGLE_RESPONSE_EXT_ID
:
1306 extn_oid
= asn1_known_oid(object
);
1308 case SINGLE_RESPONSE_CRITICAL
:
1309 critical
= object
.len
&& *object
.ptr
;
1311 DBG_log(" %s",(critical
)?
"TRUE":"FALSE");
1313 case SINGLE_RESPONSE_EXT_VALUE
:
1322 * add an ocsp location to a chained list
1325 add_ocsp_location(const ocsp_location_t
*loc
, ocsp_location_t
**chain
)
1327 ocsp_location_t
*location
= malloc_thing(ocsp_location_t
);
1329 /* unshare location fields */
1330 clonetochunk(location
->issuer
, loc
->issuer
.ptr
, loc
->issuer
.len
);
1332 clonetochunk(location
->authNameID
, loc
->authNameID
.ptr
, loc
->authNameID
.len
);
1334 if (loc
->authKeyID
.ptr
== NULL
)
1336 location
->authKeyID
= empty_chunk
;
1340 clonetochunk(location
->authKeyID
, loc
->authKeyID
.ptr
, loc
->authKeyID
.len
);
1343 if (loc
->authKeySerialNumber
.ptr
== NULL
)
1345 location
->authKeySerialNumber
= empty_chunk
;
1349 clonetochunk(location
->authKeySerialNumber
1350 , loc
->authKeySerialNumber
.ptr
, loc
->authKeySerialNumber
.len
);
1353 clonetochunk(location
->uri
, 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
= malloc_thing(ocsp_certinfo_t
);
1401 clonetochunk(cnew
->serialNumber
, info
->serialNumber
.ptr
, info
->serialNumber
.len
);
1402 cnew
->next
= certinfo
;
1408 datatot(info
->serialNumber
.ptr
, info
->serialNumber
.len
, ':'
1410 DBG_log("ocsp %s for serial %s %s"
1411 , request?
"fetch request":"certinfo"
1413 , (cmp
== 0)?
(request?
"already exists":"updated"):"added")
1420 certinfo
->status
= CERT_UNDEFINED
;
1423 certinfo
->thisUpdate
= now
;
1425 certinfo
->nextUpdate
= UNDEFINED_TIME
;
1429 certinfo
->status
= info
->status
;
1430 certinfo
->revocationTime
= info
->revocationTime
;
1431 certinfo
->revocationReason
= info
->revocationReason
;
1433 certinfo
->thisUpdate
= (info
->thisUpdate
!= UNDEFINED_TIME
)?
1434 info
->thisUpdate
: now
;
1436 certinfo
->once
= (info
->nextUpdate
== UNDEFINED_TIME
);
1438 certinfo
->nextUpdate
= (certinfo
->once
)?
1439 (now
+ OCSP_DEFAULT_VALID_TIME
) : info
->nextUpdate
;
1444 * process received ocsp single response and add it to ocsp cache
1447 process_single_response(ocsp_location_t
*location
, single_response_t
*sres
)
1449 ocsp_certinfo_t
*certinfo
, **certinfop
;
1452 if (sres
->hash_algorithm
!= OID_SHA1
)
1454 plog("only SHA-1 hash supported in OCSP single response");
1457 if (!(same_chunk(sres
->issuer_name_hash
, location
->authNameID
)
1458 && same_chunk(sres
->issuer_key_hash
, location
->authKeyID
)))
1460 plog("ocsp single response has wrong issuer");
1464 /* traverse list of certinfos in increasing order */
1465 certinfop
= &location
->certinfo
;
1466 certinfo
= *certinfop
;
1468 while (certinfo
!= NULL
)
1470 cmp
= cmp_chunk(sres
->serialNumber
, certinfo
->serialNumber
);
1473 certinfop
= &certinfo
->next
;
1474 certinfo
= *certinfop
;
1479 plog("received unrequested cert status from ocsp server");
1483 /* unlink cert from ocsp fetch request list */
1484 *certinfop
= certinfo
->next
;
1486 /* update certinfo using the single response information */
1487 certinfo
->thisUpdate
= sres
->thisUpdate
;
1488 certinfo
->nextUpdate
= sres
->nextUpdate
;
1489 certinfo
->status
= sres
->status
;
1490 certinfo
->revocationTime
= sres
->revocationTime
;
1491 certinfo
->revocationReason
= sres
->revocationReason
;
1493 /* add or update certinfo in ocsp cache */
1494 lock_ocsp_cache("process_single_response");
1495 add_certinfo(location
, certinfo
, &ocsp_cache
, FALSE
);
1496 unlock_ocsp_cache("process_single_response");
1498 /* free certinfo unlinked from ocsp fetch request list */
1499 free_certinfo(certinfo
);
1504 * parse and verify ocsp response and update the ocsp cache
1507 parse_ocsp(ocsp_location_t
*location
, chunk_t blob
)
1509 response_t res
= empty_response
;
1511 /* parse the ocsp response without looking at the single responses yet */
1512 response_status status
= parse_ocsp_response(blob
, &res
);
1514 if (status
!= STATUS_SUCCESSFUL
)
1516 plog("error in ocsp response");
1519 /* check if there was a nonce in the request */
1520 if (location
->nonce
.ptr
!= NULL
&& res
.nonce
.ptr
== NULL
)
1522 plog("ocsp response contains no nonce, replay attack possible");
1524 /* check if the nonce is identical */
1525 if (res
.nonce
.ptr
!= NULL
&& !same_chunk(res
.nonce
, location
->nonce
))
1527 plog("invalid nonce in ocsp response");
1530 /* check if the response is signed by a trusted key */
1531 if (!valid_ocsp_response(&res
))
1533 plog("invalid ocsp response");
1537 DBG_log("valid ocsp response")
1540 /* now parse the single responses one at a time */
1547 asn1_init(&ctx
, res
.responses
, 0, FALSE
, DBG_RAW
);
1549 while (objectID
< RESPONSES_ROOF
)
1551 if (!extract_object(responsesObjects
, &objectID
, &object
, &level
, &ctx
))
1554 if (objectID
== RESPONSES_SINGLE_RESPONSE
)
1556 single_response_t sres
= empty_single_response
;
1558 if (parse_ocsp_single_response(object
, level
+1, &sres
))
1560 process_single_response(location
, &sres
);