From 6d3e7a64a0f69f1581983fa7d741257268049620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20R=C3=BCmelin?= Date: Thu, 10 Jan 2013 21:27:20 +0100 Subject: [PATCH] IKEv1 support for PKCS#7 wrapped certificates --- .../encoding/payloads/cert_payload.c | 18 +++++ .../encoding/payloads/cert_payload.h | 8 +++ .../sa/ikev1/tasks/isakmp_cert_pre.c | 70 +++++++++++++++++++ 3 files changed, 96 insertions(+) diff --git a/src/libcharon/encoding/payloads/cert_payload.c b/src/libcharon/encoding/payloads/cert_payload.c index 3a230b91e..a32f5705d 100644 --- a/src/libcharon/encoding/payloads/cert_payload.c +++ b/src/libcharon/encoding/payloads/cert_payload.c @@ -234,6 +234,23 @@ METHOD(cert_payload_t, get_cert, certificate_t*, BUILD_BLOB_ASN1_DER, this->data, BUILD_END); } +METHOD(cert_payload_t, get_container, container_t*, + private_cert_payload_t *this) +{ + int type; + + switch (this->encoding) + { + case ENC_PKCS7_WRAPPED_X509: + type = CONTAINER_PKCS7; + break; + default: + return NULL; + } + return lib->creds->create(lib->creds, CRED_CONTAINER, type, + BUILD_BLOB_ASN1_DER, this->data, BUILD_END); +} + METHOD(cert_payload_t, get_hash, chunk_t, private_cert_payload_t *this) { @@ -289,6 +306,7 @@ cert_payload_t *cert_payload_create(payload_type_t type) .destroy = _destroy, }, .get_cert = _get_cert, + .get_container = _get_container, .get_cert_encoding = _get_cert_encoding, .get_hash = _get_hash, .get_url = _get_url, diff --git a/src/libcharon/encoding/payloads/cert_payload.h b/src/libcharon/encoding/payloads/cert_payload.h index 768afbbdb..834f35d60 100644 --- a/src/libcharon/encoding/payloads/cert_payload.h +++ b/src/libcharon/encoding/payloads/cert_payload.h @@ -28,6 +28,7 @@ typedef enum cert_encoding_t cert_encoding_t; #include #include +#include #include /** @@ -71,6 +72,13 @@ struct cert_payload_t { */ certificate_t *(*get_cert)(cert_payload_t *this); + /** + * Get the payloads certificate container. + * + * @return container copy + */ + container_t *(*get_container)(cert_payload_t *this); + /** * Get the encoding of the certificate. * diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c b/src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c index 3282ed933..17279ea07 100644 --- a/src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c +++ b/src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c @@ -13,6 +13,28 @@ * for more details. */ +/* + * Copyright (C) 2013 Volker RĂ¼melin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "isakmp_cert_pre.h" #include @@ -21,6 +43,7 @@ #include #include #include +#include typedef struct private_isakmp_cert_pre_t private_isakmp_cert_pre_t; @@ -188,6 +211,53 @@ static void process_certs(private_isakmp_cert_pre_t *this, message_t *message) } break; case ENC_PKCS7_WRAPPED_X509: + { + container_t *container; + + container = cert_payload->get_container(cert_payload); + if (container) + { + pkcs7_t *pkcs7; + enumerator_t *enumerator; + + pkcs7 = (pkcs7_t *)container; + enumerator = pkcs7->create_cert_enumerator(pkcs7); + while (enumerator->enumerate(enumerator, &cert)) + { + if (cert->get_type(cert) == CERT_X509) + { + auth_rule_t rule; + x509_t *x509 = (x509_t*)cert; + + if (x509->get_flags(x509) & X509_CA) + { + DBG1(DBG_IKE, + "received intermediate ca cert \"%Y\"", + cert->get_subject(cert)); + rule = AUTH_HELPER_IM_CERT; + } + else + { + DBG1(DBG_IKE, + "received end entity cert \"%Y\"", + cert->get_subject(cert)); + rule = AUTH_HELPER_SUBJECT_CERT; + } + auth->add(auth, rule, cert->get_ref(cert)); + } + else + { + DBG1(DBG_IKE, + "received unsupported cert type %N", + certificate_type_names, + cert->get_type(cert)); + } + } + enumerator->destroy(enumerator); + container->destroy(container); + } + break; + } case ENC_PGP: case ENC_DNS_SIGNED_KEY: case ENC_KERBEROS_TOKEN: