59
62
static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
64
enumerator_t *enumerator;
62
65
payload_t *payload;
64
bool ca_found = FALSE;
66
auth = this->ike_sa->get_my_auth(this->ike_sa);
68
iterator = message->get_payload_iterator(message);
69
while (iterator->iterate(iterator, (void**)&payload))
68
auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
70
enumerator = message->create_payload_enumerator(message);
71
while (enumerator->enumerate(enumerator, &payload))
71
73
switch(payload->get_type(payload))
73
75
case CERTIFICATE_REQUEST:
75
77
certreq_payload_t *certreq = (certreq_payload_t*)payload;
78
enumerator_t *enumerator;
77
enumerator_t *enumerator;
79
81
this->ike_sa->set_condition(this->ike_sa, COND_CERTREQ_SEEN, TRUE);
96
98
CERT_X509, KEY_ANY, id, TRUE);
99
DBG1(DBG_IKE, "received cert request for \"%D\"",
101
DBG1(DBG_IKE, "received cert request for \"%Y\"",
100
102
cert->get_subject(cert));
101
auth->add_item(auth, AUTHN_CA_CERT, cert);
103
auth->add(auth, AUTH_RULE_CA_CERT, cert);
107
107
DBG1(DBG_IKE, "received cert request for unknown ca "
108
"with keyid %D", id);
109
auth->add_item(auth, AUTHN_CA_CERT_KEYID, id);
108
"with keyid %Y", id);
176
176
static void process_certs(private_ike_cert_pre_t *this, message_t *message)
178
iterator_t *iterator;
178
enumerator_t *enumerator;
179
179
payload_t *payload;
181
181
bool first = TRUE;
183
auth = this->ike_sa->get_other_auth(this->ike_sa);
183
auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
185
iterator = message->get_payload_iterator(message);
186
while (iterator->iterate(iterator, (void**)&payload))
185
enumerator = message->create_payload_enumerator(message);
186
while (enumerator->enumerate(enumerator, &payload))
188
188
if (payload->get_type(payload) == CERTIFICATE)
190
cert_payload_t *cert_payload = (cert_payload_t*)payload;
191
cert_encoding_t type = cert_payload->get_cert_encoding(cert_payload);
190
cert_payload_t *cert_payload;
191
cert_encoding_t encoding;
195
cert_payload = (cert_payload_t*)payload;
196
encoding = cert_payload->get_cert_encoding(cert_payload);
194
case ENC_X509_SIGNATURE:
195
200
case ENC_X509_HASH_AND_URL:
197
if (type == ENC_X509_HASH_AND_URL &&
198
!this->http_cert_lookup_supported_sent)
202
if (!this->do_http_lookup)
200
204
DBG1(DBG_IKE, "received hash-and-url encoded cert, but"
201
205
" we don't accept them, ignore");
205
certificate_t *cert = try_get_cert(cert_payload);
210
case ENC_X509_SIGNATURE:
212
cert = try_get_cert(cert_payload);
209
/* we've got a certificate from the payload or the cache */
211
{ /* the first certificate MUST be an end entity one */
212
DBG1(DBG_IKE, "received end entity cert \"%D\"",
216
{ /* the first is an end entity certificate */
217
DBG1(DBG_IKE, "received end entity cert \"%Y\"",
213
218
cert->get_subject(cert));
214
auth->add_item(auth, AUTHN_SUBJECT_CERT, cert);
219
auth->add(auth, AUTH_HELPER_SUBJECT_CERT, cert);
219
DBG1(DBG_IKE, "received issuer cert \"%D\"",
224
DBG1(DBG_IKE, "received issuer cert \"%Y\"",
220
225
cert->get_subject(cert));
221
auth->add_item(auth, AUTHN_IM_CERT, cert);
226
auth->add(auth, AUTH_HELPER_IM_CERT, cert);
225
else if (type == ENC_X509_HASH_AND_URL)
229
else if (encoding == ENC_X509_HASH_AND_URL)
227
/* we received a "Hash and URL" encoded certificate that
228
* we haven't fetched yet, we store the URL and fetch
230
char *url = cert_payload->get_url(cert_payload);
231
/* we fetch the certificate not yet, but only if
232
* it is really needed during authentication */
233
url = cert_payload->get_url(cert_payload);
233
DBG1(DBG_IKE, "received invalid hash-and-url encoded"
236
DBG1(DBG_IKE, "received invalid hash-and-url "
237
"encoded cert, ignore");
239
{ /* the first certificate MUST be an end entity one */
242
{ /* first URL is for an end entity certificate */
240
243
DBG1(DBG_IKE, "received hash-and-url for end"
241
" entity cert \"%s\"", url);
242
auth->add_item(auth, AUTHN_SUBJECT_HASH_URL, url);
244
" entity cert \"%s\"", url);
245
auth->add(auth, AUTH_HELPER_SUBJECT_HASH_URL, url);
247
250
DBG1(DBG_IKE, "received hash-and-url for issuer"
248
251
" cert \"%s\"", url);
249
auth->add_item(auth, AUTHN_IM_HASH_URL, url);
252
auth->add(auth, AUTH_HELPER_IM_HASH_URL, url);
264
267
case ENC_OCSP_CONTENT:
266
269
DBG1(DBG_ENC, "certificate encoding %N not supported",
267
cert_encoding_names, cert_payload->get_cert_encoding(cert_payload));
270
cert_encoding_names, encoding);
271
iterator->destroy(iterator);
274
enumerator->destroy(enumerator);
275
* add a certificate request to the message, building request payload if required.
278
* add the keyid of a certificate to the certificate request payload
277
static void add_certreq_payload(message_t *message, certreq_payload_t **reqp,
280
static void add_certreq(certreq_payload_t **req, certificate_t *cert)
280
public_key_t *public;
281
certreq_payload_t *req;
283
public = cert->get_public_key(cert);
288
282
switch (cert->get_type(cert))
286
public_key_t *public;
292
287
identification_t *keyid;
293
288
x509_t *x509 = (x509_t*)cert;
296
291
{ /* no CA cert, skip */
301
*reqp = certreq_payload_create_type(CERT_X509);
302
message->add_payload(message, (payload_t*)*reqp);
294
public = cert->get_public_key(cert);
301
*req = certreq_payload_create_type(CERT_X509);
305
303
keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
306
req->add_keyid(req, keyid->get_encoding(keyid));
307
DBG1(DBG_IKE, "sending cert request for \"%D\"",
304
(*req)->add_keyid(*req, keyid->get_encoding(keyid));
305
public->destroy(public);
306
DBG1(DBG_IKE, "sending cert request for \"%Y\"",
308
307
cert->get_subject(cert));
314
public->destroy(public);
316
* add a auth_cfg's CA certificates to the certificate request
318
static void add_certreqs(certreq_payload_t **req, auth_cfg_t *auth)
320
enumerator_t *enumerator;
324
enumerator = auth->create_enumerator(auth);
325
while (enumerator->enumerate(enumerator, &type, &value))
329
case AUTH_RULE_CA_CERT:
330
add_certreq(req, (certificate_t*)value);
336
enumerator->destroy(enumerator);
320
342
static void build_certreqs(private_ike_cert_pre_t *this, message_t *message)
344
enumerator_t *enumerator;
322
345
ike_cfg_t *ike_cfg;
323
346
peer_cfg_t *peer_cfg;
324
enumerator_t *enumerator;
325
347
certificate_t *cert;
326
bool restricted = FALSE;
327
certreq_payload_t *x509_req = NULL;
349
certreq_payload_t *req = NULL;
329
351
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
330
352
if (!ike_cfg->send_certreq(ike_cfg))
335
357
/* check if we require a specific CA for that peer */
336
358
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
340
identification_t *id;
342
auth_info_t *auth = peer_cfg->get_auth(peer_cfg);
343
enumerator_t *auth_enumerator = auth->create_item_enumerator(auth);
345
while (auth_enumerator->enumerate(auth_enumerator, &item, &ptr))
361
enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, FALSE);
362
while (enumerator->enumerate(enumerator, &auth))
350
cert = (certificate_t *)ptr;
351
add_certreq_payload(message, &x509_req, cert);
354
case AUTHZ_CA_CERT_NAME:
355
id = (identification_t *)ptr;
356
enumerator = charon->credentials->create_cert_enumerator(
357
charon->credentials, CERT_ANY, KEY_ANY, id, TRUE);
358
while (enumerator->enumerate(enumerator, &cert, TRUE))
360
add_certreq_payload(message, &x509_req, cert);
363
enumerator->destroy(enumerator);
364
add_certreqs(&req, auth);
369
auth_enumerator->destroy(auth_enumerator);
366
enumerator->destroy(enumerator);
374
/* otherwise include all trusted CA certificates */
371
/* otherwise add all trusted CA certificates */
375
372
enumerator = charon->credentials->create_cert_enumerator(
376
373
charon->credentials, CERT_ANY, KEY_ANY, NULL, TRUE);
377
while (enumerator->enumerate(enumerator, &cert, TRUE))
374
while (enumerator->enumerate(enumerator, &cert))
379
add_certreq_payload(message, &x509_req, cert);
376
add_certreq(&req, cert);
381
378
enumerator->destroy(enumerator);
384
/* if we've added at least one certreq, we notify our peer that we support
385
* "Hash and URL" for the requested certificates */
386
if (lib->settings->get_bool(lib->settings, "charon.hash_and_url", FALSE) &&
387
message->get_payload(message, CERTIFICATE_REQUEST))
389
message->add_notify(message, FALSE, HTTP_CERT_LOOKUP_SUPPORTED, chunk_empty);
390
this->http_cert_lookup_supported_sent = TRUE;
383
message->add_payload(message, (payload_t*)req);
385
if (lib->settings->get_bool(lib->settings, "charon.hash_and_url", FALSE))
387
message->add_notify(message, FALSE, HTTP_CERT_LOOKUP_SUPPORTED,
389
this->do_http_lookup = TRUE;
395
* Check if this is the final authentication round
397
static bool final_auth(message_t *message)
399
enumerator_t *enumerator;
401
notify_payload_t *notify;
403
/* we check for an AUTH payload without a ANOTHER_AUTH_FOLLOWS notify */
404
if (message->get_payload(message, AUTHENTICATION) == NULL)
408
enumerator = message->create_payload_enumerator(message);
409
while (enumerator->enumerate(enumerator, &payload))
411
if (payload->get_type(payload) == NOTIFY)
413
notify = (notify_payload_t*)payload;
414
if (notify->get_notify_type(notify) == ANOTHER_AUTH_FOLLOWS)
416
enumerator->destroy(enumerator);
421
enumerator->destroy(enumerator);
408
438
* Implementation of task_t.process for responder
410
440
static status_t process_r(private_ike_cert_pre_t *this, message_t *message)
412
if (message->get_exchange_type(message) == IKE_SA_INIT)
442
if (message->get_exchange_type(message) != IKE_SA_INIT)
443
{ /* handle certreqs/certs in any IKE_AUTH, just in case */
444
process_certreqs(this, message);
445
process_certs(this, message);
416
process_certreqs(this, message);
417
process_certs(this, message);
447
this->final = final_auth(message);
418
448
return NEED_MORE;