Fix referencing of multiple CERTREQ payload with IKEv1, other cleanups
[strongswan.git] / src / libcharon / sa / tasks / ike_cert_pre.c
1 /*
2 * Copyright (C) 2008 Tobias Brunner
3 * Copyright (C) 2006-2009 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "ike_cert_pre.h"
18
19 #include <daemon.h>
20 #include <sa/ike_sa.h>
21 #include <encoding/payloads/cert_payload.h>
22 #include <encoding/payloads/sa_payload.h>
23 #include <encoding/payloads/certreq_payload.h>
24 #include <credentials/certificates/x509.h>
25
26
27 typedef struct private_ike_cert_pre_t private_ike_cert_pre_t;
28
29 /**
30 * Private members of a ike_cert_pre_t task.
31 */
32 struct private_ike_cert_pre_t {
33
34 /**
35 * Public methods and task_t interface.
36 */
37 ike_cert_pre_t public;
38
39 /**
40 * Assigned IKE_SA.
41 */
42 ike_sa_t *ike_sa;
43
44 /**
45 * Are we the initiator?
46 */
47 bool initiator;
48
49 /**
50 * Do we accept HTTP certificate lookup requests
51 */
52 bool do_http_lookup;
53
54 /**
55 * wheter this is the final authentication round
56 */
57 bool final;
58
59 /** states of ike cert pre */
60 enum {
61 CP_INIT,
62 CP_SA,
63 CP_SA_POST,
64 CP_REQ_SENT,
65 CP_NO_CERT,
66 } state;
67
68 /**
69 * type of certicate request to send
70 */
71 payload_type_t cert_req_payload_type;
72 };
73
74 /**
75 * add certificate to auth
76 */
77 static bool add_certificate(auth_cfg_t *auth, id_type_t type, chunk_t data)
78 {
79 identification_t *id;
80 certificate_t *cert;
81 bool status = TRUE;
82
83 if (!data.len)
84 {
85 return FALSE;
86 }
87 id = identification_create_from_encoding(type, data);
88 cert = lib->credmgr->get_cert(lib->credmgr, CERT_X509, KEY_ANY, id, TRUE);
89 if (cert)
90 {
91 DBG1(DBG_IKE, "received cert request for \"%Y\"",
92 cert->get_subject(cert));
93 auth->add(auth, AUTH_RULE_CA_CERT, cert);
94 }
95 else
96 {
97 DBG2(DBG_IKE, "received cert request for unknown ca %Y", id);
98 status = FALSE;
99 }
100 id->destroy(id);
101
102 return status;
103 }
104
105 /**
106 * read certificate requests
107 */
108 static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
109 {
110 enumerator_t *enumerator;
111 payload_t *payload;
112 auth_cfg_t *auth;
113
114 auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
115
116 enumerator = message->create_payload_enumerator(message);
117 while (enumerator->enumerate(enumerator, &payload))
118 {
119 switch (payload->get_type(payload))
120 {
121 case CERTIFICATE_REQUEST:
122 case CERTIFICATE_REQUEST_V1:
123 {
124 certreq_payload_t *certreq = (certreq_payload_t*)payload;
125 enumerator_t *enumerator;
126 u_int unknown = 0;
127 chunk_t chunk;
128
129 this->ike_sa->set_condition(this->ike_sa, COND_CERTREQ_SEEN, TRUE);
130
131 if (certreq->get_cert_type(certreq) != CERT_X509)
132 {
133 DBG1(DBG_IKE, "cert payload %N not supported - ignored",
134 certificate_type_names, certreq->get_cert_type(certreq));
135 break;
136 }
137
138 if (payload->get_type(payload) == CERTIFICATE_REQUEST)
139 {
140 enumerator = certreq->create_keyid_enumerator(certreq);
141 while (enumerator->enumerate(enumerator, &chunk))
142 {
143 if (!add_certificate(auth, ID_KEY_ID, chunk))
144 {
145 unknown++;
146 }
147 }
148 enumerator->destroy(enumerator);
149 }
150 else
151 {
152 chunk = certreq->get_dn(certreq);
153 if (!add_certificate(auth, ID_DER_ASN1_DN, chunk))
154 {
155 unknown++;
156 }
157 }
158 if (unknown)
159 {
160 DBG1(DBG_IKE, "received %u cert requests for an unknown ca",
161 unknown);
162 }
163 break;
164 }
165 case NOTIFY:
166 {
167 notify_payload_t *notify = (notify_payload_t*)payload;
168
169 /* we only handle one type of notify here */
170 if (notify->get_notify_type(notify) == HTTP_CERT_LOOKUP_SUPPORTED)
171 {
172 this->ike_sa->enable_extension(this->ike_sa, EXT_HASH_AND_URL);
173 }
174 break;
175 }
176 default:
177 /* ignore other payloads here, these are handled elsewhere */
178 break;
179 }
180 }
181 enumerator->destroy(enumerator);
182 }
183
184 /**
185 * tries to extract a certificate from the cert payload or the credential
186 * manager (based on the hash of a "Hash and URL" encoded cert).
187 * Note: the returned certificate (if any) has to be destroyed
188 */
189 static certificate_t *try_get_cert(cert_payload_t *cert_payload)
190 {
191 certificate_t *cert = NULL;
192
193 switch (cert_payload->get_cert_encoding(cert_payload))
194 {
195 case ENC_X509_SIGNATURE:
196 {
197 cert = cert_payload->get_cert(cert_payload);
198 break;
199 }
200 case ENC_X509_HASH_AND_URL:
201 {
202 identification_t *id;
203 chunk_t hash = cert_payload->get_hash(cert_payload);
204 if (!hash.ptr)
205 {
206 /* invalid "Hash and URL" data (logged elsewhere) */
207 break;
208 }
209 id = identification_create_from_encoding(ID_KEY_ID, hash);
210 cert = lib->credmgr->get_cert(lib->credmgr,
211 CERT_X509, KEY_ANY, id, FALSE);
212 id->destroy(id);
213 break;
214 }
215 default:
216 {
217 break;
218 }
219 }
220 return cert;
221 }
222
223 /**
224 * import certificates
225 */
226 static void process_certs(private_ike_cert_pre_t *this, message_t *message)
227 {
228 enumerator_t *enumerator;
229 payload_t *payload;
230 auth_cfg_t *auth;
231 bool first = TRUE;
232
233 auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
234
235 enumerator = message->create_payload_enumerator(message);
236 while (enumerator->enumerate(enumerator, &payload))
237 {
238 if (payload->get_type(payload) == CERTIFICATE ||
239 payload->get_type(payload) == CERTIFICATE_V1)
240 {
241 cert_payload_t *cert_payload;
242 cert_encoding_t encoding;
243 certificate_t *cert;
244 char *url;
245
246 cert_payload = (cert_payload_t*)payload;
247 encoding = cert_payload->get_cert_encoding(cert_payload);
248
249 switch (encoding)
250 {
251 case ENC_X509_HASH_AND_URL:
252 {
253 if (!this->do_http_lookup)
254 {
255 DBG1(DBG_IKE, "received hash-and-url encoded cert, but"
256 " we don't accept them, ignore");
257 break;
258 }
259 /* FALL */
260 }
261 case ENC_X509_SIGNATURE:
262 {
263 cert = try_get_cert(cert_payload);
264 if (cert)
265 {
266 if (first)
267 { /* the first is an end entity certificate */
268 DBG1(DBG_IKE, "received end entity cert \"%Y\"",
269 cert->get_subject(cert));
270 auth->add(auth, AUTH_HELPER_SUBJECT_CERT, cert);
271 first = FALSE;
272 }
273 else
274 {
275 DBG1(DBG_IKE, "received issuer cert \"%Y\"",
276 cert->get_subject(cert));
277 auth->add(auth, AUTH_HELPER_IM_CERT, cert);
278 }
279 }
280 else if (encoding == ENC_X509_HASH_AND_URL)
281 {
282 /* we fetch the certificate not yet, but only if
283 * it is really needed during authentication */
284 url = cert_payload->get_url(cert_payload);
285 if (!url)
286 {
287 DBG1(DBG_IKE, "received invalid hash-and-url "
288 "encoded cert, ignore");
289 break;
290 }
291 url = strdup(url);
292 if (first)
293 { /* first URL is for an end entity certificate */
294 DBG1(DBG_IKE, "received hash-and-url for end"
295 " entity cert \"%s\"", url);
296 auth->add(auth, AUTH_HELPER_SUBJECT_HASH_URL, url);
297 first = FALSE;
298 }
299 else
300 {
301 DBG1(DBG_IKE, "received hash-and-url for issuer"
302 " cert \"%s\"", url);
303 auth->add(auth, AUTH_HELPER_IM_HASH_URL, url);
304 }
305 }
306 break;
307 }
308 case ENC_CRL:
309 cert = cert_payload->get_cert(cert_payload);
310 if (cert)
311 {
312 DBG1(DBG_IKE, "received CRL \"%Y\"",
313 cert->get_subject(cert));
314 auth->add(auth, AUTH_HELPER_REVOCATION_CERT, cert);
315 }
316 break;
317 case ENC_PKCS7_WRAPPED_X509:
318 case ENC_PGP:
319 case ENC_DNS_SIGNED_KEY:
320 case ENC_KERBEROS_TOKEN:
321 case ENC_ARL:
322 case ENC_SPKI:
323 case ENC_X509_ATTRIBUTE:
324 case ENC_RAW_RSA_KEY:
325 case ENC_X509_HASH_AND_URL_BUNDLE:
326 case ENC_OCSP_CONTENT:
327 default:
328 DBG1(DBG_ENC, "certificate encoding %N not supported",
329 cert_encoding_names, encoding);
330 }
331 }
332 }
333 enumerator->destroy(enumerator);
334 }
335
336 /**
337 * add the keyid of a certificate to the certificate request payload
338 */
339 static void add_certreq(private_ike_cert_pre_t *this,
340 certreq_payload_t **req, certificate_t *cert)
341 {
342 switch (cert->get_type(cert))
343 {
344 case CERT_X509:
345 {
346 public_key_t *public;
347 chunk_t keyid;
348 x509_t *x509 = (x509_t*)cert;
349
350 if (!(x509->get_flags(x509) & X509_CA))
351 { /* no CA cert, skip */
352 break;
353 }
354 public = cert->get_public_key(cert);
355 if (!public)
356 {
357 break;
358 }
359 if (*req == NULL)
360 {
361 *req = certreq_payload_create_type(CERTIFICATE_REQUEST, CERT_X509);
362 }
363 if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &keyid))
364 {
365 (*req)->add_keyid(*req, keyid);
366 DBG1(DBG_IKE, "sending cert request for \"%Y\"",
367 cert->get_subject(cert));
368 }
369 public->destroy(public);
370 break;
371 }
372 default:
373 break;
374 }
375 }
376
377 /**
378 * Add the subject of a CA certificate a message
379 */
380 static void add_certreq_v1(private_ike_cert_pre_t *this,
381 message_t *message, certificate_t *cert)
382 {
383 switch (cert->get_type(cert))
384 {
385 case CERT_X509:
386 {
387 x509_t *x509 = (x509_t*)cert;
388 identification_t *id;
389 certreq_payload_t *req;
390
391 if (!(x509->get_flags(x509) & X509_CA))
392 { /* no CA cert, skip */
393 break;
394 }
395 req = certreq_payload_create_type(CERTIFICATE_REQUEST_V1, CERT_X509);
396 id = cert->get_subject(cert);
397 req->set_dn(req, id->get_encoding(id));
398 DBG1(DBG_IKE, "sending cert request for \"%Y\"",
399 cert->get_subject(cert));
400 message->add_payload(message, &req->payload_interface);
401 break;
402 }
403 default:
404 break;
405 }
406 }
407
408 /**
409 * add a auth_cfg's CA certificates to the certificate request
410 */
411 static void add_certreqs(private_ike_cert_pre_t *this,
412 certreq_payload_t **req, auth_cfg_t *auth)
413 {
414 enumerator_t *enumerator;
415 auth_rule_t type;
416 void *value;
417
418 enumerator = auth->create_enumerator(auth);
419 while (enumerator->enumerate(enumerator, &type, &value))
420 {
421 switch (type)
422 {
423 case AUTH_RULE_CA_CERT:
424 add_certreq(this, req, (certificate_t*)value);
425 break;
426 default:
427 break;
428 }
429 }
430 enumerator->destroy(enumerator);
431 }
432
433 /**
434 * add a auth_cfg's CA certificates to the certificate request
435 */
436 static void add_certreqs_v1(private_ike_cert_pre_t *this,
437 auth_cfg_t *auth, message_t *message)
438 {
439 enumerator_t *enumerator;
440 auth_rule_t type;
441 void *value;
442
443 enumerator = auth->create_enumerator(auth);
444 while (enumerator->enumerate(enumerator, &type, &value))
445 {
446 switch (type)
447 {
448 case AUTH_RULE_CA_CERT:
449 add_certreq_v1(this, message, (certificate_t*)value);
450 break;
451 default:
452 break;
453 }
454 }
455 enumerator->destroy(enumerator);
456 }
457
458 /**
459 * build certificate requests
460 */
461 static void build_certreqs(private_ike_cert_pre_t *this, message_t *message)
462 {
463 enumerator_t *enumerator;
464 ike_cfg_t *ike_cfg;
465 peer_cfg_t *peer_cfg;
466 certificate_t *cert;
467 auth_cfg_t *auth;
468 certreq_payload_t *req = NULL;
469
470 ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
471 if (!ike_cfg->send_certreq(ike_cfg))
472 {
473 return;
474 }
475
476 /* check if we require a specific CA for that peer */
477 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
478 if (peer_cfg)
479 {
480 enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, FALSE);
481 while (enumerator->enumerate(enumerator, &auth))
482 {
483 add_certreqs(this, &req, auth);
484 }
485 enumerator->destroy(enumerator);
486 }
487
488 if (!req)
489 {
490 /* otherwise add all trusted CA certificates */
491 enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
492 CERT_ANY, KEY_ANY, NULL, TRUE);
493 while (enumerator->enumerate(enumerator, &cert))
494 {
495 add_certreq(this, &req, cert);
496 }
497 enumerator->destroy(enumerator);
498 }
499
500 if (req)
501 {
502 message->add_payload(message, (payload_t*)req);
503
504 if (lib->settings->get_bool(lib->settings, "charon.hash_and_url", FALSE))
505 {
506 message->add_notify(message, FALSE, HTTP_CERT_LOOKUP_SUPPORTED,
507 chunk_empty);
508 this->do_http_lookup = TRUE;
509 }
510 }
511 }
512
513 /**
514 * build certificate requests
515 */
516 static void build_certreqs_v1(private_ike_cert_pre_t *this, message_t *message)
517 {
518 enumerator_t *enumerator;
519 ike_cfg_t *ike_cfg;
520 peer_cfg_t *peer_cfg;
521 certificate_t *cert;
522 auth_cfg_t *auth;
523
524 ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
525 if (!ike_cfg->send_certreq(ike_cfg))
526 {
527 return;
528 }
529
530 /* check if we require a specific CA for that peer */
531 /* Get the first authentcation config from peer config */
532 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
533 if (peer_cfg)
534 {
535 enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, FALSE);
536 if (enumerator->enumerate(enumerator, &auth))
537 {
538 add_certreqs_v1(this, auth, message);
539 }
540 enumerator->destroy(enumerator);
541 }
542
543 if (!message->get_payload(message, CERTIFICATE_REQUEST_V1))
544 {
545 /* otherwise add all trusted CA certificates */
546 enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
547 CERT_ANY, KEY_ANY, NULL, TRUE);
548 while (enumerator->enumerate(enumerator, &cert))
549 {
550 add_certreq_v1(this, message, cert);
551 }
552 enumerator->destroy(enumerator);
553 }
554 }
555
556 /**
557 * Check if this is the final authentication round
558 */
559 static bool final_auth(message_t *message)
560 {
561 /* we check for an AUTH payload without a ANOTHER_AUTH_FOLLOWS notify */
562 if (message->get_payload(message, AUTHENTICATION) == NULL)
563 {
564 return FALSE;
565 }
566 if (message->get_notify(message, ANOTHER_AUTH_FOLLOWS))
567 {
568 return FALSE;
569 }
570 return TRUE;
571 }
572
573 /**
574 * Checks for the auth_method to see if this task should handle certificates.
575 * (IKEv1 only)
576 */
577 static status_t check_auth_method(private_ike_cert_pre_t *this,
578 message_t *message)
579 {
580 enumerator_t *enumerator;
581 payload_t *payload;
582 status_t status = SUCCESS;
583
584 enumerator = message->create_payload_enumerator(message);
585 while (enumerator->enumerate(enumerator, &payload))
586 {
587 if (payload->get_type(payload) == SECURITY_ASSOCIATION_V1)
588 {
589 sa_payload_t *sa_payload = (sa_payload_t*)payload;
590
591 switch (sa_payload->get_auth_method(sa_payload))
592 {
593 case AUTH_RSA:
594 case AUTH_XAUTH_INIT_RSA:
595 case AUTH_XAUTH_RESP_RSA:
596 DBG3(DBG_IKE, "handling certs method (%d)",
597 sa_payload->get_auth_method(sa_payload));
598 status = NEED_MORE;
599 break;
600 default:
601 DBG3(DBG_IKE, "not handling certs method (%d)",
602 sa_payload->get_auth_method(sa_payload));
603 status = SUCCESS;
604 break;
605 }
606
607 this->state = CP_SA;
608 break;
609 }
610 }
611 enumerator->destroy(enumerator);
612
613 if (status != NEED_MORE)
614 {
615 this->state = CP_NO_CERT;
616 this->final = TRUE;
617 }
618
619 return status;
620 }
621
622 METHOD(task_t, build_i, status_t,
623 private_ike_cert_pre_t *this, message_t *message)
624 {
625 if (message->get_message_id(message) == 1)
626 { /* initiator sends CERTREQs in first IKE_AUTH */
627 build_certreqs(this, message);
628 }
629 return NEED_MORE;
630 }
631
632 METHOD(task_t, process_r, status_t,
633 private_ike_cert_pre_t *this, message_t *message)
634 {
635 if (message->get_exchange_type(message) != IKE_SA_INIT)
636 { /* handle certreqs/certs in any IKE_AUTH, just in case */
637 process_certreqs(this, message);
638 process_certs(this, message);
639 }
640 this->final = final_auth(message);
641 return NEED_MORE;
642 }
643
644 METHOD(task_t, build_r, status_t,
645 private_ike_cert_pre_t *this, message_t *message)
646 {
647 if (message->get_exchange_type(message) == IKE_SA_INIT)
648 {
649 build_certreqs(this, message);
650 }
651 if (this->final)
652 {
653 return SUCCESS;
654 }
655 return NEED_MORE;
656 }
657
658 METHOD(task_t, process_i, status_t,
659 private_ike_cert_pre_t *this, message_t *message)
660 {
661 if (message->get_exchange_type(message) == IKE_SA_INIT)
662 {
663 process_certreqs(this, message);
664 }
665 process_certs(this, message);
666
667 if (final_auth(message))
668 {
669 return SUCCESS;
670 }
671 return NEED_MORE;
672 }
673
674 METHOD(task_t, process_r_v1, status_t,
675 private_ike_cert_pre_t *this, message_t *message)
676 {
677 switch (message->get_exchange_type(message))
678 {
679 case ID_PROT:
680 {
681 switch (this->state)
682 {
683 case CP_INIT:
684 check_auth_method(this, message);
685 break;
686 case CP_SA:
687 process_certreqs(this, message);
688 this->state = CP_SA_POST;
689 break;
690 case CP_SA_POST:
691 process_certreqs(this, message);
692 process_certs(this, message);
693 this->state = CP_REQ_SENT;
694 this->final = TRUE;
695 break;
696 default:
697 break;
698 }
699 break;
700 }
701 case AGGRESSIVE:
702 {
703 if (check_auth_method(this, message) == NEED_MORE)
704 {
705 process_certreqs(this, message);
706 process_certs(this, message);
707 }
708 this->final = TRUE;
709 break;
710 }
711 default:
712 break;
713 }
714
715 return NEED_MORE;
716 }
717
718 METHOD(task_t, process_i_v1, status_t,
719 private_ike_cert_pre_t *this, message_t *message)
720 {
721 /* TODO: */
722 return FAILED;
723 }
724
725 METHOD(task_t, build_r_v1, status_t,
726 private_ike_cert_pre_t *this, message_t *message)
727 {
728
729 switch (message->get_exchange_type(message))
730 {
731 case ID_PROT:
732 {
733 if (this->state == CP_SA_POST)
734 {
735 build_certreqs_v1(this, message);
736 }
737 break;
738 }
739 case AGGRESSIVE:
740 {
741 if (this->state != CP_NO_CERT)
742 {
743 build_certreqs_v1(this, message);
744 }
745 }
746 default:
747 break;
748
749 }
750
751 if (this->final)
752 {
753 return SUCCESS;
754 }
755 return NEED_MORE;
756 }
757
758 METHOD(task_t, build_i_v1, status_t,
759 private_ike_cert_pre_t *this, message_t *message)
760 {
761 /* TODO: */
762 return FAILED;
763 }
764
765 METHOD(task_t, get_type, task_type_t,
766 private_ike_cert_pre_t *this)
767 {
768 return TASK_IKE_CERT_PRE;
769 }
770
771 METHOD(task_t, migrate, void,
772 private_ike_cert_pre_t *this, ike_sa_t *ike_sa)
773 {
774 this->ike_sa = ike_sa;
775 }
776
777 METHOD(task_t, destroy, void,
778 private_ike_cert_pre_t *this)
779 {
780 free(this);
781 }
782
783 /*
784 * Described in header.
785 */
786 ike_cert_pre_t *ike_cert_pre_create(ike_sa_t *ike_sa, bool initiator)
787 {
788 private_ike_cert_pre_t *this;
789
790 INIT(this,
791 .public = {
792 .task = {
793 .get_type = _get_type,
794 .migrate = _migrate,
795 .destroy = _destroy,
796 },
797 },
798 .ike_sa = ike_sa,
799 .initiator = initiator,
800 );
801
802 if (ike_sa->get_version(ike_sa) == IKEV2)
803 {
804 if (initiator)
805 {
806 this->public.task.build = _build_i;
807 this->public.task.process = _process_i;
808 }
809 else
810 {
811 this->public.task.build = _build_r;
812 this->public.task.process = _process_r;
813 }
814 this->cert_req_payload_type = CERTIFICATE_REQUEST;
815 }
816 else
817 {
818 this->state = CP_INIT;
819 if (initiator)
820 {
821 this->public.task.build = _build_i_v1;
822 this->public.task.process = _process_i_v1;
823 }
824 else
825 {
826 this->public.task.build = _build_r_v1;
827 this->public.task.process = _process_r_v1;
828 }
829 this->cert_req_payload_type = CERTIFICATE_REQUEST_V1;
830
831 }
832
833 return &this->public;
834 }