2 * Copyright (C) 2011 Martin Willi
4 * Copyright (C) secunet Security Networks AG
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>.
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
17 #include "isakmp_cert_post.h"
20 #include <sa/ike_sa.h>
21 #include <encoding/payloads/cert_payload.h>
22 #include <encoding/payloads/certreq_payload.h>
23 #include <encoding/payloads/auth_payload.h>
24 #include <encoding/payloads/sa_payload.h>
25 #include <credentials/certificates/x509.h>
28 typedef struct private_isakmp_cert_post_t private_isakmp_cert_post_t
;
31 * Private members of a isakmp_cert_post_t task.
33 struct private_isakmp_cert_post_t
{
36 * Public methods and task_t interface.
38 isakmp_cert_post_t
public;
46 * Are we the initiator?
51 * States of ike cert pre
61 * Check if we actually use certificates for authentication
63 static bool use_certs(private_isakmp_cert_post_t
*this, message_t
*message
)
65 enumerator_t
*enumerator
;
69 enumerator
= message
->create_payload_enumerator(message
);
70 while (enumerator
->enumerate(enumerator
, &payload
))
72 if (payload
->get_type(payload
) == PLV1_SECURITY_ASSOCIATION
)
74 sa_payload_t
*sa_payload
= (sa_payload_t
*)payload
;
76 switch (sa_payload
->get_auth_method(sa_payload
))
82 case AUTH_XAUTH_INIT_RSA
:
83 case AUTH_XAUTH_RESP_RSA
:
84 case AUTH_HYBRID_INIT_RSA
:
85 case AUTH_HYBRID_RESP_RSA
:
94 enumerator
->destroy(enumerator
);
100 * Add certificates to message
102 static void build_certs(private_isakmp_cert_post_t
*this, message_t
*message
)
104 peer_cfg_t
*peer_cfg
;
106 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
112 switch (peer_cfg
->get_cert_policy(peer_cfg
))
114 case CERT_NEVER_SEND
:
116 case CERT_SEND_IF_ASKED
:
117 if (!this->ike_sa
->has_condition(this->ike_sa
, COND_CERTREQ_SEEN
))
122 case CERT_ALWAYS_SEND
:
124 cert_payload_t
*payload
;
125 enumerator_t
*enumerator
;
130 auth
= this->ike_sa
->get_auth_cfg(this->ike_sa
, TRUE
);
131 cert
= auth
->get(auth
, AUTH_RULE_SUBJECT_CERT
);
136 payload
= cert_payload_create_from_cert(PLV1_CERTIFICATE
, cert
);
141 DBG1(DBG_IKE
, "sending end entity cert \"%Y\"",
142 cert
->get_subject(cert
));
143 message
->add_payload(message
, (payload_t
*)payload
);
145 enumerator
= auth
->create_enumerator(auth
);
146 while (enumerator
->enumerate(enumerator
, &type
, &cert
))
148 if (type
== AUTH_RULE_IM_CERT
)
150 payload
= cert_payload_create_from_cert(PLV1_CERTIFICATE
, cert
);
153 DBG1(DBG_IKE
, "sending issuer cert \"%Y\"",
154 cert
->get_subject(cert
));
155 message
->add_payload(message
, (payload_t
*)payload
);
159 enumerator
->destroy(enumerator
);
164 METHOD(task_t
, build_i
, status_t
,
165 private_isakmp_cert_post_t
*this, message_t
*message
)
167 switch (message
->get_exchange_type(message
))
170 if (this->state
== CR_AUTH
)
172 build_certs(this, message
);
177 if (this->state
== CR_AUTH
)
179 build_certs(this, message
);
188 METHOD(task_t
, process_r
, status_t
,
189 private_isakmp_cert_post_t
*this, message_t
*message
)
191 switch (message
->get_exchange_type(message
))
198 if (!use_certs(this, message
))
216 if (!use_certs(this, message
))
232 METHOD(task_t
, build_r
, status_t
,
233 private_isakmp_cert_post_t
*this, message_t
*message
)
235 switch (message
->get_exchange_type(message
))
244 this->state
= CR_AUTH
;
247 build_certs(this, message
);
254 build_certs(this, message
);
255 this->state
= CR_AUTH
;
267 METHOD(task_t
, process_i
, status_t
,
268 private_isakmp_cert_post_t
*this, message_t
*message
)
270 switch (message
->get_exchange_type(message
))
277 if (!use_certs(this, message
))
284 this->state
= CR_AUTH
;
294 if (this->state
== CR_SA
)
296 if (!use_certs(this, message
))
300 this->state
= CR_AUTH
;
310 METHOD(task_t
, get_type
, task_type_t
,
311 private_isakmp_cert_post_t
*this)
313 return TASK_ISAKMP_CERT_POST
;
316 METHOD(task_t
, migrate
, void,
317 private_isakmp_cert_post_t
*this, ike_sa_t
*ike_sa
)
319 this->ike_sa
= ike_sa
;
323 METHOD(task_t
, destroy
, void,
324 private_isakmp_cert_post_t
*this)
330 * Described in header.
332 isakmp_cert_post_t
*isakmp_cert_post_create(ike_sa_t
*ike_sa
, bool initiator
)
334 private_isakmp_cert_post_t
*this;
339 .get_type
= _get_type
,
345 .initiator
= initiator
,
350 this->public.task
.process
= _process_i
;
351 this->public.task
.build
= _build_i
;
355 this->public.task
.process
= _process_r
;
356 this->public.task
.build
= _build_r
;
358 return &this->public;