removing svn keyword $Id$ from all files
[strongswan.git] / src / libstrongswan / plugins / x509 / x509_ocsp_request.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 * Copyright (C) 2007 Andreas Steffen
4 * Hochschule fuer 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
18 #include "x509_ocsp_request.h"
19
20 #include <library.h>
21 #include <asn1/oid.h>
22 #include <asn1/asn1.h>
23 #include <utils/identification.h>
24 #include <utils/linked_list.h>
25 #include <debug.h>
26 #include <credentials/certificates/x509.h>
27
28 #define NONCE_LEN 16
29
30 typedef struct private_x509_ocsp_request_t private_x509_ocsp_request_t;
31
32 /**
33 * private data of x509_ocsp_request
34 */
35 struct private_x509_ocsp_request_t {
36
37 /**
38 * public functions
39 */
40 x509_ocsp_request_t public;
41
42 /**
43 * CA the candidates belong to
44 */
45 x509_t *ca;
46
47 /**
48 * Requestor name, subject of cert used if not set
49 */
50 identification_t *requestor;
51
52 /**
53 * Requestor certificate, included in request
54 */
55 certificate_t *cert;
56
57 /**
58 * Requestor private key to sign request
59 */
60 private_key_t *key;
61
62 /**
63 * list of certificates to check, x509_t
64 */
65 linked_list_t *candidates;
66
67 /**
68 * nonce used in request
69 */
70 chunk_t nonce;
71
72 /**
73 * encoded OCSP request
74 */
75 chunk_t encoding;
76
77 /**
78 * reference count
79 */
80 refcount_t ref;
81 };
82
83 static u_char ASN1_nonce_oid_str[] = {
84 0x06, 0x09,
85 0x2B, 0x06,
86 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
87 };
88
89 static u_char ASN1_response_oid_str[] = {
90 0x06, 0x09,
91 0x2B, 0x06,
92 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
93 };
94
95 static u_char ASN1_response_content_str[] = {
96 0x04, 0x0D,
97 0x30, 0x0B,
98 0x06, 0x09,
99 0x2B, 0x06,
100 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
101 };
102
103 static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
104 static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
105 static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
106
107 /**
108 * build requestorName
109 */
110 static chunk_t build_requestorName(private_x509_ocsp_request_t *this)
111 {
112 if (this->requestor || this->cert)
113 { /* use requestor name, fallback to his cert subject */
114 if (!this->requestor)
115 {
116 this->requestor = this->cert->get_subject(this->cert);
117 this->requestor = this->requestor->clone(this->requestor);
118 }
119 return asn1_wrap(ASN1_CONTEXT_C_1, "m",
120 asn1_simple_object(ASN1_CONTEXT_C_4,
121 this->requestor->get_encoding(this->requestor)));
122
123 }
124 return chunk_empty;
125 }
126
127 /**
128 * build Request, not using singleRequestExtensions
129 */
130 static chunk_t build_Request(private_x509_ocsp_request_t *this,
131 chunk_t issuerNameHash, chunk_t issuerKeyHash,
132 chunk_t serialNumber)
133 {
134 return asn1_wrap(ASN1_SEQUENCE, "m",
135 asn1_wrap(ASN1_SEQUENCE, "cmmm",
136 asn1_algorithmIdentifier(OID_SHA1),
137 asn1_simple_object(ASN1_OCTET_STRING, issuerNameHash),
138 asn1_simple_object(ASN1_OCTET_STRING, issuerKeyHash),
139 asn1_simple_object(ASN1_INTEGER, serialNumber)));
140 }
141
142 /**
143 * build requestList
144 */
145 static chunk_t build_requestList(private_x509_ocsp_request_t *this)
146 {
147 chunk_t issuerNameHash, issuerKeyHash;
148 identification_t *issuer;
149 x509_t *x509;
150 certificate_t *cert;
151 chunk_t list = chunk_empty;
152 public_key_t *public;
153
154 cert = (certificate_t*)this->ca;
155 public = cert->get_public_key(cert);
156 if (public)
157 {
158 hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
159 if (hasher)
160 {
161 identification_t *keyid = public->get_id(public, ID_PUBKEY_SHA1);
162 if (keyid)
163 {
164 enumerator_t *enumerator;
165
166 issuerKeyHash = keyid->get_encoding(keyid);
167
168 issuer = cert->get_subject(cert);
169 hasher->allocate_hash(hasher, issuer->get_encoding(issuer),
170 &issuerNameHash);
171 hasher->destroy(hasher);
172
173 enumerator = this->candidates->create_enumerator(this->candidates);
174 while (enumerator->enumerate(enumerator, &x509))
175 {
176 chunk_t request, serialNumber;
177
178 serialNumber = x509->get_serial(x509);
179 request = build_Request(this, issuerNameHash, issuerKeyHash,
180 serialNumber);
181 list = chunk_cat("mm", list, request);
182 }
183 enumerator->destroy(enumerator);
184 chunk_free(&issuerNameHash);
185 }
186 }
187 else
188 {
189 DBG1("creating OCSP request failed, SHA1 not supported");
190 }
191 public->destroy(public);
192 }
193 else
194 {
195 DBG1("creating OCSP request failed, CA certificate has no public key");
196 }
197 return asn1_wrap(ASN1_SEQUENCE, "m", list);
198 }
199
200 /**
201 * build nonce extension
202 */
203 static chunk_t build_nonce(private_x509_ocsp_request_t *this)
204 {
205 rng_t *rng;
206
207 rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
208 if (rng)
209 {
210 rng->allocate_bytes(rng, NONCE_LEN, &this->nonce);
211 rng->destroy(rng);
212 return asn1_wrap(ASN1_SEQUENCE, "cm", ASN1_nonce_oid,
213 asn1_simple_object(ASN1_OCTET_STRING, this->nonce));
214 }
215 DBG1("creating OCSP request nonce failed, no RNG found");
216 return chunk_empty;
217 }
218
219 /**
220 * build acceptableResponses extension
221 */
222 static chunk_t build_acceptableResponses(private_x509_ocsp_request_t *this)
223 {
224 return asn1_wrap(ASN1_SEQUENCE, "cc",
225 ASN1_response_oid,
226 ASN1_response_content);
227 }
228
229 /**
230 * build requestExtensions
231 */
232 static chunk_t build_requestExtensions(private_x509_ocsp_request_t *this)
233 {
234 return asn1_wrap(ASN1_CONTEXT_C_2, "m",
235 asn1_wrap(ASN1_SEQUENCE, "mm",
236 build_nonce(this),
237 build_acceptableResponses(this)));
238 }
239
240 /**
241 * build tbsRequest
242 */
243 static chunk_t build_tbsRequest(private_x509_ocsp_request_t *this)
244 {
245 return asn1_wrap(ASN1_SEQUENCE, "mmm",
246 build_requestorName(this),
247 build_requestList(this),
248 build_requestExtensions(this));
249 }
250
251 /**
252 * Build the optionalSignature
253 */
254 static chunk_t build_optionalSignature(private_x509_ocsp_request_t *this,
255 chunk_t tbsRequest)
256 {
257 int oid;
258 signature_scheme_t scheme;
259 chunk_t certs, signature;
260
261 switch (this->key->get_type(this->key))
262 {
263 /* TODO: use a generic mapping function */
264 case KEY_RSA:
265 oid = OID_SHA1_WITH_RSA;
266 scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
267 break;
268 case KEY_ECDSA:
269 oid = OID_ECDSA_WITH_SHA1;
270 scheme = SIGN_ECDSA_WITH_SHA1;
271 break;
272 default:
273 DBG1("unable to sign OCSP request, %N signature not supported",
274 key_type_names, this->key->get_type(this->key));
275 return chunk_empty;
276 }
277
278 if (!this->key->sign(this->key, scheme, tbsRequest, &signature))
279 {
280 DBG1("creating OCSP signature failed, skipped");
281 return chunk_empty;
282 }
283 if (this->cert)
284 {
285 certs = asn1_wrap(ASN1_CONTEXT_C_0, "m",
286 asn1_wrap(ASN1_SEQUENCE, "m",
287 this->cert->get_encoding(this->cert)));
288 }
289 return asn1_wrap(ASN1_CONTEXT_C_0, "m",
290 asn1_wrap(ASN1_SEQUENCE, "cmm",
291 asn1_algorithmIdentifier(oid),
292 asn1_bitstring("m", signature),
293 certs));
294 }
295
296 /**
297 * Build the OCSPRequest data
298 *
299 */
300 static chunk_t build_OCSPRequest(private_x509_ocsp_request_t *this)
301 {
302 chunk_t tbsRequest, optionalSignature = chunk_empty;
303
304 tbsRequest = build_tbsRequest(this);
305 if (this->key)
306 {
307 optionalSignature = build_optionalSignature(this, tbsRequest);
308 }
309 return asn1_wrap(ASN1_SEQUENCE, "mm", tbsRequest, optionalSignature);
310 }
311
312
313 /**
314 * Implementation of certificate_t.get_type
315 */
316 static certificate_type_t get_type(private_x509_ocsp_request_t *this)
317 {
318 return CERT_X509_OCSP_REQUEST;
319 }
320
321 /**
322 * Implementation of certificate_t.get_subject
323 */
324 static identification_t* get_subject(private_x509_ocsp_request_t *this)
325 {
326 certificate_t *ca = (certificate_t*)this->ca;
327
328 if (this->requestor)
329 {
330 return this->requestor;
331 }
332 if (this->cert)
333 {
334 return this->cert->get_subject(this->cert);
335 }
336 return ca->get_subject(ca);
337 }
338
339 /**
340 * Implementation of certificate_t.get_issuer
341 */
342 static identification_t* get_issuer(private_x509_ocsp_request_t *this)
343 {
344 certificate_t *ca = (certificate_t*)this->ca;
345
346 return ca->get_subject(ca);
347 }
348
349 /**
350 * Implementation of certificate_t.has_subject.
351 */
352 static id_match_t has_subject(private_x509_ocsp_request_t *this,
353 identification_t *subject)
354 {
355 certificate_t *current;
356 enumerator_t *enumerator;
357 id_match_t match, best = ID_MATCH_NONE;
358
359 enumerator = this->candidates->create_enumerator(this->candidates);
360 while (enumerator->enumerate(enumerator, &current))
361 {
362 match = current->has_subject(current, subject);
363 if (match > best)
364 {
365 best = match;
366 }
367 }
368 enumerator->destroy(enumerator);
369 return best;
370 }
371
372 /**
373 * Implementation of certificate_t.has_subject.
374 */
375 static id_match_t has_issuer(private_x509_ocsp_request_t *this,
376 identification_t *issuer)
377 {
378 certificate_t *ca = (certificate_t*)this->ca;
379
380 return ca->has_subject(ca, issuer);
381 }
382
383 /**
384 * Implementation of certificate_t.issued_by
385 */
386 static bool issued_by(private_x509_ocsp_request_t *this, certificate_t *issuer)
387 {
388 DBG1("OCSP request validation not implemented!");
389 return FALSE;
390 }
391
392 /**
393 * Implementation of certificate_t.get_public_key
394 */
395 static public_key_t* get_public_key(private_x509_ocsp_request_t *this)
396 {
397 return NULL;
398 }
399
400 /**
401 * Implementation of x509_cert_t.get_validity.
402 */
403 static bool get_validity(private_x509_ocsp_request_t *this, time_t *when,
404 time_t *not_before, time_t *not_after)
405 {
406 certificate_t *cert;
407
408 if (this->cert)
409 {
410 cert = this->cert;
411 }
412 else
413 {
414 cert = (certificate_t*)this->ca;
415 }
416 return cert->get_validity(cert, when, not_before, not_after);
417 }
418
419 /**
420 * Implementation of certificate_t.get_encoding.
421 */
422 static chunk_t get_encoding(private_x509_ocsp_request_t *this)
423 {
424 return chunk_clone(this->encoding);
425 }
426
427 /**
428 * Implementation of certificate_t.equals.
429 */
430 static bool equals(private_x509_ocsp_request_t *this, certificate_t *other)
431 {
432 chunk_t encoding;
433 bool equal;
434
435 if (this == (private_x509_ocsp_request_t*)other)
436 {
437 return TRUE;
438 }
439 if (other->get_type(other) != CERT_X509_OCSP_REQUEST)
440 {
441 return FALSE;
442 }
443 if (other->equals == (void*)equals)
444 { /* skip allocation if we have the same implementation */
445 return chunk_equals(this->encoding, ((private_x509_ocsp_request_t*)other)->encoding);
446 }
447 encoding = other->get_encoding(other);
448 equal = chunk_equals(this->encoding, encoding);
449 free(encoding.ptr);
450 return equal;
451 }
452
453 /**
454 * Implementation of certificate_t.asdf
455 */
456 static private_x509_ocsp_request_t* get_ref(private_x509_ocsp_request_t *this)
457 {
458 ref_get(&this->ref);
459 return this;
460 }
461
462 /**
463 * Implementation of x509_ocsp_request_t.destroy
464 */
465 static void destroy(private_x509_ocsp_request_t *this)
466 {
467 if (ref_put(&this->ref))
468 {
469 DESTROY_IF((certificate_t*)this->ca);
470 DESTROY_IF(this->requestor);
471 DESTROY_IF(this->cert);
472 DESTROY_IF(this->key);
473 this->candidates->destroy_offset(this->candidates, offsetof(certificate_t, destroy));
474 chunk_free(&this->nonce);
475 chunk_free(&this->encoding);
476 free(this);
477 }
478 }
479
480 /**
481 * create an empty but initialized OCSP request
482 */
483 static private_x509_ocsp_request_t *create_empty()
484 {
485 private_x509_ocsp_request_t *this = malloc_thing(private_x509_ocsp_request_t);
486
487 this->public.interface.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
488 this->public.interface.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
489 this->public.interface.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
490 this->public.interface.interface.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject;
491 this->public.interface.interface.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
492 this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
493 this->public.interface.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
494 this->public.interface.interface.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
495 this->public.interface.interface.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
496 this->public.interface.interface.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
497 this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
498 this->public.interface.interface.destroy = (void (*)(certificate_t *this))destroy;
499
500 this->ca = NULL;
501 this->requestor = NULL;
502 this->cert = NULL;
503 this->key = NULL;
504 this->nonce = chunk_empty;
505 this->encoding = chunk_empty;
506 this->candidates = linked_list_create();
507 this->ref = 1;
508
509 return this;
510 }
511
512 typedef struct private_builder_t private_builder_t;
513 /**
514 * Builder implementation for certificate loading
515 */
516 struct private_builder_t {
517 /** implements the builder interface */
518 builder_t public;
519 /** OCSP request to build */
520 private_x509_ocsp_request_t *req;
521 };
522
523 /**
524 * Implementation of builder_t.build
525 */
526 static x509_ocsp_request_t *build(private_builder_t *this)
527 {
528 private_x509_ocsp_request_t *req;
529
530 req = this->req;
531 free(this);
532 if (req->ca)
533 {
534 req->encoding = build_OCSPRequest(req);
535 return &req->public;
536 }
537 destroy(req);
538 return NULL;
539 }
540
541 /**
542 * Implementation of builder_t.add
543 */
544 static void add(private_builder_t *this, builder_part_t part, ...)
545 {
546 va_list args;
547 certificate_t *cert;
548 identification_t *subject;
549 private_key_t *private;
550
551 va_start(args, part);
552 switch (part)
553 {
554 case BUILD_CA_CERT:
555 cert = va_arg(args, certificate_t*);
556 if (cert->get_type(cert) == CERT_X509)
557 {
558 this->req->ca = (x509_t*)cert->get_ref(cert);
559 }
560 break;
561 case BUILD_CERT:
562 cert = va_arg(args, certificate_t*);
563 if (cert->get_type(cert) == CERT_X509)
564 {
565 this->req->candidates->insert_last(this->req->candidates,
566 cert->get_ref(cert));
567 }
568 break;
569 case BUILD_SIGNING_CERT:
570 cert = va_arg(args, certificate_t*);
571 this->req->cert = cert->get_ref(cert);
572 break;
573 case BUILD_SIGNING_KEY:
574 private = va_arg(args, private_key_t*);
575 this->req->key = private->get_ref(private);
576 break;
577 case BUILD_SUBJECT:
578 subject = va_arg(args, identification_t*);
579 this->req->requestor = subject->clone(subject);
580 break;
581 default:
582 /* cancel if option not supported */
583 if (this->req)
584 {
585 destroy(this->req);
586 }
587 builder_cancel(&this->public);
588 break;
589 }
590 va_end(args);
591 }
592
593 /**
594 * Builder construction function
595 */
596 builder_t *x509_ocsp_request_builder(certificate_type_t type)
597 {
598 private_builder_t *this;
599
600 if (type != CERT_X509_OCSP_REQUEST)
601 {
602 return NULL;
603 }
604
605 this = malloc_thing(private_builder_t);
606
607 this->req = create_empty();
608 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
609 this->public.build = (void*(*)(builder_t *this))build;
610
611 return &this->public;
612 }
613