summaryrefslogtreecommitdiff
path: root/sbin/isakmpd/exchange.c
diff options
context:
space:
mode:
authorTom Cosgrove <tom@cvs.openbsd.org>2007-08-05 09:43:10 +0000
committerTom Cosgrove <tom@cvs.openbsd.org>2007-08-05 09:43:10 +0000
commitb687ea83cafbd4ecb3396f1d75f884a96dbeb57d (patch)
treec092261e5596669583fc4bcfb6685f21a42fbacc /sbin/isakmpd/exchange.c
parente8d5aeb04e626db42024da53ad97701ee69d3434 (diff)
Allow key exchange with RSA signature authentication to work with
Cisco IOS and other initiators that only send their certs in response to CERT_REQUEST. With input and help from cloder@, Stuart Henderson, mpf@, and several others who did lots of testing - thanks to all. ok hshoexer@
Diffstat (limited to 'sbin/isakmpd/exchange.c')
-rw-r--r--sbin/isakmpd/exchange.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/sbin/isakmpd/exchange.c b/sbin/isakmpd/exchange.c
index 1cce615e439..39d6242d790 100644
--- a/sbin/isakmpd/exchange.c
+++ b/sbin/isakmpd/exchange.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: exchange.c,v 1.130 2007/04/16 13:01:39 moritz Exp $ */
+/* $OpenBSD: exchange.c,v 1.131 2007/08/05 09:43:09 tom Exp $ */
/* $EOM: exchange.c,v 1.143 2000/12/04 00:02:25 angelos Exp $ */
/*
@@ -1593,6 +1593,8 @@ exchange_free_aca_list(struct exchange *exchange)
for (aca = TAILQ_FIRST(&exchange->aca_list); aca;
aca = TAILQ_FIRST(&exchange->aca_list)) {
+ if (aca->raw_ca)
+ free(aca->raw_ca);
if (aca->data) {
if (aca->handler)
aca->handler->free_aca(aca->data);
@@ -1603,6 +1605,58 @@ exchange_free_aca_list(struct exchange *exchange)
}
}
+/* Add any CERTREQs we should send. */
+int
+exchange_add_certreqs(struct message *msg)
+{
+ struct exchange *exchange = msg->exchange;
+ struct certreq_aca *aca;
+ u_int8_t *buf;
+
+ /*
+ * Some peers (e.g. Cisco IOS) won't send their cert unless we
+ * specifically ask beforehand with CERTREQ. We reflect any
+ * CERTREQs we receive from the initiator in order to do this.
+ * This avoids leaking information about which CAs we trust,
+ * and works in the most common case where both ends trust the
+ * same CA.
+ */
+ for (aca = TAILQ_FIRST(&exchange->aca_list); aca;
+ aca = TAILQ_NEXT(aca, link)) {
+
+ /* But only do this if we have at least one CA */
+ if (aca->handler != NULL && aca->handler->ca_count() == 0) {
+ LOG_DBG((LOG_EXCHANGE, 10,
+ "exchange_add_certreqs: no CA, so not "
+ "sending a CERTREQ"));
+ continue;
+ }
+
+ if (aca->raw_ca_len) {
+ buf = malloc(ISAKMP_CERTREQ_SZ + aca->raw_ca_len);
+ if (buf == NULL) {
+ log_error("exchange_add_certreqs: "
+ "malloc (%lu) failed",
+ ISAKMP_CERTREQ_SZ +
+ (unsigned long)aca->raw_ca_len);
+ return -1;
+ }
+
+ buf[ISAKMP_CERTREQ_TYPE_OFF] = aca->id;
+ memcpy(buf + ISAKMP_CERTREQ_AUTHORITY_OFF,
+ aca->raw_ca, aca->raw_ca_len);
+
+ if (message_add_payload(msg, ISAKMP_PAYLOAD_CERT_REQ,
+ buf, ISAKMP_CERTREQ_SZ + aca->raw_ca_len, 1)) {
+ free(buf);
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
/* Obtain certificates from acceptable certification authority. */
int
exchange_add_certs(struct message *msg)