summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>2000-01-31 08:18:42 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>2000-01-31 08:18:42 +0000
commitf23f12f37b8e7c1a504a9d97ddbac1623eb8ad3f (patch)
tree1469c23a01f72d7d43c120d9cee62d88a88479b6
parentc5e8e9c16a1e93cc55a80506b8e5cd12ec9329c9 (diff)
Merge with EOM 1.30
author: angelos Make x509_cert_init() able to re-initialize. author: angelos Fix delegating to a CA.
-rw-r--r--sbin/isakmpd/x509.c123
1 files changed, 84 insertions, 39 deletions
diff --git a/sbin/isakmpd/x509.c b/sbin/isakmpd/x509.c
index c782409cfe1..d2f5c73b63a 100644
--- a/sbin/isakmpd/x509.c
+++ b/sbin/isakmpd/x509.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: x509.c,v 1.18 2000/01/27 08:49:24 niklas Exp $ */
-/* $EOM: x509.c,v 1.28 2000/01/27 08:53:22 niklas Exp $ */
+/* $OpenBSD: x509.c,v 1.19 2000/01/31 08:18:41 niklas Exp $ */
+/* $EOM: x509.c,v 1.30 2000/01/31 05:50:59 angelos Exp $ */
/*
* Copyright (c) 1998, 1999 Niels Provos. All rights reserved.
@@ -77,8 +77,8 @@ extern int keynote_sessid;
* only differing in subjectAltName.
*/
#if defined (USE_LIBCRYPTO) || defined (HAVE_DLOPEN)
-static X509_STORE *x509_certs;
-static X509_STORE *x509_cas;
+static X509_STORE *x509_certs = NULL;
+static X509_STORE *x509_cas = NULL;
#endif
/* Initial number of bits used as hash. */
@@ -90,7 +90,7 @@ struct x509_hash {
X509 *cert;
};
-static LIST_HEAD (x509_list, x509_hash) *x509_tab;
+static LIST_HEAD (x509_list, x509_hash) *x509_tab = NULL;
/* Works both as a maximum index and a mask. */
static int bucket_mask;
@@ -99,29 +99,26 @@ static int bucket_mask;
/*
* Given an X509 certificate, create a KeyNote assertion where
* Issuer/Subject -> Authorizer/Licensees,
+ * XXX RSA-specific
*/
int
x509_generate_kn (X509 *cert)
{
- char *fmt = "Authorizer: \"%s\"\nLicensees: \"%s\"\n";
+ char *fmt = "Authorizer: \"rsa-hex:%s\"\nLicensees: \"rsa-hex:%s\"\n";
X509_NAME *issuer, *subject;
struct keynote_deckey dc;
char *ikey, *skey, *buf;
X509_STORE_CTX csc;
+ X509_OBJECT obj;
X509 *icert;
-#if SSLEAY_VERSION_NUMBER >= 0x00904100L
- STACK_OF (X509) *sk;
-#else
- STACK *sk;
-#endif
RSA *key;
issuer = LC (X509_get_issuer_name, (cert));
subject = LC (X509_get_subject_name, (cert));
/* Missing or self-signed, ignore cert but don't report failure */
- if (!issuer || !subject || LC (X509_name_cmp, (issuer, subject)))
- return 1;
+ if (!issuer || !subject || !LC (X509_name_cmp, (issuer, subject)))
+ return 1;
if (!x509_cert_get_key (cert, &key))
{
@@ -143,19 +140,22 @@ x509_generate_kn (X509 *cert)
LC (RSA_free, (key));
/* Now find issuer's certificate so we can get the public key */
- LC (X509_STORE_CTX_init, (&csc, x509_cas, NULL, NULL));
-#if SSLEAY_VERSION_NUMBER >= 0x00904100L
- sk = LC (sk_X509_new_null, ());
-#else
- sk = LC (sk_new_null, ());
-#endif
- icert = LC (X509_find_by_subject, (sk, issuer));
-#if SSLEAY_VERSION_NUMBER >= 0x00904100L
- LC (sk_X509_free, (sk));
-#else
- LC (sk_free, (sk));
-#endif
+ LC (X509_STORE_CTX_init, (&csc, x509_cas, cert, NULL));
+ if (LC (X509_STORE_get_by_subject, (&csc, X509_LU_X509, issuer, &obj)) !=
+ X509_LU_X509)
+ {
+ LC (X509_STORE_CTX_cleanup, (&csc));
+ LC (X509_STORE_CTX_init, (&csc, x509_certs, cert, NULL));
+ if (LC (X509_STORE_get_by_subject, (&csc, X509_LU_X509, issuer, &obj)) !=
+ X509_LU_X509)
+ {
+ LC (X509_STORE_CTX_cleanup, (&csc));
+ return 0;
+ }
+ }
+
LC (X509_STORE_CTX_cleanup, (&csc));
+ icert = obj.data.x509;
if (icert == NULL)
{
@@ -172,6 +172,8 @@ x509_generate_kn (X509 *cert)
return 0;
}
+ LC (X509_OBJECT_free_contents, (&obj));
+
dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
dc.dec_key = (void *) key;
skey = LK (kn_encode_key, (&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
@@ -191,13 +193,14 @@ x509_generate_kn (X509 *cert)
log_fatal ("x509_generate_kn: "
"failed to allocate memory for KeyNote credential");
- sprintf (buf, fmt, ikey, skey);
+ sprintf (buf, fmt, skey, ikey);
free (ikey);
free (skey);
if (LK (kn_add_assertion, (keynote_sessid, buf, strlen (buf),
ASSERT_FLAG_LOCAL)) == -1)
{
+ printf("%d\n", keynote_errno);
log_error ("x509_generate_kn: failed to add new KeyNote credential");
free (buf);
return 0;
@@ -207,7 +210,9 @@ x509_generate_kn (X509 *cert)
* XXX
* Should add a remove-assertion event set to the expiration of the
* X509 cert (and remove such events when we reinit and close the keynote
- * session).
+ * session) -- that's relevant only for really long-lived daemons.
+ * Alternatively (and preferably), we can encode the X509 expiration
+ * in the KeyNote Conditions.
* XXX
*/
@@ -240,9 +245,26 @@ x509_hash (u_int8_t *id, size_t len)
void
x509_hash_init ()
{
+ struct x509_hash *certh;
int i;
bucket_mask = (1 << INITIAL_BUCKET_BITS) - 1;
+
+ /* If reinitializing, free existing entries */
+ if (x509_tab)
+ {
+ for (i = 0; i <= bucket_mask; i++)
+ for (certh = LIST_FIRST (&x509_tab[i]); certh;
+ certh = LIST_NEXT (certh, link))
+ {
+ LIST_REMOVE (certh, link);
+ LC (X509_free, (certh->cert));
+ free (certh);
+ }
+
+ free(x509_tab);
+ }
+
x509_tab = malloc ((bucket_mask + 1) * sizeof (struct x509_list));
if (!x509_tab)
log_fatal ("x509_hash_init: malloc (%d) failed",
@@ -402,6 +424,21 @@ x509_read_from_dir (X509_STORE *ctx, char *name, int hash)
file->d_name);
}
+ if (hash)
+ {
+#if defined (USE_KEYNOTE) || defined (HAVE_DLOPEN)
+#ifdef USE_KEYNOTE
+ if (x509_generate_kn (cert) == 0)
+#else
+ if (libkeynote && x509_generate_kn (cert) == 0)
+#endif
+ {
+ log_print ("x509_read_from_dir: x509_generate_kn failed");
+ continue;
+ }
+#endif /* USE_KEYNOTE || HAVE_DLOPEN */
+ }
+
if (hash && !x509_hash_enter (cert))
log_print ("x509_read_from_dir: x509_hash_enter (%s) failed",
file->d_name);
@@ -424,43 +461,51 @@ x509_cert_init (void)
x509_hash_init ();
- /* Process client certificates we will accept. */
- dirname = conf_get_str ("X509-certificates", "Cert-directory");
+ /* Process CA certificates we will trust. */
+ dirname = conf_get_str ("X509-certificates", "CA-directory");
if (!dirname)
{
- log_print ("x509_cert_init: no Cert-directory");
+ log_print ("x509_cert_init: no CA-directory");
return 0;
}
- x509_certs = LC (X509_STORE_new, ());
- if (!x509_certs)
+ /* Free if already initialized */
+ if (x509_cas)
+ LC (X509_STORE_free, (x509_cas));
+
+ x509_cas = LC (X509_STORE_new, ());
+ if (!x509_cas)
{
log_print ("x509_cert_init: creating new X509_STORE failed");
return 0;
}
- if (!x509_read_from_dir (x509_certs, dirname, 1))
+ if (!x509_read_from_dir (x509_cas, dirname, 0))
{
log_print ("x509_cert_init: x509_read_from_dir failed");
return 0;
}
- /* Process CA certificates we will trust. */
- dirname = conf_get_str ("X509-certificates", "CA-directory");
+ /* Process client certificates we will accept. */
+ dirname = conf_get_str ("X509-certificates", "Cert-directory");
if (!dirname)
{
- log_print ("x509_cert_init: no CA-directory");
+ log_print ("x509_cert_init: no Cert-directory");
return 0;
}
- x509_cas = LC (X509_STORE_new, ());
- if (!x509_cas)
+ /* Free if already initialized */
+ if (x509_certs)
+ LC (X509_STORE_free, (x509_certs));
+
+ x509_certs = LC (X509_STORE_new, ());
+ if (!x509_certs)
{
log_print ("x509_cert_init: creating new X509_STORE failed");
return 0;
}
- if (!x509_read_from_dir (x509_cas, dirname, 0))
+ if (!x509_read_from_dir (x509_certs, dirname, 1))
{
log_print ("x509_cert_init: x509_read_from_dir failed");
return 0;