merged the modularization branch (credentials) back to trunk
[strongswan.git] / src / libstrongswan / plugins / x509 / x509_ocsp_response.c
1 /**
2 * Copyright (C) 2008 Martin Willi
3 * Copyright (C) 2007 Andreas Steffen
4 * Hochschule für Technik Rapperswil
5 * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 *
17 * $Id$
18 */
19
20 #include "x509_ocsp_response.h"
21
22 #include <time.h>
23
24 #include <asn1/oid.h>
25 #include <asn1/asn1.h>
26 #include <utils/identification.h>
27 #include <utils/linked_list.h>
28 #include <debug.h>
29
30 #include <library.h>
31 #include <credentials/certificates/x509.h>
32 #include <credentials/certificates/crl.h>
33
34 typedef struct private_x509_ocsp_response_t private_x509_ocsp_response_t;
35
36 /**
37 * Private data of a ocsp_t object.
38 */
39 struct private_x509_ocsp_response_t {
40 /**
41 * Public interface for this ocsp object.
42 */
43 x509_ocsp_response_t public;
44
45 /**
46 * complete encoded OCSP response
47 */
48 chunk_t data;
49
50 /**
51 * data for signature verficiation
52 */
53 chunk_t tbsResponseData;
54
55 /**
56 * signature algorithm (OID)
57 */
58 int signatureAlgorithm;
59
60 /**
61 * signature value
62 */
63 chunk_t signature;
64
65 /**
66 * name or keyid of the responder
67 */
68 identification_t *responderId;
69
70 /**
71 * time of response production
72 */
73 time_t producedAt;
74
75 /**
76 * list of included certificates
77 */
78 linked_list_t *certs;
79
80 /**
81 * Linked list of OCSP responses, single_response_t
82 */
83 linked_list_t *responses;
84
85 /**
86 * Nonce required for ocsp request and response
87 */
88 chunk_t nonce;
89
90 /**
91 * reference counter
92 */
93 refcount_t ref;
94 };
95
96 /**
97 * single response contained in OCSP response
98 */
99 typedef struct {
100 /** hash algorithm OID to for the two hashes */
101 int hashAlgorithm;
102 /** hash of issuer DN */
103 chunk_t issuerNameHash;
104 /** issuerKeyID */
105 chunk_t issuerKeyHash;
106 /** serial number of certificate */
107 chunk_t serialNumber;
108 /** OCSP certificate status */
109 cert_validation_t status;
110 /** time of revocation, if revoked */
111 time_t revocationTime;
112 /** revocation reason, if revoked */
113 crl_reason_t revocationReason;
114 /** creation of associated CRL */
115 time_t thisUpdate;
116 /** creation of next CRL */
117 time_t nextUpdate;
118 } single_response_t;
119
120 /* our OCSP response version implementation */
121 #define OCSP_BASIC_RESPONSE_VERSION 1
122
123 /* some OCSP specific prefabricated ASN.1 constants */
124 static u_char ASN1_nonce_oid_str[] = {
125 0x06, 0x09,
126 0x2B, 0x06,
127 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
128 };
129
130 static u_char ASN1_response_oid_str[] = {
131 0x06, 0x09,
132 0x2B, 0x06,
133 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
134 };
135
136 static u_char ASN1_response_content_str[] = {
137 0x04, 0x0D,
138 0x30, 0x0B,
139 0x06, 0x09,
140 0x2B, 0x06,
141 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
142 };
143
144 static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
145 static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
146 static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
147
148 /* asn.1 definitions for parsing */
149
150 static const asn1Object_t ocspResponseObjects[] = {
151 { 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
152 { 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
153 { 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
154 { 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
155 { 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
156 { 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
157 { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
158 };
159
160 #define OCSP_RESPONSE_STATUS 1
161 #define OCSP_RESPONSE_TYPE 4
162 #define OCSP_RESPONSE 5
163 #define OCSP_RESPONSE_ROOF 7
164
165 static const asn1Object_t basicResponseObjects[] = {
166 { 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
167 { 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
168 { 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
169 ASN1_DEF }, /* 2 */
170 { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
171 { 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
172 { 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
173 { 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
174 { 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
175 { 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
176 { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
177 { 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
178 { 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
179 { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
180 { 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
181 { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
182 { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
183 { 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
184 ASN1_DEF }, /* 16 */
185 { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
186 { 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
187 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
188 { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
189 { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
190 { 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
191 { 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
192 { 3, "certificate", ASN1_SEQUENCE, ASN1_RAW }, /* 24 */
193 { 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
194 { 1, "end opt", ASN1_EOC, ASN1_END } /* 26 */
195 };
196
197 #define BASIC_RESPONSE_TBS_DATA 1
198 #define BASIC_RESPONSE_VERSION 3
199 #define BASIC_RESPONSE_ID_BY_NAME 5
200 #define BASIC_RESPONSE_ID_BY_KEY 8
201 #define BASIC_RESPONSE_PRODUCED_AT 10
202 #define BASIC_RESPONSE_RESPONSES 11
203 #define BASIC_RESPONSE_EXT_ID 15
204 #define BASIC_RESPONSE_CRITICAL 16
205 #define BASIC_RESPONSE_EXT_VALUE 17
206 #define BASIC_RESPONSE_ALGORITHM 20
207 #define BASIC_RESPONSE_SIGNATURE 21
208 #define BASIC_RESPONSE_CERTIFICATE 24
209 #define BASIC_RESPONSE_ROOF 27
210
211 static const asn1Object_t responsesObjects[] = {
212 { 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
213 { 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
214 { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
215 };
216
217 #define RESPONSES_SINGLE_RESPONSE 1
218 #define RESPONSES_ROOF 3
219
220 static const asn1Object_t singleResponseObjects[] = {
221 { 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
222 { 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
223 { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
224 { 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
225 { 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
226 { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
227 { 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
228 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
229 { 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
230 { 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
231 { 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
232 { 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
233 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
234 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
235 { 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
236 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
237 { 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
238 { 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
239 { 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
240 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
241 { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
242 { 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
243 { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
244 { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
245 { 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
246 ASN1_DEF }, /* 24 */
247 { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
248 { 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
249 { 1, "end opt", ASN1_EOC, ASN1_END } /* 27 */
250 };
251
252 #define SINGLE_RESPONSE_ALGORITHM 2
253 #define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
254 #define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
255 #define SINGLE_RESPONSE_SERIAL_NUMBER 5
256 #define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
257 #define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
258 #define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
259 #define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
260 #define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
261 #define SINGLE_RESPONSE_THIS_UPDATE 16
262 #define SINGLE_RESPONSE_NEXT_UPDATE 18
263 #define SINGLE_RESPONSE_EXT_ID 23
264 #define SINGLE_RESPONSE_CRITICAL 24
265 #define SINGLE_RESPONSE_EXT_VALUE 25
266 #define SINGLE_RESPONSE_ROOF 28
267
268 /**
269 * Implementaiton of ocsp_response_t.get_status
270 */
271 static cert_validation_t get_status(private_x509_ocsp_response_t *this,
272 x509_t *subject, x509_t *issuer,
273 time_t *revocation_time,
274 crl_reason_t *revocation_reason,
275 time_t *this_update, time_t *next_update)
276 {
277 enumerator_t *enumerator;
278 single_response_t *response;
279 cert_validation_t status = VALIDATION_FAILED;
280 certificate_t *issuercert = &issuer->interface;
281
282 enumerator = this->responses->create_enumerator(this->responses);
283 while (enumerator->enumerate(enumerator, &response))
284 {
285 hasher_t *hasher;
286 identification_t *id;
287 chunk_t hash;
288
289 /* check serial first, is cheaper */
290 if (!chunk_equals(subject->get_serial(subject), response->serialNumber))
291 {
292 continue;
293 }
294 /* check issuerKeyHash if available */
295 if (response->issuerKeyHash.ptr)
296 {
297 public_key_t *public;
298
299 public = issuercert->get_public_key(issuercert);
300 if (!public)
301 {
302 continue;
303 }
304 switch (response->hashAlgorithm)
305 { /* TODO: generic mapper function */
306 case OID_SHA1:
307 id = public->get_id(public, ID_PUBKEY_SHA1);
308 break;
309 default:
310 public->destroy(public);
311 continue;
312 }
313 if (!chunk_equals(response->issuerKeyHash, id->get_encoding(id)))
314 {
315 public->destroy(public);
316 continue;
317 }
318 public->destroy(public);
319 }
320 /* check issuerNameHash, if available */
321 else if (response->issuerNameHash.ptr)
322 {
323 hasher = lib->crypto->create_hasher(lib->crypto,
324 hasher_algorithm_from_oid(response->hashAlgorithm));
325 if (!hasher)
326 {
327 continue;
328 }
329 id = issuercert->get_subject(issuercert);
330 hasher->allocate_hash(hasher, id->get_encoding(id), &hash);
331 hasher->destroy(hasher);
332 if (!chunk_equals(hash, response->issuerNameHash))
333 {
334 continue;
335 }
336 }
337 else
338 {
339 continue;
340 }
341 /* got a match */
342 status = response->status;
343 *revocation_time = response->revocationTime;
344 *revocation_reason = response->revocationReason;
345 *this_update = response->thisUpdate;
346 *next_update = response->nextUpdate;
347
348 break;
349 }
350 enumerator->destroy(enumerator);
351 return status;
352 }
353
354 /**
355 * Implementation of ocsp_response_t.create_cert_enumerator.
356 */
357 static enumerator_t* create_cert_enumerator(private_x509_ocsp_response_t *this)
358 {
359 return this->certs->create_enumerator(this->certs);
360 }
361
362 /**
363 * parse a single OCSP response
364 */
365 static bool parse_singleResponse(private_x509_ocsp_response_t *this,
366 chunk_t blob, int level0)
367 {
368 u_int level;
369 asn1_ctx_t ctx;
370 chunk_t object;
371 int objectID = 0;
372 single_response_t *response;
373
374 response = malloc_thing(single_response_t);
375 response->hashAlgorithm = OID_UNKNOWN;
376 response->issuerNameHash = chunk_empty;
377 response->issuerKeyHash = chunk_empty;
378 response->serialNumber = chunk_empty;
379 response->status = VALIDATION_FAILED;
380 response->revocationTime = 0;
381 response->revocationReason = CRL_UNSPECIFIED;
382 response->thisUpdate = 0;
383 response->nextUpdate = 0;
384
385 asn1_init(&ctx, blob, level0, FALSE, FALSE);
386 while (objectID < SINGLE_RESPONSE_ROOF)
387 {
388 if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx))
389 {
390 free(response);
391 return FALSE;
392 }
393 switch (objectID)
394 {
395 case SINGLE_RESPONSE_ALGORITHM:
396 response->hashAlgorithm = parse_algorithmIdentifier(object, level+1, NULL);
397 break;
398 case SINGLE_RESPONSE_ISSUER_NAME_HASH:
399 response->issuerNameHash = object;
400 break;
401 case SINGLE_RESPONSE_ISSUER_KEY_HASH:
402 response->issuerKeyHash = object;
403 break;
404 case SINGLE_RESPONSE_SERIAL_NUMBER:
405 response->serialNumber = object;
406 break;
407 case SINGLE_RESPONSE_CERT_STATUS_GOOD:
408 response->status = VALIDATION_GOOD;
409 break;
410 case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
411 response->status = VALIDATION_REVOKED;
412 break;
413 case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
414 response->revocationTime = asn1totime(&object, ASN1_GENERALIZEDTIME);
415 break;
416 case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
417 if (object.len == 1)
418 {
419 response->revocationReason = *object.ptr;
420 }
421 break;
422 case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
423 response->status = VALIDATION_FAILED;
424 break;
425 case SINGLE_RESPONSE_THIS_UPDATE:
426 response->thisUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
427 break;
428 case SINGLE_RESPONSE_NEXT_UPDATE:
429 response->nextUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
430 break;
431 }
432 objectID++;
433 }
434 this->responses->insert_last(this->responses, response);
435 return TRUE;
436 }
437
438 /**
439 * parse all contained responses
440 */
441 static bool parse_responses(private_x509_ocsp_response_t *this,
442 chunk_t blob, int level0)
443 {
444 u_int level;
445 asn1_ctx_t ctx;
446 chunk_t object;
447 int objectID = 0;
448
449 asn1_init(&ctx, blob, level0, FALSE, FALSE);
450 while (objectID < RESPONSES_ROOF)
451 {
452 if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx))
453 {
454 return FALSE;
455 }
456 switch (objectID)
457 {
458 case RESPONSES_SINGLE_RESPONSE:
459 if (!parse_singleResponse(this, object, level+1))
460 {
461 return FALSE;
462 }
463 break;
464 default:
465 break;
466 }
467 objectID++;
468 }
469 return TRUE;
470 }
471
472 /**
473 * parse a basicOCSPResponse
474 */
475 static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
476 chunk_t blob, int level0)
477 {
478 u_int level, version;
479 asn1_ctx_t ctx;
480 bool critical;
481 chunk_t object, responses = chunk_empty;
482 int objectID = 0;
483 int extn_oid = OID_UNKNOWN;
484 certificate_t *cert;
485
486 asn1_init(&ctx, blob, level0, FALSE, FALSE);
487 while (objectID < BASIC_RESPONSE_ROOF)
488 {
489 if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))
490 {
491 return FALSE;
492 }
493 switch (objectID)
494 {
495 case BASIC_RESPONSE_TBS_DATA:
496 this->tbsResponseData = object;
497 break;
498 case BASIC_RESPONSE_VERSION:
499 version = (object.len)? (1 + (u_int)*object.ptr) : 1;
500 if (version != OCSP_BASIC_RESPONSE_VERSION)
501 {
502 DBG1("OCSP ResponseData version %d not supported", version);
503 return FALSE;
504 }
505 break;
506 case BASIC_RESPONSE_ID_BY_NAME:
507 this->responderId = identification_create_from_encoding(
508 ID_DER_ASN1_DN, object);
509 DBG3(" %D", this->responderId);
510 break;
511 case BASIC_RESPONSE_ID_BY_KEY:
512 this->responderId = identification_create_from_encoding(
513 ID_PUBKEY_INFO_SHA1, object);
514 DBG3(" %D", this->responderId);
515 break;
516 case BASIC_RESPONSE_PRODUCED_AT:
517 this->producedAt = asn1totime(&object, ASN1_GENERALIZEDTIME);
518 break;
519 case BASIC_RESPONSE_RESPONSES:
520 responses = object;
521 break;
522 case BASIC_RESPONSE_EXT_ID:
523 extn_oid = known_oid(object);
524 break;
525 case BASIC_RESPONSE_CRITICAL:
526 critical = object.len && *object.ptr;
527 DBG3(" %s", critical ? "TRUE" : "FALSE");
528 break;
529 case BASIC_RESPONSE_EXT_VALUE:
530 if (extn_oid == OID_NONCE)
531 {
532 this->nonce = object;
533 }
534 break;
535 case BASIC_RESPONSE_ALGORITHM:
536 this->signatureAlgorithm = parse_algorithmIdentifier(
537 object, level+1, NULL);
538 break;
539 case BASIC_RESPONSE_SIGNATURE:
540 this->signature = object;
541 break;
542 case BASIC_RESPONSE_CERTIFICATE:
543 {
544 cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,CERT_X509,
545 BUILD_BLOB_ASN1_DER, chunk_clone(object),
546 BUILD_END);
547 if (cert)
548 {
549 this->certs->insert_last(this->certs, cert);
550 }
551 break;
552 }
553 }
554 objectID++;
555 }
556 if (!this->responderId)
557 {
558 this->responderId = identification_create_from_encoding(ID_ANY, chunk_empty);
559 }
560 return parse_responses(this, responses, level + 1);
561 }
562
563 /**
564 * Parse OCSPResponse object
565 */
566 static bool parse_OCSPResponse(private_x509_ocsp_response_t *this)
567 {
568 asn1_ctx_t ctx;
569 chunk_t object;
570 u_int level;
571 int objectID = 0;
572 int responseType = OID_UNKNOWN;
573 ocsp_status_t status;
574
575 asn1_init(&ctx, this->data, 0, FALSE, FALSE);
576 while (objectID < OCSP_RESPONSE_ROOF)
577 {
578 if (!extract_object(ocspResponseObjects, &objectID, &object, &level, &ctx))
579 {
580 return FALSE;
581 }
582 switch (objectID)
583 {
584 case OCSP_RESPONSE_STATUS:
585 status = (ocsp_status_t)*object.ptr;
586 switch (status)
587 {
588 case OCSP_SUCCESSFUL:
589 break;
590 default:
591 DBG1("OCSP response status: %N",
592 ocsp_status_names, status);
593 return FALSE;
594 }
595 break;
596 case OCSP_RESPONSE_TYPE:
597 responseType = known_oid(object);
598 break;
599 case OCSP_RESPONSE:
600 switch (responseType)
601 {
602 case OID_BASIC:
603 return parse_basicOCSPResponse(this, object, level+1);
604 default:
605 DBG1("OCSP response type %#B not supported", &object);
606 return FALSE;
607 }
608 break;
609 }
610 objectID++;
611 }
612 return FALSE;
613 }
614
615 /**
616 * Implementation of certificate_t.get_type
617 */
618 static certificate_type_t get_type(private_x509_ocsp_response_t *this)
619 {
620 return CERT_X509_OCSP_RESPONSE;
621 }
622
623 /**
624 * Implementation of certificate_t.get_issuer
625 */
626 static identification_t* get_issuer(private_x509_ocsp_response_t *this)
627 {
628 return this->responderId;
629 }
630
631 /**
632 * Implementation of certificate_t.has_subject.
633 */
634 static id_match_t has_issuer(private_x509_ocsp_response_t *this,
635 identification_t *issuer)
636 {
637 return this->responderId->matches(this->responderId, issuer);
638 }
639
640 /**
641 * Implementation of certificate_t.issued_by
642 */
643 static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer,
644 bool sigcheck)
645 {
646 public_key_t *key;
647 signature_scheme_t scheme;
648 bool valid;
649 x509_t *x509 = (x509_t*)issuer;
650
651 if (issuer->get_type(issuer) != CERT_X509)
652 {
653 return FALSE;
654 }
655 if (this->responderId->get_type(this->responderId) == ID_DER_ASN1_DN)
656 {
657 if (!this->responderId->equals(this->responderId,
658 issuer->get_subject(issuer)))
659 {
660 return FALSE;
661 }
662 }
663 else
664 {
665 bool equal;
666 public_key_t *public = issuer->get_public_key(issuer);
667
668 if (public == NULL)
669 {
670 return FALSE;
671 }
672 equal = this->responderId->equals(this->responderId,
673 public->get_id(public, ID_PUBKEY_SHA1));
674 public->destroy(public);
675 if (!equal)
676 {
677 return FALSE;
678 }
679 }
680 if (!(x509->get_flags(x509) & X509_OCSP_SIGNER))
681 {
682 return FALSE;
683 }
684 if (!sigcheck)
685 {
686 return TRUE;
687 }
688 /* TODO: generic OID to scheme mapper? */
689 switch (this->signatureAlgorithm)
690 {
691 case OID_MD5_WITH_RSA:
692 scheme = SIGN_RSA_EMSA_PKCS1_MD5;
693 break;
694 case OID_SHA1_WITH_RSA:
695 scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
696 break;
697 case OID_SHA256_WITH_RSA:
698 scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
699 break;
700 case OID_SHA384_WITH_RSA:
701 scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
702 break;
703 case OID_SHA512_WITH_RSA:
704 scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
705 break;
706 default:
707 return FALSE;
708 }
709 key = issuer->get_public_key(issuer);
710 if (key == NULL)
711 {
712 return FALSE;
713 }
714 valid = key->verify(key, scheme, this->tbsResponseData, this->signature);
715 key->destroy(key);
716 return valid;
717 }
718
719 /**
720 * Implementation of certificate_t.get_public_key
721 */
722 static public_key_t* get_public_key(private_x509_ocsp_response_t *this)
723 {
724 return NULL;
725 }
726
727 /**
728 * Implementation of x509_cert_t.get_validity.
729 */
730 static bool get_validity(private_x509_ocsp_response_t *this, time_t *when,
731 time_t *not_before, time_t *not_after)
732 {
733 time_t t;
734
735 if (when == NULL)
736 {
737 t = time(NULL);
738 }
739 else
740 {
741 t = *when;
742 }
743 if (not_before)
744 {
745 *not_before = this->producedAt;
746 }
747 if (not_after)
748 {
749 *not_after = ~0;
750 }
751 /* valid from produceAt up to infinity */
752 if (t >= this->producedAt)
753 {
754 return TRUE;
755 }
756 return FALSE;
757 }
758
759 /**
760 * Implementation of certificate_t.get_encoding.
761 */
762 static chunk_t get_encoding(private_x509_ocsp_response_t *this)
763 {
764 return chunk_clone(this->data);
765 }
766
767 /**
768 * Implementation of certificate_t.equals.
769 */
770 static bool equals(private_x509_ocsp_response_t *this, certificate_t *other)
771 {
772 if (this == (private_x509_ocsp_response_t*)other)
773 {
774 return TRUE;
775 }
776 if (other->get_type(other) != CERT_X509_OCSP_RESPONSE)
777 {
778 return FALSE;
779 }
780 /* check if we have the same X509 implementation */
781 if (other->equals == (void*)equals)
782 {
783 return chunk_equals(this->data,
784 ((private_x509_ocsp_response_t*)other)->data);
785 }
786 /* TODO: compare against other implementation */
787 return FALSE;
788 }
789
790 /**
791 * Implementation of certificate_t.get_ref
792 */
793 static private_x509_ocsp_response_t* get_ref(private_x509_ocsp_response_t *this)
794 {
795 ref_get(&this->ref);
796 return this;
797 }
798
799 /**
800 * Implements ocsp_t.destroy.
801 */
802 static void destroy(private_x509_ocsp_response_t *this)
803 {
804 if (ref_put(&this->ref))
805 {
806 this->certs->destroy_offset(this->certs, offsetof(certificate_t, destroy));
807 this->responses->destroy_function(this->responses, free);
808 DESTROY_IF(this->responderId);
809 free(this->data.ptr);
810 free(this);
811 }
812 }
813
814 /**
815 * load an OCSP response
816 */
817 static x509_ocsp_response_t *load(chunk_t data)
818 {
819 private_x509_ocsp_response_t *this;
820
821 this = malloc_thing(private_x509_ocsp_response_t);
822
823 this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
824 this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer;
825 this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
826 this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_issuer;
827 this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
828 this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by;
829 this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
830 this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
831 this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
832 this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
833 this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
834 this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
835 this->public.interface.get_status = (cert_validation_t(*)(ocsp_response_t*, x509_t *subject, x509_t *issuer, time_t *revocation_time,crl_reason_t *revocation_reason,time_t *this_update, time_t *next_update))get_status;
836 this->public.interface.create_cert_enumerator = (enumerator_t*(*)(ocsp_response_t*))create_cert_enumerator;
837
838 this->ref = 1;
839 this->data = data;
840 this->tbsResponseData = chunk_empty;
841 this->responderId = NULL;
842 this->producedAt = UNDEFINED_TIME;
843 this->responses = linked_list_create();
844 this->nonce = chunk_empty;
845 this->signatureAlgorithm = OID_UNKNOWN;
846 this->signature = chunk_empty;
847 this->certs = linked_list_create();
848
849 if (!parse_OCSPResponse(this))
850 {
851 destroy(this);
852 return NULL;
853 }
854 return &this->public;
855 }
856
857
858 typedef struct private_builder_t private_builder_t;
859 /**
860 * Builder implementation for certificate loading
861 */
862 struct private_builder_t {
863 /** implements the builder interface */
864 builder_t public;
865 /** loaded response */
866 x509_ocsp_response_t *res;
867 };
868
869 /**
870 * Implementation of builder_t.build
871 */
872 static x509_ocsp_response_t *build(private_builder_t *this)
873 {
874 x509_ocsp_response_t *res = this->res;
875
876 free(this);
877 return res;
878 }
879
880 /**
881 * Implementation of builder_t.add
882 */
883 static void add(private_builder_t *this, builder_part_t part, ...)
884 {
885 va_list args;
886
887 if (this->res)
888 {
889 DBG1("ignoring surplus build part %N", builder_part_names, part);
890 return;
891 }
892
893 switch (part)
894 {
895 case BUILD_BLOB_ASN1_DER:
896 {
897 va_start(args, part);
898 this->res = load(va_arg(args, chunk_t));
899 va_end(args);
900 break;
901 }
902 default:
903 DBG1("ignoring unsupported build part %N", builder_part_names, part);
904 break;
905 }
906 }
907
908 /**
909 * Builder construction function
910 */
911 builder_t *x509_ocsp_response_builder(certificate_type_t type)
912 {
913 private_builder_t *this;
914
915 if (type != CERT_X509_OCSP_RESPONSE)
916 {
917 return NULL;
918 }
919
920 this = malloc_thing(private_builder_t);
921
922 this->res = NULL;
923 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
924 this->public.build = (void*(*)(builder_t *this))build;
925
926 return &this->public;
927 }
928