1
/* Support of X.509 keys
2
* Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
3
* Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
4
* Copyright (C) 2002 Mario Strasser
5
* Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
6
* Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
8
* This program is free software; you can redistribute it and/or modify it
9
* under the terms of the GNU General Public License as published by the
10
* Free Software Foundation; either version 2 of the License, or (at your
11
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13
* This program is distributed in the hope that it will be useful, but
14
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18
* RCSID $Id: x509keys.c,v 1.4 2004/06/27 22:42:14 mcr Exp $
27
#include <sys/types.h>
30
#include <openswan/ipsec_policy.h>
32
#include <sys/queue.h>
34
#include "constants.h"
47
#include "demux.h" /* needs packet.h */
48
#include "connections.h"
60
/* extract id and public key from x.509 certificate and
61
* insert it into a pubkeyrec
64
add_x509_public_key(x509cert_t *cert , time_t until
65
, enum dns_auth_level dns_auth_level)
69
cert_t c = { FALSE, CERT_X509_SIGNATURE, {cert} };
71
/* we support RSA only */
72
if (cert->subjectPublicKeyAlgorithm != PUBKEY_ALG_RSA) return;
74
/* ID type: ID_DER_ASN1_DN (X.509 subject field) */
75
pk = allocate_RSA_public_key(c);
77
pk->id.kind = ID_DER_ASN1_DN;
78
pk->id.name = cert->subject;
79
pk->dns_auth_level = dns_auth_level;
80
pk->until_time = until;
81
pk->issuer = cert->issuer;
82
delete_public_keys(&pk->id, pk->alg);
83
install_public_key(pk, &pubkeys);
85
gn = cert->subjectAltName;
87
while (gn != NULL) /* insert all subjectAltNames */
89
struct id id = empty_id;
92
if (id.kind != ID_NONE)
94
pk = allocate_RSA_public_key(c);
96
pk->dns_auth_level = dns_auth_level;
97
pk->until_time = until;
98
pk->issuer = cert->issuer;
99
delete_public_keys(&pk->id, pk->alg);
100
install_public_key(pk, &pubkeys);
107
/* when a X.509 certificate gets revoked, all instances of
108
* the corresponding public key must be removed
111
remove_x509_public_key(/*const*/ x509cert_t *cert)
113
const cert_t c = {FALSE, CERT_X509_SIGNATURE, {cert}};
114
struct pubkey_list *p, **pp;
115
struct pubkey *revoked_pk;
117
revoked_pk = allocate_RSA_public_key(c);
123
if (same_RSA_public_key(&p->key->u.rsa, &revoked_pk->u.rsa))
125
/* remove p from list and free memory */
126
*pp = free_public_keyentry(p);
127
loglog(RC_LOG_SERIOUS,
128
"invalid RSA public key deleted");
136
free_public_key(revoked_pk);
140
* Decode the CERT payload of Phase 1.
143
decode_cert(struct msg_digest *md)
145
struct payload_digest *p;
147
for (p = md->chain[ISAKMP_NEXT_CERT]; p != NULL; p = p->next)
149
struct isakmp_cert *const cert = &p->payload.cert;
152
blob.ptr = p->pbs.cur;
153
blob.len = pbs_left(&p->pbs);
154
if (cert->isacert_type == CERT_X509_SIGNATURE)
156
x509cert_t cert = empty_x509cert;
157
if (parse_x509cert(blob, 0, &cert))
159
if (verify_x509cert(&cert, strict_crl_policy, &valid_until))
161
DBG(DBG_X509 | DBG_PARSING,
162
DBG_log("Public key validated")
164
add_x509_public_key(&cert, valid_until, DAL_SIGNED);
168
plog("X.509 certificate rejected");
170
free_generalNames(cert.subjectAltName, FALSE);
171
free_generalNames(cert.crlDistributionPoints, FALSE);
174
plog("Syntax error in X.509 certificate");
176
else if (cert->isacert_type == CERT_PKCS7_WRAPPED_X509)
178
x509cert_t *cert = NULL;
180
if (parse_pkcs7_cert(blob, &cert))
181
store_x509certs(&cert, strict_crl_policy);
183
plog("Syntax error in PKCS#7 wrapped X.509 certificates");
187
loglog(RC_LOG_SERIOUS, "ignoring %s certificate payload",
188
enum_show(&cert_type_names, cert->isacert_type));
189
DBG_cond_dump_chunk(DBG_PARSING, "CERT:\n", blob);
195
* Decode the CR payload of Phase 1.
198
decode_cr(struct msg_digest *md, generalName_t **requested_ca)
200
struct payload_digest *p;
202
for (p = md->chain[ISAKMP_NEXT_CR]; p != NULL; p = p->next)
204
struct isakmp_cr *const cr = &p->payload.cr;
207
ca_name.len = pbs_left(&p->pbs);
208
ca_name.ptr = (ca_name.len > 0)? p->pbs.cur : NULL;
210
DBG_cond_dump_chunk(DBG_PARSING, "CR", ca_name);
212
if (cr->isacr_type == CERT_X509_SIGNATURE)
220
if (!is_asn1(ca_name))
223
gn = alloc_thing(generalName_t, "generalName");
224
clonetochunk(ca_name, ca_name.ptr,ca_name.len, "ca name");
225
gn->kind = GN_DIRECTORY_NAME;
227
gn->next = *requested_ca;
231
DBG(DBG_PARSING | DBG_CONTROL,
232
dntoa_or_null(buf, IDTOA_BUF, ca_name, "%any");
233
DBG_log("requested CA: '%s'", buf);
237
loglog(RC_LOG_SERIOUS, "ignoring %s certificate request payload",
238
enum_show(&cert_type_names, cr->isacr_type));
243
build_and_ship_CR(u_int8_t type, chunk_t ca, pb_stream *outs, u_int8_t np)
246
struct isakmp_cr cr_hd;
248
cr_hd.isacr_type = type;
250
/* build CR header */
251
if (!out_struct(&cr_hd, &isakmp_ipsec_cert_req_desc, outs, &cr_pbs))
256
/* build CR body containing the distinguished name of the CA */
257
if (!out_chunk(ca, &cr_pbs, "CA"))
260
close_output_pbs(&cr_pbs);
265
collect_rw_ca_candidates(struct msg_digest *md, generalName_t **top)
267
struct connection *d = find_host_connection(&md->iface->addr
268
, pluto_port, (ip_address*)NULL, md->sender_port);
270
for (; d != NULL; d = d->hp_next)
272
/* must be a road warrior connection */
273
if (d->kind == CK_TEMPLATE && !(d->policy & POLICY_OPPO)
274
&& d->spd.that.ca.ptr != NULL)
277
bool new_entry = TRUE;
279
for (gn = *top; gn != NULL; gn = gn->next)
281
if (same_dn(gn->name, d->spd.that.ca))
289
gn = alloc_thing(generalName_t, "generalName");
290
gn->kind = GN_DIRECTORY_NAME;
291
gn->name = d->spd.that.ca;