port the libstrongswan memory allocation methods to pluto
[strongswan.git] / src / pluto / ocsp.c
1 /* Support of the Online Certificate Status Protocol (OCSP)
2 * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
3 * Zuercher Hochschule Winterthur
4 *
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>.
9 *
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
13 * for more details.
14 *
15 * RCSID $Id$
16 */
17
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <time.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25
26 #include <freeswan.h>
27 #include <ipsec_policy.h>
28
29 #include "constants.h"
30 #include "defs.h"
31 #include "log.h"
32 #include "x509.h"
33 #include "crl.h"
34 #include "ca.h"
35 #include "rnd.h"
36 #include "asn1.h"
37 #include "certs.h"
38 #include "smartcard.h"
39 #include <asn1/oid.h>
40 #include "whack.h"
41 #include "pkcs1.h"
42 #include "keys.h"
43 #include "fetch.h"
44 #include "ocsp.h"
45
46 #define NONCE_LENGTH 16
47
48 static const char *const cert_status_names[] = {
49 "good",
50 "revoked",
51 "unknown",
52 "undefined"
53 };
54
55
56 static const char *const response_status_names[] = {
57 "successful",
58 "malformed request",
59 "internal error",
60 "try later",
61 "status #4",
62 "signature required",
63 "unauthorized"
64 };
65
66 /* response container */
67 typedef struct response response_t;
68
69 struct response {
70 chunk_t tbs;
71 chunk_t responder_id_name;
72 chunk_t responder_id_key;
73 time_t produced_at;
74 chunk_t responses;
75 chunk_t nonce;
76 int algorithm;
77 chunk_t signature;
78 };
79
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 */
89 };
90
91 /* single response container */
92 typedef struct single_response single_response_t;
93
94 struct single_response {
95 single_response_t *next;
96 int hash_algorithm;
97 chunk_t issuer_name_hash;
98 chunk_t issuer_key_hash;
99 chunk_t serialNumber;
100 cert_status_t status;
101 time_t revocationTime;
102 crl_reason_t revocationReason;
103 time_t thisUpdate;
104 time_t nextUpdate;
105 };
106
107 const single_response_t empty_single_response = {
108 NULL , /* *next */
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 */
118 };
119
120
121 /* list of single requests */
122 typedef struct request_list request_list_t;
123 struct request_list {
124 chunk_t request;
125 request_list_t *next;
126 };
127
128 /* some OCSP specific prefabricated ASN.1 constants */
129
130 static u_char ASN1_nonce_oid_str[] = {
131 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
132 };
133
134 static const chunk_t ASN1_nonce_oid = strchunk(ASN1_nonce_oid_str);
135
136 static u_char ASN1_response_oid_str[] = {
137 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
138 };
139
140 static const chunk_t ASN1_response_oid = strchunk(ASN1_response_oid_str);
141
142 static u_char ASN1_response_content_str[] = {
143 0x04, 0x0D,
144 0x30, 0x0B,
145 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
146 };
147
148 static const chunk_t ASN1_response_content = strchunk(ASN1_response_content_str);
149
150 /* default OCSP uri */
151 static chunk_t ocsp_default_uri;
152
153 /* ocsp cache: pointer to first element */
154 static ocsp_location_t *ocsp_cache = NULL;
155
156 /* static temporary storage for ocsp requestor information */
157 static x509cert_t *ocsp_requestor_cert = NULL;
158
159 static smartcard_t *ocsp_requestor_sc = NULL;
160
161 static const struct RSA_private_key *ocsp_requestor_pri = NULL;
162
163 /* asn.1 definitions for parsing */
164
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 */
173 };
174
175 #define OCSP_RESPONSE_STATUS 1
176 #define OCSP_RESPONSE_TYPE 4
177 #define OCSP_RESPONSE 5
178 #define OCSP_RESPONSE_ROOF 7
179
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 |
184 ASN1_DEF }, /* 2 */
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 |
199 ASN1_DEF }, /* 16 */
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 */
210 };
211
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
225
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 */
230 };
231
232 #define RESPONSES_SINGLE_RESPONSE 1
233 #define RESPONSES_ROOF 3
234
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 |
261 ASN1_DEF }, /* 24 */
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 */
265 };
266
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
282
283 /* build an ocsp location from certificate information
284 * without unsharing its contents
285 */
286 static bool
287 build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
288 {
289 static u_char digest[SHA1_DIGEST_SIZE]; /* temporary storage */
290
291 location->uri = cert->accessLocation;
292
293 if (location->uri.ptr == NULL)
294 {
295 ca_info_t *ca = get_ca_info(cert->issuer, cert->authKeySerialNumber
296 , cert->authKeyID);
297 if (ca != NULL && ca->ocspuri != NULL)
298 setchunk(location->uri, ca->ocspuri, strlen(ca->ocspuri))
299 else
300 /* abort if no ocsp location uri is defined */
301 return FALSE;
302 }
303
304 setchunk(location->authNameID, digest, SHA1_DIGEST_SIZE);
305 compute_digest(cert->issuer, OID_SHA1, &location->authNameID);
306
307 location->next = NULL;
308 location->issuer = cert->issuer;
309 location->authKeyID = cert->authKeyID;
310 location->authKeySerialNumber = cert->authKeySerialNumber;
311
312 if (cert->authKeyID.ptr == NULL)
313 {
314 x509cert_t *authcert = get_authcert(cert->issuer
315 , cert->authKeySerialNumber, cert->authKeyID, AUTH_CA);
316
317 if (authcert != NULL)
318 {
319 location->authKeyID = authcert->subjectKeyID;
320 location->authKeySerialNumber = authcert->serialNumber;
321 }
322 }
323
324 location->nonce = empty_chunk;
325 location->certinfo = NULL;
326
327 return TRUE;
328 }
329
330 /*
331 * compare two ocsp locations for equality
332 */
333 static bool
334 same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *b)
335 {
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);
341 }
342
343 /*
344 * find an existing ocsp location in a chained list
345 */
346 ocsp_location_t*
347 get_ocsp_location(const ocsp_location_t * loc, ocsp_location_t *chain)
348 {
349
350 while (chain != NULL)
351 {
352 if (same_ocsp_location(loc, chain))
353 return chain;
354 chain = chain->next;
355 }
356 return NULL;
357 }
358
359 /* retrieves the status of a cert from the ocsp cache
360 * returns CERT_UNDEFINED if no status is found
361 */
362 static cert_status_t
363 get_ocsp_status(const ocsp_location_t *loc, chunk_t serialNumber
364 ,time_t *nextUpdate, time_t *revocationTime, crl_reason_t *revocationReason)
365 {
366 ocsp_certinfo_t *certinfo, **certinfop;
367 int cmp = -1;
368
369 /* find location */
370 ocsp_location_t *location = get_ocsp_location(loc, ocsp_cache);
371
372 if (location == NULL)
373 return CERT_UNDEFINED;
374
375 /* traverse list of certinfos in increasing order */
376 certinfop = &location->certinfo;
377 certinfo = *certinfop;
378
379 while (certinfo != NULL)
380 {
381 cmp = cmp_chunk(serialNumber, certinfo->serialNumber);
382 if (cmp <= 0)
383 break;
384 certinfop = &certinfo->next;
385 certinfo = *certinfop;
386 }
387
388 if (cmp == 0)
389 {
390 *nextUpdate = certinfo->nextUpdate;
391 *revocationTime = certinfo->revocationTime;
392 *revocationReason = certinfo->revocationReason;
393 return certinfo->status;
394 }
395
396 return CERT_UNDEFINED;
397 }
398
399 /*
400 * verify the ocsp status of a certificate
401 */
402 cert_status_t
403 verify_by_ocsp(const x509cert_t *cert, time_t *until
404 , time_t *revocationDate, crl_reason_t *revocationReason)
405 {
406 cert_status_t status;
407 ocsp_location_t location;
408 time_t nextUpdate = 0;
409
410 *revocationDate = UNDEFINED_TIME;
411 *revocationReason = REASON_UNSPECIFIED;
412
413 /* is an ocsp location defined? */
414 if (!build_ocsp_location(cert, &location))
415 return CERT_UNDEFINED;
416
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");
421
422 if (status == CERT_UNDEFINED || nextUpdate < time(NULL))
423 {
424 plog("ocsp status is stale or not in cache");
425 add_ocsp_fetch_request(&location, cert->serialNumber);
426
427 /* inititate fetching of ocsp status */
428 wake_fetch_thread("verify_by_ocsp");
429 }
430 *until = nextUpdate;
431 return status;
432 }
433
434 /*
435 * check if an ocsp status is about to expire
436 */
437 void
438 check_ocsp(void)
439 {
440 ocsp_location_t *location;
441
442 lock_ocsp_cache("check_ocsp");
443 location = ocsp_cache;
444
445 while (location != NULL)
446 {
447 char buf[BUF_LEN];
448 bool first = TRUE;
449 ocsp_certinfo_t *certinfo = location->certinfo;
450
451 while (certinfo != NULL)
452 {
453 if (!certinfo->once)
454 {
455 time_t time_left = certinfo->nextUpdate - time(NULL);
456
457 DBG(DBG_CONTROL,
458 if (first)
459 {
460 dntoa(buf, BUF_LEN, location->issuer);
461 DBG_log("issuer: '%s'", buf);
462 if (location->authKeyID.ptr != NULL)
463 {
464 datatot(location->authKeyID.ptr, location->authKeyID.len
465 , ':', buf, BUF_LEN);
466 DBG_log("authkey: %s", buf);
467 }
468 first = FALSE;
469 }
470 datatot(certinfo->serialNumber.ptr, certinfo->serialNumber.len
471 , ':', buf, BUF_LEN);
472 DBG_log("serial: %s, %ld seconds left", buf, time_left)
473 )
474
475 if (time_left < 2*crl_check_interval)
476 add_ocsp_fetch_request(location, certinfo->serialNumber);
477 }
478 certinfo = certinfo->next;
479 }
480 location = location->next;
481 }
482 unlock_ocsp_cache("check_ocsp");
483 }
484
485 /*
486 * frees the allocated memory of a certinfo struct
487 */
488 static void
489 free_certinfo(ocsp_certinfo_t *certinfo)
490 {
491 freeanychunk(certinfo->serialNumber);
492 free(certinfo);
493 }
494
495 /*
496 * frees all certinfos in a chained list
497 */
498 static void
499 free_certinfos(ocsp_certinfo_t *chain)
500 {
501 ocsp_certinfo_t *certinfo;
502
503 while (chain != NULL)
504 {
505 certinfo = chain;
506 chain = chain->next;
507 free_certinfo(certinfo);
508 }
509 }
510
511 /*
512 * frees the memory allocated to an ocsp location including all certinfos
513 */
514 static void
515 free_ocsp_location(ocsp_location_t* location)
516 {
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);
523 free(location);
524 }
525
526 /*
527 * free a chained list of ocsp locations
528 */
529 void
530 free_ocsp_locations(ocsp_location_t **chain)
531 {
532 while (*chain != NULL)
533 {
534 ocsp_location_t *location = *chain;
535 *chain = location->next;
536 free_ocsp_location(location);
537 }
538 }
539
540 /*
541 * free the ocsp cache
542 */
543 void
544 free_ocsp_cache(void)
545 {
546 lock_ocsp_cache("free_ocsp_cache");
547 free_ocsp_locations(&ocsp_cache);
548 unlock_ocsp_cache("free_ocsp_cache");
549 }
550
551 /*
552 * frees the ocsp cache and global variables
553 */
554 void
555 free_ocsp(void)
556 {
557 free(ocsp_default_uri.ptr);
558 free_ocsp_cache();
559 }
560
561 /*
562 * list a chained list of ocsp_locations
563 */
564 void
565 list_ocsp_locations(ocsp_location_t *location, bool requests, bool utc
566 , bool strict)
567 {
568 bool first = TRUE;
569
570 while (location != NULL)
571 {
572 ocsp_certinfo_t *certinfo = location->certinfo;
573
574 if (certinfo != NULL)
575 {
576 u_char buf[BUF_LEN];
577
578 if (first)
579 {
580 whack_log(RC_COMMENT, " ");
581 whack_log(RC_COMMENT, "List of OCSP %s:", requests?
582 "fetch requests":"responses");
583 first = FALSE;
584 }
585 whack_log(RC_COMMENT, " ");
586 if (location->issuer.ptr != NULL)
587 {
588 dntoa(buf, BUF_LEN, location->issuer);
589 whack_log(RC_COMMENT, " issuer: '%s'", buf);
590 }
591 whack_log(RC_COMMENT, " uri: '%.*s'", (int)location->uri.len
592 , location->uri.ptr);
593 if (location->authNameID.ptr != NULL)
594 {
595 datatot(location->authNameID.ptr, location->authNameID.len, ':'
596 , buf, BUF_LEN);
597 whack_log(RC_COMMENT, " authname: %s", buf);
598 }
599 if (location->authKeyID.ptr != NULL)
600 {
601 datatot(location->authKeyID.ptr, location->authKeyID.len, ':'
602 , buf, BUF_LEN);
603 whack_log(RC_COMMENT, " authkey: %s", buf);
604 }
605 if (location->authKeySerialNumber.ptr != NULL)
606 {
607 datatot(location->authKeySerialNumber.ptr
608 , location->authKeySerialNumber.len, ':', buf, BUF_LEN);
609 whack_log(RC_COMMENT, " aserial: %s", buf);
610 }
611 while (certinfo != NULL)
612 {
613 char thisUpdate[TIMETOA_BUF];
614
615 strcpy(thisUpdate, timetoa(&certinfo->thisUpdate, utc));
616
617 if (requests)
618 {
619 whack_log(RC_COMMENT, "%s, trials: %d", thisUpdate
620 , certinfo->trials);
621 }
622 else if (certinfo->once)
623 {
624 whack_log(RC_COMMENT, "%s, onetime use%s", thisUpdate
625 , (certinfo->nextUpdate < time(NULL))? " (expired)": "");
626 }
627 else
628 {
629 whack_log(RC_COMMENT, "%s, until %s %s", thisUpdate
630 , timetoa(&certinfo->nextUpdate, utc)
631 , check_expiry(certinfo->nextUpdate, OCSP_WARNING_INTERVAL, strict));
632 }
633 datatot(certinfo->serialNumber.ptr, certinfo->serialNumber.len, ':'
634 , buf, BUF_LEN);
635 whack_log(RC_COMMENT, " serial: %s, %s", buf
636 , cert_status_names[certinfo->status]);
637 certinfo = certinfo->next;
638 }
639 }
640 location = location->next;
641 }
642 }
643
644 /*
645 * list the ocsp cache
646 */
647 void
648 list_ocsp_cache(bool utc, bool strict)
649 {
650 lock_ocsp_cache("list_ocsp_cache");
651 list_ocsp_locations(ocsp_cache, FALSE, utc, strict);
652 unlock_ocsp_cache("list_ocsp_cache");
653 }
654
655 static bool
656 get_ocsp_requestor_cert(ocsp_location_t *location)
657 {
658 x509cert_t *cert = NULL;
659
660 /* initialize temporary static storage */
661 ocsp_requestor_cert = NULL;
662 ocsp_requestor_sc = NULL;
663 ocsp_requestor_pri = NULL;
664
665 for (;;)
666 {
667 char buf[BUF_LEN];
668
669 /* looking for a certificate from the same issuer */
670 cert = get_x509cert(location->issuer, location->authKeySerialNumber
671 ,location->authKeyID, cert);
672 if (cert == NULL)
673 break;
674
675 DBG(DBG_CONTROL,
676 dntoa(buf, BUF_LEN, cert->subject);
677 DBG_log("candidate: '%s'", buf);
678 )
679
680 if (cert->smartcard)
681 {
682 /* look for a matching private key on a smartcard */
683 smartcard_t *sc = scx_get(cert);
684
685 if (sc != NULL)
686 {
687 DBG(DBG_CONTROL,
688 DBG_log("matching smartcard found")
689 )
690 if (sc->valid)
691 {
692 ocsp_requestor_cert = cert;
693 ocsp_requestor_sc = sc;
694 return TRUE;
695 }
696 plog("unable to sign ocsp request without PIN");
697 }
698 }
699 else
700 {
701 /* look for a matching private key in the chained list */
702 const struct RSA_private_key *pri = get_x509_private_key(cert);
703
704 if (pri != NULL)
705 {
706 DBG(DBG_CONTROL,
707 DBG_log("matching private key found")
708 )
709 ocsp_requestor_cert = cert;
710 ocsp_requestor_pri = pri;
711 return TRUE;
712 }
713 }
714 }
715 return FALSE;
716 }
717
718 static chunk_t
719 generate_signature(chunk_t digest, smartcard_t *sc
720 , const RSA_private_key_t *pri)
721 {
722 chunk_t sigdata;
723 u_char *pos;
724 size_t siglen = 0;
725
726 if (sc != NULL)
727 {
728 /* RSA signature is done on smartcard */
729
730 if (!scx_establish_context(sc) || !scx_login(sc))
731 {
732 scx_release_context(sc);
733 return empty_chunk;
734 }
735
736 siglen = scx_get_keylength(sc);
737
738 if (siglen == 0)
739 {
740 plog("failed to get keylength from smartcard");
741 scx_release_context(sc);
742 return empty_chunk;
743 }
744
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)
748 )
749
750 pos = build_asn1_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
751 *pos++ = 0x00;
752 scx_sign_hash(sc, digest.ptr, digest.len, pos, siglen);
753 if (!pkcs11_keep_state)
754 scx_release_context(sc);
755 }
756 else
757 {
758 /* RSA signature is done in software */
759 siglen = pri->pub.k;
760 pos = build_asn1_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
761 *pos++ = 0x00;
762 sign_hash(pri, digest.ptr, digest.len, pos, siglen);
763 }
764 return sigdata;
765 }
766
767 /*
768 * build signature into ocsp request
769 * gets built only if a request cert with
770 * a corresponding private key is found
771 */
772 static chunk_t
773 build_signature(chunk_t tbsRequest)
774 {
775 chunk_t sigdata, certs;
776 chunk_t digest_info;
777
778 u_char digest_buf[MAX_DIGEST_LEN];
779 chunk_t digest_raw = { digest_buf, MAX_DIGEST_LEN };
780
781 if (!compute_digest(tbsRequest, OID_SHA1, &digest_raw))
782 return empty_chunk;
783
784 /* according to PKCS#1 v2.1 digest must be packaged into
785 * an ASN.1 structure for encryption
786 */
787 digest_info = asn1_wrap(ASN1_SEQUENCE, "cm"
788 , ASN1_sha1_id
789 , asn1_simple_object(ASN1_OCTET_STRING, digest_raw));
790
791 /* generate the RSA signature */
792 sigdata = generate_signature(digest_info
793 , ocsp_requestor_sc
794 , ocsp_requestor_pri);
795 freeanychunk(digest_info);
796
797 /* has the RSA signature generation been successful? */
798 if (sigdata.ptr == NULL)
799 return empty_chunk;
800
801 /* include our certificate */
802 certs = asn1_wrap(ASN1_CONTEXT_C_0, "m"
803 , asn1_simple_object(ASN1_SEQUENCE
804 , ocsp_requestor_cert->certificate
805 )
806 );
807
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
812 , sigdata
813 , certs
814 )
815 );
816 }
817
818 /* build request (into requestList)
819 * no singleRequestExtensions used
820 */
821 static chunk_t
822 build_request(ocsp_location_t *location, ocsp_certinfo_t *certinfo)
823 {
824 chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm"
825 , ASN1_sha1_id
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));
829
830 return asn1_wrap(ASN1_SEQUENCE, "m", reqCert);
831 }
832
833 /*
834 * build requestList (into TBSRequest)
835 */
836 static chunk_t
837 build_request_list(ocsp_location_t *location)
838 {
839 chunk_t requestList;
840 request_list_t *reqs = NULL;
841 ocsp_certinfo_t *certinfo = location->certinfo;
842 u_char *pos;
843
844 size_t datalen = 0;
845
846 /* build content */
847 while (certinfo != NULL)
848 {
849 /* build request for every certificate in list
850 * and store them in a chained list
851 */
852 request_list_t *req = malloc_thing(request_list_t);
853
854 req->request = build_request(location, certinfo);
855 req->next = reqs;
856 reqs = req;
857
858 datalen += req->request.len;
859 certinfo = certinfo->next;
860 }
861
862 pos = build_asn1_object(&requestList, ASN1_SEQUENCE
863 , datalen);
864
865 /* copy all in chained list, free list afterwards */
866 while (reqs != NULL)
867 {
868 request_list_t *req = reqs;
869
870 mv_chunk(&pos, req->request);
871 reqs = reqs->next;
872 free(req);
873 }
874
875 return requestList;
876 }
877
878 /*
879 * build requestorName (into TBSRequest)
880 */
881 static chunk_t
882 build_requestor_name(void)
883 {
884 return asn1_wrap(ASN1_CONTEXT_C_1, "m"
885 , asn1_simple_object(ASN1_CONTEXT_C_4
886 , ocsp_requestor_cert->subject));
887 }
888
889 /*
890 * build nonce extension (into requestExtensions)
891 */
892 static chunk_t
893 build_nonce_extension(ocsp_location_t *location)
894 {
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);
899
900 return asn1_wrap(ASN1_SEQUENCE, "cm"
901 , ASN1_nonce_oid
902 , asn1_simple_object(ASN1_OCTET_STRING, location->nonce));
903 }
904
905 /*
906 * build requestExtensions (into TBSRequest)
907 */
908 static chunk_t
909 build_request_ext(ocsp_location_t *location)
910 {
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"
915 , ASN1_response_oid
916 , ASN1_response_content
917 )
918 )
919 );
920 }
921
922 /*
923 * build TBSRequest (into OCSPRequest)
924 */
925 static chunk_t
926 build_tbs_request(ocsp_location_t *location, bool has_requestor_cert)
927 {
928 /* version is skipped since the default is ok */
929 return asn1_wrap(ASN1_SEQUENCE, "mmm"
930 , (has_requestor_cert)
931 ? build_requestor_name()
932 : empty_chunk
933 , build_request_list(location)
934 , build_request_ext(location));
935 }
936
937 /* assembles an ocsp request to given location
938 * and sets nonce field in location to the sent nonce
939 */
940 chunk_t
941 build_ocsp_request(ocsp_location_t *location)
942 {
943 bool has_requestor_cert;
944 chunk_t tbsRequest, signature;
945 char buf[BUF_LEN];
946
947 DBG(DBG_CONTROL,
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)
952 {
953 datatot(location->authKeyID.ptr, location->authKeyID.len, ':'
954 , buf, BUF_LEN);
955 DBG_log("authkey: %s", buf);
956 }
957 )
958 lock_certs_and_keys("build_ocsp_request");
959
960 /* looks for requestor cert and matching private key */
961 has_requestor_cert = get_ocsp_requestor_cert(location);
962
963 /* build content */
964 tbsRequest = build_tbs_request(location, has_requestor_cert);
965
966 /* sign tbsReuqest */
967 signature = (has_requestor_cert)? build_signature(tbsRequest)
968 : empty_chunk;
969
970 unlock_certs_and_keys("build_ocsp_request");
971
972 return asn1_wrap(ASN1_SEQUENCE, "mm"
973 , tbsRequest
974 , signature);
975 }
976
977 /*
978 * check if the OCSP response has a valid signature
979 */
980 static bool
981 valid_ocsp_response(response_t *res)
982 {
983 int pathlen;
984 x509cert_t *authcert;
985
986 lock_authcert_list("valid_ocsp_response");
987
988 authcert = get_authcert(res->responder_id_name, empty_chunk
989 , res->responder_id_key, AUTH_OCSP | AUTH_CA);
990
991 if (authcert == NULL)
992 {
993 plog("no matching ocsp signer cert found");
994 unlock_authcert_list("valid_ocsp_response");
995 return FALSE;
996 }
997 DBG(DBG_CONTROL,
998 DBG_log("ocsp signer cert found")
999 )
1000
1001 if (!check_signature(res->tbs, res->signature, res->algorithm
1002 , res->algorithm, authcert))
1003 {
1004 plog("signature of ocsp response is invalid");
1005 unlock_authcert_list("valid_ocsp_response");
1006 return FALSE;
1007 }
1008 DBG(DBG_CONTROL,
1009 DBG_log("signature of ocsp response is valid")
1010 )
1011
1012
1013 for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
1014 {
1015 u_char buf[BUF_LEN];
1016 err_t ugh = NULL;
1017 time_t until;
1018
1019 x509cert_t *cert = authcert;
1020
1021 DBG(DBG_CONTROL,
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)
1027 {
1028 datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
1029 , buf, BUF_LEN);
1030 DBG_log("authkey: %s", buf);
1031 }
1032 )
1033
1034 ugh = check_validity(authcert, &until);
1035
1036 if (ugh != NULL)
1037 {
1038 plog("%s", ugh);
1039 unlock_authcert_list("valid_ocsp_response");
1040 return FALSE;
1041 }
1042
1043 DBG(DBG_CONTROL,
1044 DBG_log("certificate is valid")
1045 )
1046
1047 authcert = get_authcert(cert->issuer, cert->authKeySerialNumber
1048 , cert->authKeyID, AUTH_CA);
1049
1050 if (authcert == NULL)
1051 {
1052 plog("issuer cacert not found");
1053 unlock_authcert_list("valid_ocsp_response");
1054 return FALSE;
1055 }
1056 DBG(DBG_CONTROL,
1057 DBG_log("issuer cacert found")
1058 )
1059
1060 if (!check_signature(cert->tbsCertificate, cert->signature
1061 , cert->algorithm, cert->algorithm, authcert))
1062 {
1063 plog("certificate signature is invalid");
1064 unlock_authcert_list("valid_ocsp_response");
1065 return FALSE;
1066 }
1067 DBG(DBG_CONTROL,
1068 DBG_log("certificate signature is valid")
1069 )
1070
1071 /* check if cert is self-signed */
1072 if (same_dn(cert->issuer, cert->subject))
1073 {
1074 DBG(DBG_CONTROL,
1075 DBG_log("reached self-signed root ca")
1076 )
1077 unlock_authcert_list("valid_ocsp_response");
1078 return TRUE;
1079 }
1080 }
1081 plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
1082 unlock_authcert_list("valid_ocsp_response");
1083 return FALSE;
1084 }
1085
1086 /*
1087 * parse a basic OCSP response
1088 */
1089 static bool
1090 parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
1091 {
1092 asn1_ctx_t ctx;
1093 bool critical;
1094 chunk_t object;
1095 u_int level, version;
1096 u_char buf[BUF_LEN];
1097 int objectID = 0;
1098 int extn_oid = OID_UNKNOWN;
1099
1100 asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
1101
1102 while (objectID < BASIC_RESPONSE_ROOF)
1103 {
1104 if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))
1105 return FALSE;
1106
1107 switch (objectID)
1108 {
1109 case BASIC_RESPONSE_TBS_DATA:
1110 res->tbs = object;
1111 break;
1112 case BASIC_RESPONSE_VERSION:
1113 version = (object.len)? (1 + (u_int)*object.ptr) : 1;
1114 if (version != OCSP_BASIC_RESPONSE_VERSION)
1115 {
1116 plog("wrong ocsp basic response version (version= %i)", version);
1117 return FALSE;
1118 }
1119 break;
1120 case BASIC_RESPONSE_ID_BY_NAME:
1121 res->responder_id_name = object;
1122 DBG(DBG_PARSING,
1123 dntoa(buf, BUF_LEN, object);
1124 DBG_log(" '%s'",buf)
1125 )
1126 break;
1127 case BASIC_RESPONSE_ID_BY_KEY:
1128 res->responder_id_key = object;
1129 break;
1130 case BASIC_RESPONSE_PRODUCED_AT:
1131 res->produced_at = asn1totime(&object, ASN1_GENERALIZEDTIME);
1132 break;
1133 case BASIC_RESPONSE_RESPONSES:
1134 res->responses = object;
1135 break;
1136 case BASIC_RESPONSE_EXT_ID:
1137 extn_oid = asn1_known_oid(object);
1138 break;
1139 case BASIC_RESPONSE_CRITICAL:
1140 critical = object.len && *object.ptr;
1141 DBG(DBG_PARSING,
1142 DBG_log(" %s",(critical)?"TRUE":"FALSE");
1143 )
1144 break;
1145 case BASIC_RESPONSE_EXT_VALUE:
1146 if (extn_oid == OID_NONCE)
1147 res->nonce = object;
1148 break;
1149 case BASIC_RESPONSE_ALGORITHM:
1150 res->algorithm = parse_algorithmIdentifier(object, level+1, NULL);
1151 break;
1152 case BASIC_RESPONSE_SIGNATURE:
1153 res->signature = object;
1154 break;
1155 case BASIC_RESPONSE_CERTIFICATE:
1156 {
1157 chunk_t blob;
1158 x509cert_t *cert = malloc_thing(x509cert_t);
1159
1160 clonetochunk(blob, object.ptr, object.len);
1161 *cert = empty_x509cert;
1162
1163 if (parse_x509cert(blob, level+1, cert)
1164 && cert->isOcspSigner
1165 && trust_authcert_candidate(cert, NULL))
1166 {
1167 add_authcert(cert, AUTH_OCSP);
1168 }
1169 else
1170 {
1171 DBG(DBG_CONTROL | DBG_PARSING,
1172 DBG_log("embedded ocsp certificate rejected")
1173 )
1174 free_x509cert(cert);
1175 }
1176 }
1177 break;
1178 }
1179 objectID++;
1180 }
1181 return TRUE;
1182 }
1183
1184
1185 /*
1186 * parse an ocsp response and return the result as a response_t struct
1187 */
1188 static response_status
1189 parse_ocsp_response(chunk_t blob, response_t * res)
1190 {
1191 asn1_ctx_t ctx;
1192 chunk_t object;
1193 u_int level;
1194 int objectID = 0;
1195 int ocspResponseType = OID_UNKNOWN;
1196 response_status rStatus = STATUS_INTERNALERROR;
1197
1198 asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);
1199
1200 while (objectID < OCSP_RESPONSE_ROOF)
1201 {
1202 if (!extract_object(ocspResponseObjects, &objectID, &object, &level, &ctx))
1203 return STATUS_INTERNALERROR;
1204
1205 switch (objectID) {
1206 case OCSP_RESPONSE_STATUS:
1207 rStatus = (response_status) *object.ptr;
1208
1209 switch (rStatus)
1210 {
1211 case STATUS_SUCCESSFUL:
1212 break;
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]);
1220 return rStatus;
1221 default:
1222 return STATUS_INTERNALERROR;
1223 }
1224 break;
1225 case OCSP_RESPONSE_TYPE:
1226 ocspResponseType = asn1_known_oid(object);
1227 break;
1228 case OCSP_RESPONSE:
1229 {
1230 switch (ocspResponseType) {
1231 case OID_BASIC:
1232 if (!parse_basic_ocsp_response(object, level+1, res))
1233 return STATUS_INTERNALERROR;
1234 break;
1235 default:
1236 DBG(DBG_CONTROL,
1237 DBG_log("ocsp response is not of type BASIC");
1238 DBG_dump_chunk("ocsp response OID: ", object);
1239 )
1240 return STATUS_INTERNALERROR;
1241 }
1242 }
1243 break;
1244 }
1245 objectID++;
1246 }
1247 return rStatus;
1248 }
1249
1250 /*
1251 * parse a basic OCSP response
1252 */
1253 static bool
1254 parse_ocsp_single_response(chunk_t blob, int level0, single_response_t *sres)
1255 {
1256 u_int level, extn_oid;
1257 asn1_ctx_t ctx;
1258 bool critical;
1259 chunk_t object;
1260 int objectID = 0;
1261
1262 asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
1263
1264 while (objectID < SINGLE_RESPONSE_ROOF)
1265 {
1266 if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx))
1267 return FALSE;
1268
1269 switch (objectID)
1270 {
1271 case SINGLE_RESPONSE_ALGORITHM:
1272 sres->hash_algorithm = parse_algorithmIdentifier(object, level+1, NULL);
1273 break;
1274 case SINGLE_RESPONSE_ISSUER_NAME_HASH:
1275 sres->issuer_name_hash = object;
1276 break;
1277 case SINGLE_RESPONSE_ISSUER_KEY_HASH:
1278 sres->issuer_key_hash = object;
1279 break;
1280 case SINGLE_RESPONSE_SERIAL_NUMBER:
1281 sres->serialNumber = object;
1282 break;
1283 case SINGLE_RESPONSE_CERT_STATUS_GOOD:
1284 sres->status = CERT_GOOD;
1285 break;
1286 case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
1287 sres->status = CERT_REVOKED;
1288 break;
1289 case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
1290 sres->revocationTime = asn1totime(&object, ASN1_GENERALIZEDTIME);
1291 break;
1292 case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
1293 sres->revocationReason = (object.len == 1)
1294 ? *object.ptr : REASON_UNSPECIFIED;
1295 break;
1296 case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
1297 sres->status = CERT_UNKNOWN;
1298 break;
1299 case SINGLE_RESPONSE_THIS_UPDATE:
1300 sres->thisUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
1301 break;
1302 case SINGLE_RESPONSE_NEXT_UPDATE:
1303 sres->nextUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
1304 break;
1305 case SINGLE_RESPONSE_EXT_ID:
1306 extn_oid = asn1_known_oid(object);
1307 break;
1308 case SINGLE_RESPONSE_CRITICAL:
1309 critical = object.len && *object.ptr;
1310 DBG(DBG_PARSING,
1311 DBG_log(" %s",(critical)?"TRUE":"FALSE");
1312 )
1313 case SINGLE_RESPONSE_EXT_VALUE:
1314 break;
1315 }
1316 objectID++;
1317 }
1318 return TRUE;
1319 }
1320
1321 /*
1322 * add an ocsp location to a chained list
1323 */
1324 ocsp_location_t*
1325 add_ocsp_location(const ocsp_location_t *loc, ocsp_location_t **chain)
1326 {
1327 ocsp_location_t *location = malloc_thing(ocsp_location_t);
1328
1329 /* unshare location fields */
1330 clonetochunk(location->issuer, loc->issuer.ptr, loc->issuer.len);
1331
1332 clonetochunk(location->authNameID, loc->authNameID.ptr, loc->authNameID.len);
1333
1334 if (loc->authKeyID.ptr == NULL)
1335 {
1336 location->authKeyID = empty_chunk;
1337 }
1338 else
1339 {
1340 clonetochunk(location->authKeyID, loc->authKeyID.ptr, loc->authKeyID.len);
1341 }
1342
1343 if (loc->authKeySerialNumber.ptr == NULL)
1344 {
1345 location->authKeySerialNumber = empty_chunk;
1346 }
1347 else
1348 {
1349 clonetochunk(location->authKeySerialNumber
1350 , loc->authKeySerialNumber.ptr, loc->authKeySerialNumber.len);
1351 }
1352
1353 clonetochunk(location->uri, loc->uri.ptr, loc->uri.len);
1354 location->certinfo = NULL;
1355
1356 /* insert new ocsp location in front of chain */
1357 location->next = *chain;
1358 *chain = location;
1359
1360 DBG(DBG_CONTROL,
1361 DBG_log("new ocsp location added")
1362 )
1363
1364 return location;
1365 }
1366
1367 /*
1368 * add a certinfo struct to a chained list
1369 */
1370 void
1371 add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info, ocsp_location_t **chain
1372 , bool request)
1373 {
1374 ocsp_location_t *location;
1375 ocsp_certinfo_t *certinfo, **certinfop;
1376 char buf[BUF_LEN];
1377 time_t now;
1378 int cmp = -1;
1379
1380 location = get_ocsp_location(loc, *chain);
1381 if (location == NULL)
1382 location = add_ocsp_location(loc, chain);
1383
1384 /* traverse list of certinfos in increasing order */
1385 certinfop = &location->certinfo;
1386 certinfo = *certinfop;
1387
1388 while (certinfo != NULL)
1389 {
1390 cmp = cmp_chunk(info->serialNumber, certinfo->serialNumber);
1391 if (cmp <= 0)
1392 break;
1393 certinfop = &certinfo->next;
1394 certinfo = *certinfop;
1395 }
1396
1397 if (cmp != 0)
1398 {
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;
1403 *certinfop = cnew;
1404 certinfo = cnew;
1405 }
1406
1407 DBG(DBG_CONTROL,
1408 datatot(info->serialNumber.ptr, info->serialNumber.len, ':'
1409 , buf, BUF_LEN);
1410 DBG_log("ocsp %s for serial %s %s"
1411 , request?"fetch request":"certinfo"
1412 , buf
1413 , (cmp == 0)? (request?"already exists":"updated"):"added")
1414 )
1415
1416 time(&now);
1417
1418 if (request)
1419 {
1420 certinfo->status = CERT_UNDEFINED;
1421
1422 if (cmp != 0)
1423 certinfo->thisUpdate = now;
1424
1425 certinfo->nextUpdate = UNDEFINED_TIME;
1426 }
1427 else
1428 {
1429 certinfo->status = info->status;
1430 certinfo->revocationTime = info->revocationTime;
1431 certinfo->revocationReason = info->revocationReason;
1432
1433 certinfo->thisUpdate = (info->thisUpdate != UNDEFINED_TIME)?
1434 info->thisUpdate : now;
1435
1436 certinfo->once = (info->nextUpdate == UNDEFINED_TIME);
1437
1438 certinfo->nextUpdate = (certinfo->once)?
1439 (now + OCSP_DEFAULT_VALID_TIME) : info->nextUpdate;
1440 }
1441 }
1442
1443 /*
1444 * process received ocsp single response and add it to ocsp cache
1445 */
1446 static void
1447 process_single_response(ocsp_location_t *location, single_response_t *sres)
1448 {
1449 ocsp_certinfo_t *certinfo, **certinfop;
1450 int cmp = -1;
1451
1452 if (sres->hash_algorithm != OID_SHA1)
1453 {
1454 plog("only SHA-1 hash supported in OCSP single response");
1455 return;
1456 }
1457 if (!(same_chunk(sres->issuer_name_hash, location->authNameID)
1458 && same_chunk(sres->issuer_key_hash, location->authKeyID)))
1459 {
1460 plog("ocsp single response has wrong issuer");
1461 return;
1462 }
1463
1464 /* traverse list of certinfos in increasing order */
1465 certinfop = &location->certinfo;
1466 certinfo = *certinfop;
1467
1468 while (certinfo != NULL)
1469 {
1470 cmp = cmp_chunk(sres->serialNumber, certinfo->serialNumber);
1471 if (cmp <= 0)
1472 break;
1473 certinfop = &certinfo->next;
1474 certinfo = *certinfop;
1475 }
1476
1477 if (cmp != 0)
1478 {
1479 plog("received unrequested cert status from ocsp server");
1480 return;
1481 }
1482
1483 /* unlink cert from ocsp fetch request list */
1484 *certinfop = certinfo->next;
1485
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;
1492
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");
1497
1498 /* free certinfo unlinked from ocsp fetch request list */
1499 free_certinfo(certinfo);
1500
1501 }
1502
1503 /*
1504 * parse and verify ocsp response and update the ocsp cache
1505 */
1506 void
1507 parse_ocsp(ocsp_location_t *location, chunk_t blob)
1508 {
1509 response_t res = empty_response;
1510
1511 /* parse the ocsp response without looking at the single responses yet */
1512 response_status status = parse_ocsp_response(blob, &res);
1513
1514 if (status != STATUS_SUCCESSFUL)
1515 {
1516 plog("error in ocsp response");
1517 return;
1518 }
1519 /* check if there was a nonce in the request */
1520 if (location->nonce.ptr != NULL && res.nonce.ptr == NULL)
1521 {
1522 plog("ocsp response contains no nonce, replay attack possible");
1523 }
1524 /* check if the nonce is identical */
1525 if (res.nonce.ptr != NULL && !same_chunk(res.nonce, location->nonce))
1526 {
1527 plog("invalid nonce in ocsp response");
1528 return;
1529 }
1530 /* check if the response is signed by a trusted key */
1531 if (!valid_ocsp_response(&res))
1532 {
1533 plog("invalid ocsp response");
1534 return;
1535 }
1536 DBG(DBG_CONTROL,
1537 DBG_log("valid ocsp response")
1538 )
1539
1540 /* now parse the single responses one at a time */
1541 {
1542 u_int level;
1543 asn1_ctx_t ctx;
1544 chunk_t object;
1545 int objectID = 0;
1546
1547 asn1_init(&ctx, res.responses, 0, FALSE, DBG_RAW);
1548
1549 while (objectID < RESPONSES_ROOF)
1550 {
1551 if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx))
1552 return;
1553
1554 if (objectID == RESPONSES_SINGLE_RESPONSE)
1555 {
1556 single_response_t sres = empty_single_response;
1557
1558 if (parse_ocsp_single_response(object, level+1, &sres))
1559 {
1560 process_single_response(location, &sres);
1561 }
1562 }
1563 objectID++;
1564 }
1565 }
1566 }