summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2010-06-10 16:14:05 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2010-06-10 16:14:05 +0000
commit46b04df6d6d47c2e2dc6a96e40e8382808733874 (patch)
tree552a2a26079eeef68e9f8a682889645b82ab0e04
parent0a60af3e94e15b17a3be9d22fd74fc5bff9cb226 (diff)
Add a command to revoke a certificate and generate a CRL;
make the ca install command install the CRL as well. discussed with reyk@
-rw-r--r--usr.sbin/ikectl/ikeca.c113
-rw-r--r--usr.sbin/ikectl/ikeca.cnf10
-rw-r--r--usr.sbin/ikectl/ikectl.88
-rw-r--r--usr.sbin/ikectl/ikectl.c7
-rw-r--r--usr.sbin/ikectl/parser.c3
-rw-r--r--usr.sbin/ikectl/parser.h3
6 files changed, 134 insertions, 10 deletions
diff --git a/usr.sbin/ikectl/ikeca.c b/usr.sbin/ikectl/ikeca.c
index ed25f1c1931..8fd9865a4f0 100644
--- a/usr.sbin/ikectl/ikeca.c
+++ b/usr.sbin/ikectl/ikeca.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikeca.c,v 1.3 2010/06/07 14:15:27 jsg Exp $ */
+/* $OpenBSD: ikeca.c,v 1.4 2010/06/10 16:14:04 jsg Exp $ */
/* $vantronix: ikeca.c,v 1.13 2010/06/03 15:52:52 reyk Exp $ */
/*
@@ -73,8 +73,10 @@ int ca_certificate(struct ca *, char *, int);
int ca_cert_install(struct ca *, char *);
int ca_newpass(char *);
int ca_export(struct ca *, char *);
+int ca_revoke(struct ca *, char *);
int ca_install(struct ca *);
int ca_show_certs(struct ca *);
+char * ca_readpass(char *, size_t *);
int fcopy(char *, char *, mode_t);
int rm_dir(char *);
@@ -290,8 +292,16 @@ ca_install(struct ca *ca)
snprintf(dst, sizeof(dst), "%s/ca/ca.crt", KEYBASE);
if (fcopy(src, dst, 0644) == 0)
- printf("certificate for CA '%s' installed into %s\n", ca->caname,
- dst);
+ printf("certificate for CA '%s' installed into %s\n",
+ ca->caname, dst);
+
+ snprintf(src, sizeof(src), "%s/ca.crl", ca->sslpath);
+ if (stat(src, &st) == 0) {
+ snprintf(dst, sizeof(dst), "%s/crls/ca.crl", KEYBASE);
+ if (fcopy(src, dst, 0644) == 0)
+ printf("CRL for CA '%s' installed to %s\n",
+ ca->caname, dst);
+ }
return (0);
}
@@ -400,7 +410,8 @@ ca_export(struct ca *ca, char *keyname)
char dst[PATH_MAX];
char *p;
char tpl[] = "/tmp/ikectl.XXXXXXXXXX";
- const char *exdirs[] = { "/ca", "/certs", "/private", "/export" };
+ const char *exdirs[] = { "/ca", "/certs", "/crls", "/private",
+ "/export" };
u_int i;
/* colons are not valid characters in windows filenames... */
@@ -464,6 +475,12 @@ ca_export(struct ca *ca, char *keyname)
snprintf(dst, sizeof(dst), "%s/certs/%s.crt", p, keyname);
fcopy(src, dst, 0644);
+ snprintf(src, sizeof(src), "%s/ca.crl", ca->sslpath);
+ if (stat(src, &st) == 0) {
+ snprintf(dst, sizeof(dst), "%s/crls/ca.crl", p);
+ fcopy(src, dst, 0644);
+ }
+
snprintf(cmd, sizeof(cmd), "%s rsa -out %s/local.pub"
" -in %s/private/%s.key -pubout", PATH_OPENSSL, p, ca->sslpath,
keyname);
@@ -500,6 +517,94 @@ ca_export(struct ca *ca, char *keyname)
return (0);
}
+char *
+ca_readpass(char *path, size_t *len)
+{
+ FILE *f;
+ char *p, *r;
+
+ if ((f = fopen(path, "r")) == NULL) {
+ warn("fopen %s", path);
+ return (NULL);
+ }
+
+ if ((p = fgetln(f, len)) != NULL) {
+ if ((r = malloc(*len + 1)) == NULL)
+ err(1, "malloc");
+ memcpy(r, p, *len);
+ if (r[*len - 1] == '\n')
+ r[*len - 1] = '\0';
+ else
+ r[*len] = '\0';
+ } else
+ r = NULL;
+
+ fclose(f);
+
+ return (r);
+}
+
+int
+ca_revoke(struct ca *ca, char *keyname)
+{
+ struct stat st;
+ char cmd[PATH_MAX * 2];
+ char path[PATH_MAX];
+ int fd;
+ char *pass;
+ size_t len;
+
+ snprintf(path, sizeof(path), "%s/%s.crt",
+ ca->sslpath, keyname);
+ if (stat(path, &st) != 0) {
+ warn("Problem with certificate for '%s'", keyname);
+ return (1);
+ }
+
+ snprintf(path, sizeof(path), "%s/ikeca.passwd", ca->sslpath);
+ pass = ca_readpass(path, &len);
+ if (pass == NULL)
+ err(1, "could not open passphrase file");
+
+ /* create index if it doesn't already exist */
+ snprintf(path, sizeof(path), "%s/index.txt", ca->sslpath);
+ if (stat(path, &st) != 0) {
+ if (errno == ENOENT) {
+ if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) == -1)
+ err(1, "could not create file %s", path);
+ close(fd);
+ } else
+ err(1, "could not access %s", path);
+ }
+
+ snprintf(cmd, sizeof(cmd), "env CADB='%s/index.txt' "
+ " %s ca -config %s -keyfile %s/private/ca.key"
+ " -key %s"
+ " -cert %s/ca.crt"
+ " -md sha1"
+ " -revoke %s/%s.crt",
+ ca->sslpath, PATH_OPENSSL, ca->sslcnf, ca->sslpath, pass,
+ ca->sslpath, ca->sslpath, keyname);
+ system(cmd);
+
+ snprintf(cmd, sizeof(cmd), "env CADB='%s/index.txt' "
+ " %s ca -config %s -keyfile %s/private/ca.key"
+ " -key %s"
+ " -gencrl"
+ " -cert %s/ca.crt"
+ " -md sha1"
+ " -crldays 365"
+ " -out %s/ca.crl",
+ ca->sslpath, PATH_OPENSSL, ca->sslcnf, ca->sslpath, pass,
+ ca->sslpath, ca->sslpath);
+ system(cmd);
+
+ bzero(pass, len);
+ free(pass);
+
+ return (0);
+}
+
struct ca *
ca_setup(char *caname, int create)
{
diff --git a/usr.sbin/ikectl/ikeca.cnf b/usr.sbin/ikectl/ikeca.cnf
index b3651db2f97..8423518a93b 100644
--- a/usr.sbin/ikectl/ikeca.cnf
+++ b/usr.sbin/ikectl/ikeca.cnf
@@ -1,4 +1,4 @@
-# $OpenBSD: ikeca.cnf,v 1.1 2010/06/03 16:49:00 reyk Exp $
+# $OpenBSD: ikeca.cnf,v 1.2 2010/06/10 16:14:04 jsg Exp $
# $vantronix: ikeca.cnf,v 1.3 2010/05/31 12:26:26 reyk Exp $
RANDFILE = /dev/arandom
@@ -17,6 +17,7 @@ CERTUSAGE = digitalSignature,keyCertSign,cRLSign
EXTCERTUSAGE = serverAuth,clientAuth
CERTIP = 0.0.0.0
CERTFQDN = nohost.nodomain
+CADB = index.txt
[ req ]
default_bits = 2048
@@ -79,3 +80,10 @@ extendedKeyUsage=$ENV::EXTCERTUSAGE
[x509v3_FQDN]
subjectAltName=DNS:$ENV::CERTFQDN
extendedKeyUsage=$ENV::EXTCERTUSAGE
+
+[ca]
+default_ca = CA_default
+
+[CA_default]
+database=$ENV::CADB
+
diff --git a/usr.sbin/ikectl/ikectl.8 b/usr.sbin/ikectl/ikectl.8
index 1f1d8390457..75d34fdda45 100644
--- a/usr.sbin/ikectl/ikectl.8
+++ b/usr.sbin/ikectl/ikectl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ikectl.8,v 1.2 2010/06/10 14:08:37 reyk Exp $
+.\" $OpenBSD: ikectl.8,v 1.3 2010/06/10 16:14:04 jsg Exp $
.\" $vantronix: ikectl.8,v 1.11 2010/06/03 15:55:51 reyk Exp $
.\"
.\" Copyright (c) 2007, 2008, 2009, 2010 Reyk Floeter <reyk@vantronix.net>
@@ -106,7 +106,7 @@ Create a new certificate authority with the specified
Delete the certificate authority with the specified
.Ar name .
.It Cm ca Ar name Cm install
-Install the certificate for CA
+Install the certificate and Certificate Revocation List (CRL) for CA
.Ar name
as the currently active CA.
.It Cm ca Ar name Cm certificate Ar host Cm create
@@ -127,6 +127,10 @@ into the current directory for transport to other systems.
Install the private and public key for
.Ar host
into the active configuration.
+.It Cm ca Ar name Cm certificate Ar host Cm revoke
+Revoke the certificate specified by
+.Ar host
+and generate a new Certificate Revocation List (CRL).
.It Cm show Cm ca Ar name Cm certificates
Display a listing of certificates associated with CA
.Ar name .
diff --git a/usr.sbin/ikectl/ikectl.c b/usr.sbin/ikectl/ikectl.c
index 1900db3ef98..6c47bfd7cbd 100644
--- a/usr.sbin/ikectl/ikectl.c
+++ b/usr.sbin/ikectl/ikectl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikectl.c,v 1.2 2010/06/10 14:08:37 reyk Exp $ */
+/* $OpenBSD: ikectl.c,v 1.3 2010/06/10 16:14:04 jsg Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -54,6 +54,7 @@ struct ca *ca_setup(char *, int);
int ca_create(struct ca *);
int ca_certificate(struct ca *, char *, int);
int ca_export(struct ca *, char *);
+int ca_revoke(struct ca *, char *);
int ca_delete(struct ca *);
int ca_delkey(struct ca *, char *);
int ca_install(struct ca *);
@@ -116,6 +117,9 @@ ca_opt(struct parse_result *res)
case CA_CERT_EXPORT:
ca_export(ca, res->host);
break;
+ case CA_CERT_REVOKE:
+ ca_revoke(ca, res->host);
+ break;
case SHOW_CA_CERTIFICATES:
ca_show_certs(ca);
break;
@@ -167,6 +171,7 @@ main(int argc, char *argv[])
case CA_CERT_DELETE:
case CA_CERT_INSTALL:
case CA_CERT_EXPORT:
+ case CA_CERT_REVOKE:
case SHOW_CA:
case SHOW_CA_CERTIFICATES:
ca_opt(res);
diff --git a/usr.sbin/ikectl/parser.c b/usr.sbin/ikectl/parser.c
index 4aba2efa886..2a5b28535f5 100644
--- a/usr.sbin/ikectl/parser.c
+++ b/usr.sbin/ikectl/parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.c,v 1.2 2010/06/10 14:08:37 reyk Exp $ */
+/* $OpenBSD: parser.c,v 1.3 2010/06/10 16:14:04 jsg Exp $ */
/*
* Copyright (c) 2010 Reyk Floeter <reyk@vantronix.net>
@@ -124,6 +124,7 @@ static const struct token t_ca_cert_modifiers[] = {
{ KEYWORD, "delete", CA_CERT_DELETE, NULL },
{ KEYWORD, "install", CA_CERT_INSTALL, NULL },
{ KEYWORD, "export", CA_CERT_EXPORT, NULL },
+ { KEYWORD, "revoke", CA_CERT_REVOKE, NULL },
{ ENDTOKEN, "", NONE, NULL }
};
diff --git a/usr.sbin/ikectl/parser.h b/usr.sbin/ikectl/parser.h
index 851bda3f5ed..e274e0af073 100644
--- a/usr.sbin/ikectl/parser.h
+++ b/usr.sbin/ikectl/parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.h,v 1.2 2010/06/10 14:08:37 reyk Exp $ */
+/* $OpenBSD: parser.h,v 1.3 2010/06/10 16:14:04 jsg Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -41,6 +41,7 @@ enum actions {
CA_CERT_DELETE,
CA_CERT_INSTALL,
CA_CERT_EXPORT,
+ CA_CERT_REVOKE,
SHOW_CA,
SHOW_CA_CERTIFICATES
};