diff options
-rw-r--r-- | sbin/isakmpd/cert.c | 18 | ||||
-rw-r--r-- | sbin/isakmpd/cert.h | 11 | ||||
-rw-r--r-- | sbin/isakmpd/conf.c | 5 | ||||
-rw-r--r-- | sbin/isakmpd/conf.h | 4 | ||||
-rw-r--r-- | sbin/isakmpd/init.c | 4 | ||||
-rw-r--r-- | sbin/isakmpd/isakmpd.8 | 12 | ||||
-rw-r--r-- | sbin/isakmpd/isakmpd.conf.5 | 4 | ||||
-rw-r--r-- | sbin/isakmpd/x509.c | 151 | ||||
-rw-r--r-- | sbin/isakmpd/x509.h | 5 |
9 files changed, 159 insertions, 55 deletions
diff --git a/sbin/isakmpd/cert.c b/sbin/isakmpd/cert.c index 76f088ab5c0..c416e5595a5 100644 --- a/sbin/isakmpd/cert.c +++ b/sbin/isakmpd/cert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cert.c,v 1.22 2002/06/09 08:13:06 todd Exp $ */ +/* $OpenBSD: cert.c,v 1.23 2002/08/07 13:19:20 ho Exp $ */ /* $EOM: cert.c,v 1.18 2000/09/28 12:53:27 niklas Exp $ */ /* @@ -58,7 +58,7 @@ struct cert_handler cert_handler[] = { #ifdef USE_X509 { ISAKMP_CERTENC_X509_SIG, - x509_cert_init, x509_cert_get, x509_cert_validate, + x509_cert_init, x509_crl_init, x509_cert_get, x509_cert_validate, x509_cert_insert, x509_cert_free, x509_certreq_validate, x509_certreq_decode, x509_free_aca, x509_cert_obtain, x509_cert_get_key, x509_cert_get_subjects, @@ -68,7 +68,7 @@ struct cert_handler cert_handler[] = { #ifdef USE_KEYNOTE { ISAKMP_CERTENC_KEYNOTE, - keynote_cert_init, keynote_cert_get, keynote_cert_validate, + keynote_cert_init, NULL, keynote_cert_get, keynote_cert_validate, keynote_cert_insert, keynote_cert_free, keynote_certreq_validate, keynote_certreq_decode, keynote_free_aca, keynote_cert_obtain, keynote_cert_get_key, keynote_cert_get_subjects, @@ -92,6 +92,18 @@ cert_init (void) return err; } +int +crl_init (void) +{ + int i, err = 1; + + for (i = 0; i < sizeof cert_handler / sizeof cert_handler[0]; i++) + if (cert_handler[i].crl_init && !(*cert_handler[i].crl_init) ()) + err = 0; + + return err; +} + struct cert_handler * cert_get (u_int16_t id) { diff --git a/sbin/isakmpd/cert.h b/sbin/isakmpd/cert.h index eca990c006a..6414016b863 100644 --- a/sbin/isakmpd/cert.h +++ b/sbin/isakmpd/cert.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cert.h,v 1.10 2002/06/09 08:13:06 todd Exp $ */ +/* $OpenBSD: cert.h,v 1.11 2002/08/07 13:19:20 ho Exp $ */ /* $EOM: cert.h,v 1.8 2000/09/28 12:53:27 niklas Exp $ */ /* @@ -45,8 +45,9 @@ /* * CERT handler for each kind of certificate: * - * cert_init - Initialize CERT handler - called only once. - * cert_get - Get a certificate in internal representation from raw data. + * cert_init - initialize CERT handler. + * crl_init - initialize CRLs, if applicable. + * cert_get - get a certificate in internal representation from raw data. * cert_validate - validated a certificate, if it returns != 0 we can use it. * cert_insert - inserts cert into memory storage, we can retrieve with * cert_obtain. @@ -60,7 +61,8 @@ struct cert_handler { u_int16_t id; /* ISAKMP Cert Encoding ID */ - int (*cert_init) (void); + int (*cert_init) (void); + int (*crl_init) (void); void *(*cert_get) (u_int8_t *, u_int32_t); int (*cert_validate) (void *); int (*cert_insert) (int, void *); @@ -92,5 +94,6 @@ struct certreq_aca *certreq_decode (u_int16_t, u_int8_t *, u_int32_t); void cert_free_subjects (int, u_int8_t **, u_int32_t *); struct cert_handler *cert_get (u_int16_t); int cert_init (void); +int crl_init (void); #endif /* _CERT_H_ */ diff --git a/sbin/isakmpd/conf.c b/sbin/isakmpd/conf.c index 081a117b9fc..78d8286b86f 100644 --- a/sbin/isakmpd/conf.c +++ b/sbin/isakmpd/conf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.c,v 1.43 2002/08/02 13:10:41 ho Exp $ */ +/* $OpenBSD: conf.c,v 1.44 2002/08/07 13:19:20 ho Exp $ */ /* $EOM: conf.c,v 1.48 2000/12/04 02:04:29 angelos Exp $ */ /* @@ -424,7 +424,8 @@ conf_load_defaults (int tr) 0, 1); conf_set (tr, "X509-certificates", "Private-key", CONF_DFLT_X509_PRIVATE_KEY, 0, 1); - conf_set (tr, "X509-certificates", "CRL-file", CONF_DFLT_X509_CRL_FILE, 0, 1); + conf_set (tr, "X509-certificates", "CRL-directory", CONF_DFLT_X509_CRL_DIR, + 0, 1); #endif #ifdef USE_KEYNOTE diff --git a/sbin/isakmpd/conf.h b/sbin/isakmpd/conf.h index a3bb3ea6b2e..8063f371c29 100644 --- a/sbin/isakmpd/conf.h +++ b/sbin/isakmpd/conf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.h,v 1.16 2002/08/02 13:10:41 ho Exp $ */ +/* $OpenBSD: conf.h,v 1.17 2002/08/07 13:19:20 ho Exp $ */ /* $EOM: conf.h,v 1.13 2000/09/18 00:01:47 ho Exp $ */ /* @@ -63,7 +63,7 @@ #define CONF_DFLT_X509_CA_DIR "/etc/isakmpd/ca/" #define CONF_DFLT_X509_CERT_DIR "/etc/isakmpd/certs/" #define CONF_DFLT_X509_PRIVATE_KEY "/etc/isakmpd/private/local.key" -#define CONF_DFLT_X509_CRL_FILE "/etc/isakmpd/crl.pem" +#define CONF_DFLT_X509_CRL_DIR "/etc/isakmpd/crls/" #define CONF_DFLT_KEYNOTE_CRED_DIR "/etc/isakmpd/keynote/" struct conf_list_node { diff --git a/sbin/isakmpd/init.c b/sbin/isakmpd/init.c index 9516740f697..593b1214b14 100644 --- a/sbin/isakmpd/init.c +++ b/sbin/isakmpd/init.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init.c,v 1.19 2002/06/10 18:08:58 ho Exp $ */ +/* $OpenBSD: init.c,v 1.20 2002/08/07 13:19:20 ho Exp $ */ /* $EOM: init.c,v 1.25 2000/03/30 14:27:24 ho Exp $ */ /* @@ -89,6 +89,7 @@ init (void) /* Depends on conf_init and policy_init having run */ cert_init (); + crl_init (); sa_init (); transport_init (); @@ -127,6 +128,7 @@ reinit (void) /* Reinitialize certificates */ cert_init (); + crl_init (); /* Reinitialize our connection list. */ connection_reinit (); diff --git a/sbin/isakmpd/isakmpd.8 b/sbin/isakmpd/isakmpd.8 index f2cc80f0ef1..fb996de793d 100644 --- a/sbin/isakmpd/isakmpd.8 +++ b/sbin/isakmpd/isakmpd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: isakmpd.8,v 1.41 2002/08/02 13:27:22 ho Exp $ +.\" $OpenBSD: isakmpd.8,v 1.42 2002/08/07 13:19:20 ho Exp $ .\" $EOM: isakmpd.8,v 1.23 2000/05/02 00:30:23 niklas Exp $ .\" .\" Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. @@ -330,9 +330,9 @@ and put it in .El .Pp To revoke certificates, create a Certificate Revocation List (CRL) file -and install it to -.Pa /etc/isakmpd/crl.pem . -See +and install it to the +.Pa /etc/isakmpd/crls/ +directory. See .Xr openssl 1 and the 'crl' subcommand for more info. .Pp @@ -439,8 +439,8 @@ The directory where CA certificates can be found. The directory where IKE certificates can be found, both the local certificate(s) and those of the peers, if a choice to have them kept permanently has been made. -.It Pa /etc/isakmpd/crl.pem -A list of revoked certificates. +.It Pa /etc/isakmpd/crls/ +The directory where CRLs can be found. .It Pa /etc/isakmpd/isakmpd.conf The configuration file. As this file can contain sensitive information diff --git a/sbin/isakmpd/isakmpd.conf.5 b/sbin/isakmpd/isakmpd.conf.5 index 15d29e245fc..14d7dbc3cc1 100644 --- a/sbin/isakmpd/isakmpd.conf.5 +++ b/sbin/isakmpd/isakmpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: isakmpd.conf.5,v 1.66 2002/08/02 13:27:22 ho Exp $ +.\" $OpenBSD: isakmpd.conf.5,v 1.67 2002/08/07 13:19:20 ho Exp $ .\" $EOM: isakmpd.conf.5,v 1.57 2000/12/21 14:43:17 ho Exp $ .\" .\" Copyright (c) 1998, 1999, 2000 Niklas Hallqvist. All rights reserved. @@ -740,7 +740,7 @@ Credential-directory= /etc/isakmpd/keynote/ [X509-certificates] CA-directory= /etc/isakmpd/ca/ Cert-directory= /etc/isakmpd/certs/ -CRL-file= /etc/isakmpd/crl.pem +CRL-directory= /etc/isakmpd/crls/ Private-key= /etc/isakmpd/private/local.key # Main mode transforms diff --git a/sbin/isakmpd/x509.c b/sbin/isakmpd/x509.c index fe7967bb2a9..db314a4708b 100644 --- a/sbin/isakmpd/x509.c +++ b/sbin/isakmpd/x509.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509.c,v 1.73 2002/08/02 13:10:41 ho Exp $ */ +/* $OpenBSD: x509.c,v 1.74 2002/08/07 13:19:20 ho Exp $ */ /* $EOM: x509.c,v 1.54 2001/01/16 18:42:16 ho Exp $ */ /* @@ -762,6 +762,98 @@ x509_read_from_dir (X509_STORE *ctx, char *name, int hash) return 1; } +/* XXX share code with x509_read_from_dir() ? */ +int +x509_read_crls_from_dir (X509_STORE *ctx, char *name) +{ +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + DIR *dir; + struct dirent *file; + BIO *crlh; + X509_CRL *crl; + char fullname[PATH_MAX]; + int off, size; + + if (strlen (name) >= sizeof fullname - 1) + { + log_print ("x509_read_from_dir: directory name too long"); + return 0; + } + + LOG_DBG ((LOG_CRYPTO, 40, "x509_read_crls_from_dir: reading CRLs from %s", + name)); + + dir = opendir(name); + if (!dir) + { + log_error ("x509_read_crls_from_dir: opendir (\"%s\") failed", name); + return 0; + } + + strlcpy (fullname, name, sizeof fullname); + off = strlen (fullname); + size = sizeof fullname - off; + + while ((file = readdir (dir)) != NULL) + { + strlcpy (fullname + off, file->d_name, size); + + if (file->d_type != DT_UNKNOWN) + { + if (file->d_type != DT_REG && file->d_type != DT_LNK) + continue; + } + else + { + struct stat sb; + + if (stat(fullname, &sb) == -1 || !(sb.st_mode & S_IFREG)) + continue; + } + + if (file->d_type != DT_REG && file->d_type != DT_LNK) + continue; + + LOG_DBG ((LOG_CRYPTO, 60, "x509_read_crls_from_dir: reading CRL %s", + file->d_name)); + + crlh = BIO_new (BIO_s_file ()); + if (!crlh) + { + log_error ("x509_read_crls_from_dir: " + "BIO_new (BIO_s_file ()) failed"); + continue; + } + + if (BIO_read_filename (crlh, fullname) == -1) + { + BIO_free (crlh); + log_error ("x509_read_crls_from_dir: " + "BIO_read_filename (crlh, \"%s\") failed", fullname); + continue; + } + + crl = PEM_read_bio_X509_CRL (crlh, NULL, NULL, NULL); + + BIO_free (crlh); + if (crl == NULL) + { + log_print ("x509_read_crls_from_dir: " + "PEM_read_bio_X509_CRL failed for %s", file->d_name); + continue; + } + + if (!X509_STORE_add_crl (ctx, crl)) + LOG_DBG ((LOG_CRYPTO, 50, "x509_read_crls_from_dir: " + "X509_STORE_add_crl failed for %s", file->d_name)); + } + + closedir (dir); +#endif /* OPENSSL_VERSION_NUMBER >= 0x00907000L */ + + return 1; +} + /* Initialize our databases and load our own certificates. */ int x509_cert_init (void) @@ -823,50 +915,42 @@ x509_cert_init (void) return 1; } -void * -x509_cert_get (u_int8_t *asn, u_int32_t len) -{ - return x509_from_asn (asn, len); -} - int -x509_crl_get (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x) +x509_crl_init (void) { - char *crlfile; - BIO *in; - - if ((crlfile = conf_get_str ("X509-certificates", "CRL-file")) == NULL) - { - LOG_DBG ((LOG_MISC, 10, "x509_crl_get: no CRL-file specified")); - return 0; - } - - if((in = BIO_new (BIO_s_file ())) == NULL) - { - log_print ("x509_crl_get: BIO_new (BIO_s_file ()) failed"); - return 0; - } - - if (BIO_read_filename (in, crlfile) <= 0) + /* + * XXX I'm not sure if the method to use CRLs in certificate validation + * is valid for OpenSSL versions prior to 0.9.7. For now, simply do not + * support it. + */ +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + char *dirname; + dirname = conf_get_str ("X509-certificates", "CRL-directory"); + if (!dirname) { - log_print ("x509_crl_get: BIO_read_filename (in, \"%s\") failed", - crlfile); - BIO_free (in); + log_print ("x509_crl_init: no CRL-directory"); return 0; } - *crl = PEM_read_bio_X509_CRL (in, NULL, NULL, NULL); - BIO_free (in); - if (*crl == NULL) + if (!x509_read_crls_from_dir (x509_cas, dirname)) { - log_print ("x509_crl_get: PEM_read_bio_X509_CRL (in, NULL, NULL, NULL)" - " failed"); + log_print ("x509_crl_init: x509_read_from_dir failed"); return 0; } +#else + LOG_DBG ((LOG_CRYPTO, 10, "x509_crl_init: CRL support only " + "with OpenSSL v0.9.7 or later")); +#endif return 1; } +void * +x509_cert_get (u_int8_t *asn, u_int32_t len) +{ + return x509_from_asn (asn, len); +} + int x509_cert_validate (void *scert) { @@ -881,9 +965,10 @@ x509_cert_validate (void *scert) * trust. */ X509_STORE_CTX_init (&csc, x509_cas, cert, NULL); +#if OPENSSL_VERSION_NUMBER >= 0x00907000L X509_STORE_CTX_set_flags (&csc, X509_V_FLAG_CRL_CHECK); X509_STORE_CTX_set_flags (&csc, X509_V_FLAG_CRL_CHECK_ALL); - csc.get_crl = x509_crl_get; +#endif res = X509_verify_cert (&csc); err = csc.error; X509_STORE_CTX_cleanup (&csc); diff --git a/sbin/isakmpd/x509.h b/sbin/isakmpd/x509.h index e38efdb0d04..7c0d5c7b6f9 100644 --- a/sbin/isakmpd/x509.h +++ b/sbin/isakmpd/x509.h @@ -1,4 +1,4 @@ -/* $OpenBSD: x509.h,v 1.16 2002/08/02 13:10:41 ho Exp $ */ +/* $OpenBSD: x509.h,v 1.17 2002/08/07 13:19:20 ho Exp $ */ /* $EOM: x509.h,v 1.11 2000/09/28 12:53:27 niklas Exp $ */ /* @@ -72,9 +72,9 @@ void *x509_cert_get (u_int8_t *, u_int32_t); int x509_cert_get_key (void *, void *); int x509_cert_get_subjects (void *, int *, u_int8_t ***, u_int32_t **); int x509_cert_init (void); +int x509_crl_init (void); int x509_cert_obtain (u_int8_t *, size_t, void *, u_int8_t **, u_int32_t *); int x509_cert_validate (void *); -int x509_crl_get (X509_STORE_CTX *, X509_CRL **, X509 *); void x509_free_aca (void *); void *x509_cert_dup (void *); void x509_serialize (void *, u_int8_t **, u_int32_t *); @@ -89,5 +89,6 @@ int x509_cert_subjectaltname (X509 *cert, u_char **, u_int *); X509 *x509_from_asn (u_char *, u_int); int x509_generate_kn(int, X509 *); int x509_read_from_dir (X509_STORE *, char *, int); +int x509_read_crls_from_dir (X509_STORE *, char *); #endif /* _X509_H_ */ |