summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>2000-10-07 07:00:35 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>2000-10-07 07:00:35 +0000
commit60046455c5367d063936733b0f78a78c2c0fcdc2 (patch)
tree2c3da6df15f2f99118e713dc3c9d509366e82429
parentdc768b3fb17c19383e55cdcea891752427321593 (diff)
Merge with EOM 1.43
author: niklas Multiple subject name matching, makes certificate interop with PGPnet at least partly working. Added some error checking. author: provos style as pointed out by the code style pedant. author: ho Compile without USE_KEYNOTE/USE_POLICY.
-rw-r--r--sbin/isakmpd/x509.c248
1 files changed, 160 insertions, 88 deletions
diff --git a/sbin/isakmpd/x509.c b/sbin/isakmpd/x509.c
index 38dfe318573..09ad1643e72 100644
--- a/sbin/isakmpd/x509.c
+++ b/sbin/isakmpd/x509.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: x509.c,v 1.28 2000/06/08 20:51:21 niklas Exp $ */
-/* $EOM: x509.c,v 1.40 2000/05/21 04:24:54 angelos Exp $ */
+/* $OpenBSD: x509.c,v 1.29 2000/10/07 07:00:34 niklas Exp $ */
+/* $EOM: x509.c,v 1.43 2000/09/28 12:53:27 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niels Provos. All rights reserved.
@@ -56,6 +56,7 @@
#include "sysdep.h"
+#include "cert.h"
#include "conf.h"
#include "dyn.h"
#include "exchange.h"
@@ -165,7 +166,7 @@ x509_generate_kn (X509 *cert)
{
log_print ("x509_generate_kn: "
"missing certificates, cannot construct X509 chain");
- free(ikey);
+ free (ikey);
return 0;
}
@@ -220,8 +221,18 @@ x509_generate_kn (X509 *cert)
}
free (buf);
- LC (X509_NAME_oneline, (issuer, isname, 256));
- LC (X509_NAME_oneline, (subject, subname, 256));
+ if (!LC (X509_NAME_oneline, (issuer, isname, 256)))
+ {
+ log_print ("x509_generate_kn: X509_NAME_oneline (issuer, ...) failed");
+ return 0;
+ }
+
+ if (!LC (X509_NAME_oneline, (subject, subname, 256)))
+ {
+ log_print ("x509_generate_kn: X509_NAME_oneline (subject, ...) failed");
+ return 0;
+ }
+
buf = malloc (strlen (fmt2) + strlen (isname) + strlen (subname));
if (!buf)
@@ -338,7 +349,7 @@ x509_hash_init ()
free (certh);
}
- free(x509_tab);
+ free (x509_tab);
}
x509_tab = malloc ((bucket_mask + 1) * sizeof (struct x509_list));
@@ -356,21 +367,26 @@ X509 *
x509_hash_find (u_int8_t *id, size_t len)
{
struct x509_hash *cert;
- u_int8_t *cid;
- size_t clen;
+ u_int8_t **cid;
+ size_t *clen;
+ int n, i, id_found;
for (cert = LIST_FIRST (&x509_tab[x509_hash (id, len)]); cert;
cert = LIST_NEXT (cert, link))
{
- if (!x509_cert_get_subject (cert->cert, &cid, &clen))
+ if (!x509_cert_get_subjects (cert->cert, &n, &cid, &clen))
continue;
- if (clen != len || memcmp (id, cid, len) != 0)
- {
- free (cid);
- continue;
- }
- free (cid);
+ id_found = 0;
+ for (i = 0; i < n; i++)
+ if (clen[i] == len && memcmp (id, cid[i], len) == 0)
+ {
+ id_found++;
+ break;
+ }
+ cert_free_subjects (n, cid, clen);
+ if (!id_found)
+ continue;
LOG_DBG ((LOG_CRYPTO, 70, "x509_hash_find: return X509 %p",
cert->cert));
@@ -385,20 +401,21 @@ int
x509_hash_enter (X509 *cert)
{
u_int16_t bucket = 0;
- u_int8_t *id;
- u_int32_t len;
+ u_int8_t **id;
+ u_int32_t *len;
struct x509_hash *certh;
+ int n, i;
- if (!x509_cert_get_subject (cert, &id, &len))
+ if (!x509_cert_get_subjects (cert, &n, &id, &len))
{
- log_print ("x509_hash_enter: can not retrieve subjectAltName");
+ log_print ("x509_hash_enter: can not retrieve subjects");
return 0;
}
certh = malloc (sizeof *certh);
if (!certh)
{
- free (id);
+ cert_free_subjects (n, id, len);
log_error ("x509_hash_enter: malloc (%d) failed", sizeof *certh);
return 0;
}
@@ -406,12 +423,16 @@ x509_hash_enter (X509 *cert)
certh->cert = cert;
- bucket = x509_hash (id, len);
- free (id);
+ for (i = 0; i < n; i++)
+ {
+ bucket = x509_hash (id[i], len[i]);
+
+ LIST_INSERT_HEAD (&x509_tab[bucket], certh, link);
+ LOG_DBG ((LOG_CRYPTO, 70, "x509_hash_enter: cert %p added to bucket %d",
+ cert, bucket));
+ }
+ cert_free_subjects (n, id, len);
- LIST_INSERT_HEAD (&x509_tab[bucket], certh, link);
- LOG_DBG ((LOG_CRYPTO, 70, "x509_hash_enter: cert %p added to bucket %d",
- cert, bucket));
return 1;
}
@@ -530,7 +551,9 @@ int
x509_cert_init (void)
{
char *dirname;
+#if defined(USE_KEYNOTE) || defined(USE_POLICY)
int i;
+#endif
x509_hash_init ();
@@ -842,7 +865,7 @@ x509_check_subjectaltname (u_char *id, u_int id_len, X509 *scert)
switch (idtype)
{
case IPSEC_ID_IPV4_ADDR:
- if (type == X509v3_IPV4_ADDR)
+ if (type == X509v3_IP_ADDR)
ret = 1;
break;
case IPSEC_ID_FQDN:
@@ -969,88 +992,137 @@ x509_cert_subjectaltname (X509 *scert, u_int8_t **altname, u_int32_t *len)
}
int
-x509_cert_get_subject (void *scert, u_int8_t **id, u_int32_t *id_len)
+x509_cert_get_subjects (void *scert, int *cnt, u_int8_t ***id,
+ u_int32_t **id_len)
{
X509 *cert = scert;
+ X509_NAME *subject;
int type;
u_int8_t *altname;
u_int32_t altlen;
+ char *buf = 0;
+ unsigned char *ubuf;
+ int i;
+
+ *id = 0;
+ *id_len = 0;
+
+ /*
+ * XXX I *think* the subjectAltName can be a collection, but for now
+ * I only return the subjectName and a single subjectAltName.
+ */
+ *cnt = 2;
+
+ *id = calloc(*cnt, sizeof **id);
+ if (!*id)
+ {
+ log_print ("x509_cert_get_subject: malloc (%d) failed",
+ *cnt * sizeof **id);
+ goto fail;
+ }
+
+ *id_len = malloc(*cnt * sizeof **id_len);
+ if (!*id_len)
+ {
+ log_print ("x509_cert_get_subject: malloc (%d) failed",
+ *cnt * sizeof **id_len);
+ goto fail;
+ }
+
+ /* Stash the subjectName into the first slot. */
+ subject = LC (X509_get_subject_name, (cert));
+ if (!subject)
+ goto fail;
+
+
+ (*id_len)[0] =
+ ISAKMP_ID_DATA_OFF + LC (i2d_X509_NAME, (subject, NULL)) - ISAKMP_GEN_SZ;
+ (*id)[0] = malloc ((*id_len)[0]);
+ if (!(*id)[0])
+ {
+ log_print ("x509_cert_get_subject: malloc (%d) failed", (*id_len)[0]);
+ goto fail;
+ }
+ SET_ISAKMP_ID_TYPE ((*id)[0] - ISAKMP_GEN_SZ, IPSEC_ID_DER_ASN1_DN);
+ ubuf = (*id)[0] + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
+ LC (i2d_X509_NAME, (subject, &ubuf));
+ /* Stash the subjectAltName into the second slot. */
type = x509_cert_subjectaltname (cert, &altname, &altlen);
+ if (!type)
+ goto fail;
+
+ buf = malloc (altlen + ISAKMP_ID_DATA_OFF);
+ if (!buf)
+ {
+ log_print ("x509_cert_get_subject: malloc (%d) failed",
+ altlen + ISAKMP_ID_DATA_OFF);
+ goto fail;
+ }
switch (type)
{
case X509v3_DNS_NAME:
- case X509v3_RFC_NAME:
- {
- char *buf;
-
- buf = malloc (altlen + ISAKMP_ID_DATA_OFF);
- if (!buf)
- {
- log_print ("x509_cert_get_subject: malloc (%d) failed",
- altlen + ISAKMP_ID_DATA_OFF);
- return 0;
- }
-
- if (type == X509v3_DNS_NAME)
- SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_FQDN);
- else
- SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_USER_FQDN);
+ SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_FQDN);
+ break;
- SET_IPSEC_ID_PROTO (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
- SET_IPSEC_ID_PORT (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
- memcpy (buf + ISAKMP_ID_DATA_OFF, altname, altlen);
+ case X509v3_RFC_NAME:
+ SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_USER_FQDN);
+ break;
- *id_len = ISAKMP_ID_DATA_OFF + altlen - ISAKMP_GEN_SZ;
- *id = malloc (*id_len);
- if (!*id)
- {
- log_print ("x509_cert_get_subject: malloc (%d) failed", *id_len);
- free (buf);
- return 0;
- }
- memcpy (*id, buf + ISAKMP_GEN_SZ, *id_len);
- free (buf);
- }
+ case X509v3_IP_ADDR:
+ /*
+ * XXX I dislike the numeric constants, but I don't know what we
+ * should use otherwise.
+ */
+ switch (altlen)
+ {
+ case 4:
+ SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV4_ADDR);
+ break;
+
+ case 16:
+ SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV6_ADDR);
+ break;
+
+ default:
+ log_print ("x509_cert_get_subject: "
+ "invalid subjectAltName iPAdress length %d ", altlen);
+ goto fail;
+ }
break;
-
- case X509v3_IPV4_ADDR:
- {
- char buf[ISAKMP_ID_DATA_OFF + 4];
-
- /* XXX sizeof IPV4_ADDR, how any better? */
- if (altlen != 4)
- {
- log_print ("x509_cert_get_subject: length != IP4addr: %d",
- altlen);
- return 0;
- }
+ }
- SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV4_ADDR);
- SET_IPSEC_ID_PROTO (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
- SET_IPSEC_ID_PORT (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
- memcpy (buf + ISAKMP_ID_DATA_OFF, altname, altlen);
+ SET_IPSEC_ID_PROTO (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
+ SET_IPSEC_ID_PORT (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
+ memcpy (buf + ISAKMP_ID_DATA_OFF, altname, altlen);
- *id_len = ISAKMP_ID_DATA_OFF + 4 - ISAKMP_GEN_SZ;
- *id = malloc (*id_len);
- if (!*id)
- {
- log_print ("x509_cert_get_subject: malloc (%d) failed", *id_len);
- return 0;
- }
- memcpy (*id, buf + ISAKMP_GEN_SZ, *id_len);
- }
- break;
- default:
- log_print ("x509_cert_get_subject: unsupported subjectAltName type: %d",
- type);
- return 0;
+ (*id_len)[1] = ISAKMP_ID_DATA_OFF + altlen - ISAKMP_GEN_SZ;
+ (*id)[1] = malloc ((*id_len)[1]);
+ if (!(*id)[1])
+ {
+ log_print ("x509_cert_get_subject: malloc (%d) failed", (*id_len)[1]);
+ goto fail;
}
+ memcpy ((*id)[1], buf + ISAKMP_GEN_SZ, (*id_len)[1]);
+ free (buf);
+ buf = 0;
return 1;
-}
+ fail:
+ for (i = 0; i < *cnt; i++)
+ if ((*id)[i])
+ free ((*id)[i]);
+ if (*id)
+ free (*id);
+ if (*id_len)
+ free (*id_len);
+ if (buf)
+ free (buf);
+ return 0;
+}
+
int
x509_cert_get_key (void *scert, void *keyp)
{