summaryrefslogtreecommitdiff
path: root/src/pki
diff options
context:
space:
mode:
Diffstat (limited to 'src/pki')
-rw-r--r--src/pki/Makefile.am1
-rw-r--r--src/pki/Makefile.in11
-rw-r--r--src/pki/command.h2
-rw-r--r--src/pki/commands/acert.c11
-rw-r--r--src/pki/commands/gen.c14
-rw-r--r--src/pki/commands/issue.c12
-rw-r--r--src/pki/commands/keyid.c7
-rw-r--r--src/pki/commands/pkcs12.c247
-rw-r--r--src/pki/commands/print.c34
-rw-r--r--src/pki/commands/pub.c10
-rw-r--r--src/pki/commands/req.c17
-rw-r--r--src/pki/commands/self.c20
-rw-r--r--src/pki/commands/signcrl.c8
-rw-r--r--src/pki/man/Makefile.in21
-rw-r--r--src/pki/man/pki---acert.1.in4
-rw-r--r--src/pki/man/pki---issue.1.in20
-rw-r--r--src/pki/man/pki---pkcs12.1.in62
-rw-r--r--src/pki/man/pki---req.1.in4
-rw-r--r--src/pki/man/pki---self.1.in20
-rw-r--r--src/pki/man/pki---signcrl.1.in4
-rw-r--r--src/pki/pki.c46
-rw-r--r--src/pki/pki.h8
22 files changed, 531 insertions, 52 deletions
diff --git a/src/pki/Makefile.am b/src/pki/Makefile.am
index 266802cf7..ab407e021 100644
--- a/src/pki/Makefile.am
+++ b/src/pki/Makefile.am
@@ -13,6 +13,7 @@ pki_SOURCES = pki.c pki.h command.c command.h \
commands/signcrl.c \
commands/acert.c \
commands/pkcs7.c \
+ commands/pkcs12.c \
commands/verify.c
pki_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
diff --git a/src/pki/Makefile.in b/src/pki/Makefile.in
index 5f7a1bc26..4205469fc 100644
--- a/src/pki/Makefile.in
+++ b/src/pki/Makefile.in
@@ -108,7 +108,7 @@ am_pki_OBJECTS = pki.$(OBJEXT) command.$(OBJEXT) \
commands/req.$(OBJEXT) commands/self.$(OBJEXT) \
commands/print.$(OBJEXT) commands/signcrl.$(OBJEXT) \
commands/acert.$(OBJEXT) commands/pkcs7.$(OBJEXT) \
- commands/verify.$(OBJEXT)
+ commands/pkcs12.$(OBJEXT) commands/verify.$(OBJEXT)
pki_OBJECTS = $(am_pki_OBJECTS)
pki_DEPENDENCIES = $(top_builddir)/src/libstrongswan/libstrongswan.la
AM_V_lt = $(am__v_lt_@AM_V@)
@@ -243,6 +243,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -303,10 +304,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
PTHREADLIB = @PTHREADLIB@
PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
RUBY = @RUBY@
@@ -380,6 +383,8 @@ json_CFLAGS = @json_CFLAGS@
json_LIBS = @json_LIBS@
libdir = @libdir@
libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
@@ -450,6 +455,7 @@ pki_SOURCES = pki.c pki.h command.c command.h \
commands/signcrl.c \
commands/acert.c \
commands/pkcs7.c \
+ commands/pkcs12.c \
commands/verify.c
pki_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
@@ -566,6 +572,8 @@ commands/acert.$(OBJEXT): commands/$(am__dirstamp) \
commands/$(DEPDIR)/$(am__dirstamp)
commands/pkcs7.$(OBJEXT): commands/$(am__dirstamp) \
commands/$(DEPDIR)/$(am__dirstamp)
+commands/pkcs12.$(OBJEXT): commands/$(am__dirstamp) \
+ commands/$(DEPDIR)/$(am__dirstamp)
commands/verify.$(OBJEXT): commands/$(am__dirstamp) \
commands/$(DEPDIR)/$(am__dirstamp)
@@ -586,6 +594,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/gen.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/issue.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/keyid.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/pkcs12.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/pkcs7.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/print.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/pub.Po@am__quote@
diff --git a/src/pki/command.h b/src/pki/command.h
index 9cf036bf2..d49adda09 100644
--- a/src/pki/command.h
+++ b/src/pki/command.h
@@ -24,7 +24,7 @@
/**
* Maximum number of commands (+1).
*/
-#define MAX_COMMANDS 12
+#define MAX_COMMANDS 13
/**
* Maximum number of options in a command (+3)
diff --git a/src/pki/commands/acert.c b/src/pki/commands/acert.c
index 185aa40b4..7099977f2 100644
--- a/src/pki/commands/acert.c
+++ b/src/pki/commands/acert.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -31,7 +32,7 @@
static int acert()
{
cred_encoding_type_t form = CERT_ASN1_DER;
- hash_algorithm_t digest = HASH_SHA1;
+ hash_algorithm_t digest = HASH_UNKNOWN;
certificate_t *ac = NULL, *cert = NULL, *issuer =NULL;
private_key_t *private = NULL;
public_key_t *public = NULL;
@@ -161,6 +162,10 @@ static int acert()
error = "loading issuer private key failed";
goto end;
}
+ if (digest == HASH_UNKNOWN)
+ {
+ digest = get_default_digest(private);
+ }
if (!private->belongs_to(private, public))
{
error = "issuer private key does not match issuer certificate";
@@ -286,7 +291,7 @@ static void __attribute__ ((constructor))reg()
{"not-before", 'F', 1, "date/time the validity of the AC starts"},
{"not-after", 'T', 1, "date/time the validity of the AC ends"},
{"dateform", 'D', 1, "strptime(3) input format, default: %d.%m.%y %T"},
- {"digest", 'g', 1, "digest for signature creation, default: sha1"},
+ {"digest", 'g', 1, "digest for signature creation, default: key-specific"},
{"outform", 'f', 1, "encoding of generated cert, default: der"},
}
});
diff --git a/src/pki/commands/gen.c b/src/pki/commands/gen.c
index ce28a0971..8b11854ad 100644
--- a/src/pki/commands/gen.c
+++ b/src/pki/commands/gen.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2014-2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -43,6 +44,10 @@ static int gen()
{
type = KEY_ECDSA;
}
+ else if (streq(arg, "bliss"))
+ {
+ type = KEY_BLISS;
+ }
else
{
return command_usage("invalid key type");
@@ -96,6 +101,9 @@ static int gen()
case KEY_ECDSA:
size = 384;
break;
+ case KEY_BLISS:
+ size = 1;
+ break;
default:
break;
}
@@ -151,12 +159,12 @@ static void __attribute__ ((constructor))reg()
{
command_register((command_t) {
gen, 'g', "gen", "generate a new private key",
- {" [--type rsa|ecdsa] [--size bits] [--safe-primes]",
+ {" [--type rsa|ecdsa|bliss] [--size bits] [--safe-primes]",
"[--shares n] [--threshold l] [--outform der|pem]"},
{
{"help", 'h', 0, "show usage information"},
{"type", 't', 1, "type of key, default: rsa"},
- {"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384"},
+ {"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384, bliss 1"},
{"safe-primes", 'p', 0, "generate rsa safe primes"},
{"shares", 'n', 1, "number of private rsa key shares"},
{"threshold", 'l', 1, "minimum number of participating rsa key shares"},
diff --git a/src/pki/commands/issue.c b/src/pki/commands/issue.c
index aaa2c2ff7..6a2d09d78 100644
--- a/src/pki/commands/issue.c
+++ b/src/pki/commands/issue.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -59,7 +60,7 @@ static void destroy_cdp(x509_cdp_t *this)
static int issue()
{
cred_encoding_type_t form = CERT_ASN1_DER;
- hash_algorithm_t digest = HASH_SHA1;
+ hash_algorithm_t digest = HASH_UNKNOWN;
certificate_t *cert_req = NULL, *cert = NULL, *ca =NULL;
private_key_t *private = NULL;
public_key_t *public = NULL;
@@ -287,6 +288,7 @@ static int issue()
}
break;
}
+
if (!cacert)
{
error = "--cacert is required";
@@ -355,6 +357,10 @@ static int issue()
error = "loading CA private key failed";
goto end;
}
+ if (digest == HASH_UNKNOWN)
+ {
+ digest = get_default_digest(private);
+ }
if (!private->belongs_to(private, public))
{
error = "CA private key does not match CA certificate";
@@ -589,7 +595,7 @@ static void __attribute__ ((constructor))reg()
{"crl", 'u', 1, "CRL distribution point URI to include"},
{"crlissuer", 'I', 1, "CRL Issuer for CRL at distribution point"},
{"ocsp", 'o', 1, "OCSP AuthorityInfoAccess URI to include"},
- {"digest", 'g', 1, "digest for signature creation, default: sha1"},
+ {"digest", 'g', 1, "digest for signature creation, default: key-specific"},
{"outform", 'f', 1, "encoding of generated cert, default: der"},
}
});
diff --git a/src/pki/commands/keyid.c b/src/pki/commands/keyid.c
index c3ac0c288..3bc62e74d 100644
--- a/src/pki/commands/keyid.c
+++ b/src/pki/commands/keyid.c
@@ -52,6 +52,11 @@ static int keyid()
type = CRED_PRIVATE_KEY;
subtype = KEY_ECDSA;
}
+ else if (streq(arg, "bliss-priv"))
+ {
+ type = CRED_PRIVATE_KEY;
+ subtype = KEY_BLISS;
+ }
else if (streq(arg, "pub"))
{
type = CRED_PUBLIC_KEY;
@@ -164,7 +169,7 @@ static void __attribute__ ((constructor))reg()
command_register((command_t)
{ keyid, 'k', "keyid",
"calculate key identifiers of a key/certificate",
- {"[--in file] [--type rsa-priv|ecdsa-priv|pub|pkcs10|x509]"},
+ {"[--in file] [--type rsa-priv|ecdsa-priv|bliss-priv|pub|pkcs10|x509]"},
{
{"help", 'h', 0, "show usage information"},
{"in", 'i', 1, "input file, default: stdin"},
diff --git a/src/pki/commands/pkcs12.c b/src/pki/commands/pkcs12.c
new file mode 100644
index 000000000..dcd1496ba
--- /dev/null
+++ b/src/pki/commands/pkcs12.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2014 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <errno.h>
+
+#include "pki.h"
+
+#include <credentials/certificates/x509.h>
+#include <credentials/containers/pkcs12.h>
+
+/**
+ * Show info about PKCS#12 container
+ */
+static int show(pkcs12_t *pkcs12)
+{
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ private_key_t *key;
+ int index = 1;
+
+ printf("Certificates:\n");
+ enumerator = pkcs12->create_cert_enumerator(pkcs12);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ x509_t *x509 = (x509_t*)cert;
+
+ if (x509->get_flags(x509) & X509_CA)
+ {
+ printf("[%2d] \"%Y\" (CA)\n", index++, cert->get_subject(cert));
+ }
+ else
+ {
+ printf("[%2d] \"%Y\"\n", index++, cert->get_subject(cert));
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ printf("Private keys:\n");
+ enumerator = pkcs12->create_key_enumerator(pkcs12);
+ while (enumerator->enumerate(enumerator, &key))
+ {
+ printf("[%2d] %N %d bits\n", index++, key_type_names,
+ key->get_type(key), key->get_keysize(key));
+ }
+ enumerator->destroy(enumerator);
+ return 0;
+}
+
+static int export(pkcs12_t *pkcs12, int index, char *outform)
+{
+ cred_encoding_type_t form;
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ private_key_t *key;
+ chunk_t encoding;
+ int i = 1;
+
+ enumerator = pkcs12->create_cert_enumerator(pkcs12);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ if (i++ == index)
+ {
+ form = CERT_ASN1_DER;
+ if (outform && !get_form(outform, &form, CRED_CERTIFICATE))
+ {
+ enumerator->destroy(enumerator);
+ return command_usage("invalid output format");
+ }
+ if (cert->get_encoding(cert, form, &encoding))
+ {
+ set_file_mode(stdout, form);
+ if (fwrite(encoding.ptr, encoding.len, 1, stdout) == 1)
+ {
+ free(encoding.ptr);
+ enumerator->destroy(enumerator);
+ return 0;
+ }
+ free(encoding.ptr);
+ }
+ fprintf(stderr, "certificate export failed\n");
+ enumerator->destroy(enumerator);
+ return 1;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ enumerator = pkcs12->create_key_enumerator(pkcs12);
+ while (enumerator->enumerate(enumerator, &key))
+ {
+ if (i++ == index)
+ {
+ form = PRIVKEY_ASN1_DER;
+ if (outform && !get_form(outform, &form, CRED_PRIVATE_KEY))
+ {
+ enumerator->destroy(enumerator);
+ return command_usage("invalid output format");
+ }
+ if (key->get_encoding(key, form, &encoding))
+ {
+ set_file_mode(stdout, form);
+ if (fwrite(encoding.ptr, encoding.len, 1, stdout) == 1)
+ {
+ free(encoding.ptr);
+ enumerator->destroy(enumerator);
+ return 0;
+ }
+ free(encoding.ptr);
+ }
+ fprintf(stderr, "private key export failed\n");
+ enumerator->destroy(enumerator);
+ return 0;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ fprintf(stderr, "invalid index %d\n", index);
+ return 1;
+}
+
+
+/**
+ * Handle PKCs#12 containers
+ */
+static int pkcs12()
+{
+ char *arg, *file = NULL, *outform = NULL;
+ pkcs12_t *p12 = NULL;
+ int res = 1, index = 0;
+ enum {
+ OP_NONE,
+ OP_LIST,
+ OP_EXPORT,
+ } op = OP_NONE;
+
+ while (TRUE)
+ {
+ switch (command_getopt(&arg))
+ {
+ case 'h':
+ return command_usage(NULL);
+ case 'i':
+ file = arg;
+ continue;
+ case 'l':
+ if (op != OP_NONE)
+ {
+ goto invalid;
+ }
+ op = OP_LIST;
+ continue;
+ case 'e':
+ if (op != OP_NONE)
+ {
+ goto invalid;
+ }
+ op = OP_EXPORT;
+ index = atoi(arg);
+ continue;
+ case 'f':
+ outform = arg;
+ continue;
+ case EOF:
+ break;
+ default:
+ invalid:
+ return command_usage("invalid --pkcs12 option");
+ }
+ break;
+ }
+
+ if (file)
+ {
+ p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
+ BUILD_FROM_FILE, file, BUILD_END);
+ }
+ else
+ {
+ chunk_t chunk;
+
+ set_file_mode(stdin, CERT_ASN1_DER);
+ if (!chunk_from_fd(0, &chunk))
+ {
+ fprintf(stderr, "reading input failed: %s\n", strerror(errno));
+ return 1;
+ }
+ p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
+ BUILD_BLOB, chunk, BUILD_END);
+ free(chunk.ptr);
+ }
+
+ if (!p12)
+ {
+ fprintf(stderr, "reading input failed!\n");
+ goto end;
+ }
+
+ switch (op)
+ {
+ case OP_LIST:
+ res = show(p12);
+ break;
+ case OP_EXPORT:
+ res = export(p12, index, outform);
+ break;
+ default:
+ p12->container.destroy(&p12->container);
+ return command_usage(NULL);
+ }
+
+end:
+ if (p12)
+ {
+ p12->container.destroy(&p12->container);
+ }
+ return res;
+}
+
+/**
+ * Register the command.
+ */
+static void __attribute__ ((constructor))reg()
+{
+ command_register((command_t) {
+ pkcs12, 'u', "pkcs12", "PKCS#12 functions",
+ {"--export index|--list [--in file]",
+ "[--outform der|pem]"},
+ {
+ {"help", 'h', 0, "show usage information"},
+ {"in", 'i', 1, "input file, default: stdin"},
+ {"list", 'l', 0, "list certificates and keys"},
+ {"export", 'e', 1, "export the credential with the given index"},
+ {"outform", 'f', 1, "encoding of exported credentials, default: der"},
+ }
+ });
+}
diff --git a/src/pki/commands/print.c b/src/pki/commands/print.c
index fb07169bf..fa69de133 100644
--- a/src/pki/commands/print.c
+++ b/src/pki/commands/print.c
@@ -32,9 +32,12 @@
static void print_pubkey(public_key_t *key)
{
chunk_t chunk;
+ key_type_t type;
+
+ type = key->get_type(key);
+ printf("pubkey: %N %d bits%s\n", key_type_names, type,
+ key->get_keysize(key), (type == KEY_BLISS) ? " strength" : "");
- printf("pubkey: %N %d bits\n", key_type_names, key->get_type(key),
- key->get_keysize(key));
if (key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &chunk))
{
printf("keyid: %#B\n", &chunk);
@@ -66,6 +69,22 @@ static void print_key(private_key_t *key)
}
/**
+ * Get a prefix for a named constraint identity type
+ */
+static char* get_type_pfx(identification_t *id)
+{
+ switch (id->get_type(id))
+ {
+ case ID_RFC822_ADDR:
+ return "email:";
+ case ID_FQDN:
+ return "dns:";
+ default:
+ return "";
+ }
+}
+
+/**
* Print X509 specific certificate information
*/
static void print_x509(x509_t *x509)
@@ -202,7 +221,7 @@ static void print_x509(x509_t *x509)
printf("Permitted NameConstraints:\n");
first = FALSE;
}
- printf(" %Y\n", id);
+ printf(" %s%Y\n", get_type_pfx(id), id);
}
enumerator->destroy(enumerator);
first = TRUE;
@@ -214,7 +233,7 @@ static void print_x509(x509_t *x509)
printf("Excluded NameConstraints:\n");
first = FALSE;
}
- printf(" %Y\n", id);
+ printf(" %s%Y\n", get_type_pfx(id), id);
}
enumerator->destroy(enumerator);
@@ -580,6 +599,11 @@ static int print()
type = CRED_PRIVATE_KEY;
subtype = KEY_ECDSA;
}
+ else if (streq(arg, "bliss-priv"))
+ {
+ type = CRED_PRIVATE_KEY;
+ subtype = KEY_BLISS;
+ }
else
{
return command_usage( "invalid input type");
@@ -652,7 +676,7 @@ static void __attribute__ ((constructor))reg()
command_register((command_t)
{ print, 'a', "print",
"print a credential in a human readable form",
- {"[--in file] [--type rsa-priv|ecdsa-priv|pub|x509|crl|ac]"},
+ {"[--in file] [--type rsa-priv|ecdsa-priv|bliss-priv|pub|x509|crl|ac]"},
{
{"help", 'h', 0, "show usage information"},
{"in", 'i', 1, "input file, default: stdin"},
diff --git a/src/pki/commands/pub.c b/src/pki/commands/pub.c
index b8d2f701d..ccc3c4251 100644
--- a/src/pki/commands/pub.c
+++ b/src/pki/commands/pub.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -53,6 +54,11 @@ static int pub()
type = CRED_PRIVATE_KEY;
subtype = KEY_ECDSA;
}
+ else if (streq(arg, "bliss"))
+ {
+ type = CRED_PRIVATE_KEY;
+ subtype = KEY_BLISS;
+ }
else if (streq(arg, "pub"))
{
type = CRED_PUBLIC_KEY;
@@ -183,7 +189,7 @@ static void __attribute__ ((constructor))reg()
command_register((command_t) {
pub, 'p', "pub",
"extract the public key from a private key/certificate",
- {"[--in file|--keyid hex] [--type rsa|ecdsa|pub|pkcs10|x509]",
+ {"[--in file|--keyid hex] [--type rsa|ecdsa|bliss|pub|pkcs10|x509]",
"[--outform der|pem|dnskey|sshkey]"},
{
{"help", 'h', 0, "show usage information"},
diff --git a/src/pki/commands/req.c b/src/pki/commands/req.c
index 023683569..da991b505 100644
--- a/src/pki/commands/req.c
+++ b/src/pki/commands/req.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
- * Copyright (C) 2009 Andreas Steffen
+ * Copyright (C) 2009-2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* HSR Hochschule fuer Technik Rapperswil
*
@@ -30,7 +31,7 @@ static int req()
{
cred_encoding_type_t form = CERT_ASN1_DER;
key_type_t type = KEY_RSA;
- hash_algorithm_t digest = HASH_SHA1;
+ hash_algorithm_t digest = HASH_UNKNOWN;
certificate_t *cert = NULL;
private_key_t *private = NULL;
char *file = NULL, *dn = NULL, *error = NULL;
@@ -57,6 +58,10 @@ static int req()
{
type = KEY_ECDSA;
}
+ else if (streq(arg, "bliss"))
+ {
+ type = KEY_BLISS;
+ }
else
{
error = "invalid input type";
@@ -134,6 +139,10 @@ static int req()
error = "parsing private key failed";
goto end;
}
+ if (digest == HASH_UNKNOWN)
+ {
+ digest = get_default_digest(private);
+ }
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST,
BUILD_SIGNING_KEY, private,
BUILD_SUBJECT, id,
@@ -185,7 +194,7 @@ static void __attribute__ ((constructor))reg()
command_register((command_t) {
req, 'r', "req",
"create a PKCS#10 certificate request",
- {" [--in file] [--type rsa|ecdsa] --dn distinguished-name",
+ {" [--in file] [--type rsa|ecdsa|bliss] --dn distinguished-name",
"[--san subjectAltName]+ [--password challengePassword]",
"[--digest md5|sha1|sha224|sha256|sha384|sha512] [--outform der|pem]"},
{
@@ -195,7 +204,7 @@ static void __attribute__ ((constructor))reg()
{"dn", 'd', 1, "subject distinguished name"},
{"san", 'a', 1, "subjectAltName to include in cert request"},
{"password",'p', 1, "challengePassword to include in cert request"},
- {"digest", 'g', 1, "digest for signature creation, default: sha1"},
+ {"digest", 'g', 1, "digest for signature creation, default: key-specific"},
{"outform", 'f', 1, "encoding of generated request, default: der"},
}
});
diff --git a/src/pki/commands/self.c b/src/pki/commands/self.c
index daefcdc10..a785c2a0c 100644
--- a/src/pki/commands/self.c
+++ b/src/pki/commands/self.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -49,7 +50,7 @@ static int self()
{
cred_encoding_type_t form = CERT_ASN1_DER;
key_type_t type = KEY_RSA;
- hash_algorithm_t digest = HASH_SHA1;
+ hash_algorithm_t digest = HASH_UNKNOWN;
certificate_t *cert = NULL;
private_key_t *private = NULL;
public_key_t *public = NULL;
@@ -57,7 +58,8 @@ static int self()
identification_t *id = NULL;
linked_list_t *san, *ocsp, *permitted, *excluded, *policies, *mappings;
int pathlen = X509_NO_CONSTRAINT, inhibit_any = X509_NO_CONSTRAINT;
- int inhibit_mapping = X509_NO_CONSTRAINT, require_explicit = X509_NO_CONSTRAINT;
+ int inhibit_mapping = X509_NO_CONSTRAINT;
+ int require_explicit = X509_NO_CONSTRAINT;
chunk_t serial = chunk_empty;
chunk_t encoding = chunk_empty;
time_t not_before, not_after, lifetime = 1095 * 24 * 60 * 60;
@@ -88,6 +90,10 @@ static int self()
{
type = KEY_ECDSA;
}
+ else if (streq(arg, "bliss"))
+ {
+ type = KEY_BLISS;
+ }
else
{
error = "invalid input type";
@@ -308,6 +314,10 @@ static int self()
error = "loading private key failed";
goto end;
}
+ if (digest == HASH_UNKNOWN)
+ {
+ digest = get_default_digest(private);
+ }
public = private->get_public_key(private);
if (!public)
{
@@ -407,7 +417,7 @@ static void __attribute__ ((constructor))reg()
command_register((command_t) {
self, 's', "self",
"create a self signed certificate",
- {" [--in file|--keyid hex] [--type rsa|ecdsa]",
+ {" [--in file|--keyid hex] [--type rsa|ecdsa|bliss]",
" --dn distinguished-name [--san subjectAltName]+",
"[--lifetime days] [--serial hex] [--ca] [--ocsp uri]+",
"[--flag serverAuth|clientAuth|crlSign|ocspSigning|msSmartcardLogon]+",
@@ -441,7 +451,7 @@ static void __attribute__ ((constructor))reg()
{"policy-any", 'A', 1, "inhibitAnyPolicy constraint"},
{"flag", 'e', 1, "include extendedKeyUsage flag"},
{"ocsp", 'o', 1, "OCSP AuthorityInfoAccess URI to include"},
- {"digest", 'g', 1, "digest for signature creation, default: sha1"},
+ {"digest", 'g', 1, "digest for signature creation, default: key-specific"},
{"outform", 'f', 1, "encoding of generated cert, default: der"},
}
});
diff --git a/src/pki/commands/signcrl.c b/src/pki/commands/signcrl.c
index e5f49efe2..720dfd8a9 100644
--- a/src/pki/commands/signcrl.c
+++ b/src/pki/commands/signcrl.c
@@ -117,7 +117,7 @@ static int sign_crl()
certificate_t *ca = NULL, *crl = NULL;
crl_t *lastcrl = NULL;
x509_t *x509;
- hash_algorithm_t digest = HASH_SHA1;
+ hash_algorithm_t digest = HASH_UNKNOWN;
char *arg, *cacert = NULL, *cakey = NULL, *lastupdate = NULL, *error = NULL;
char *basecrl = NULL;
char serial[512], *keyid = NULL;
@@ -330,6 +330,10 @@ static int sign_crl()
error = "loading CA private key failed";
goto error;
}
+ if (digest == HASH_UNKNOWN)
+ {
+ digest = get_default_digest(private);
+ }
if (!private->belongs_to(private, public))
{
error = "CA private key does not match CA certificate";
@@ -465,7 +469,7 @@ static void __attribute__ ((constructor))reg()
{"serial", 's', 1, "hex encoded certificate serial number to revoke"},
{"reason", 'r', 1, "reason for certificate revocation"},
{"date", 'd', 1, "revocation date as unix timestamp, default: now"},
- {"digest", 'g', 1, "digest for signature creation, default: sha1"},
+ {"digest", 'g', 1, "digest for signature creation, default: key-specific"},
{"outform", 'f', 1, "encoding of generated crl, default: der"},
}
});
diff --git a/src/pki/man/Makefile.in b/src/pki/man/Makefile.in
index c288015de..45355bacd 100644
--- a/src/pki/man/Makefile.in
+++ b/src/pki/man/Makefile.in
@@ -81,10 +81,11 @@ subdir = src/pki/man
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(srcdir)/pki.1.in $(srcdir)/pki---gen.1.in \
$(srcdir)/pki---issue.1.in $(srcdir)/pki---keyid.1.in \
- $(srcdir)/pki---pkcs7.1.in $(srcdir)/pki---print.1.in \
- $(srcdir)/pki---pub.1.in $(srcdir)/pki---req.1.in \
- $(srcdir)/pki---self.1.in $(srcdir)/pki---signcrl.1.in \
- $(srcdir)/pki---acert.1.in $(srcdir)/pki---verify.1.in
+ $(srcdir)/pki---pkcs7.1.in $(srcdir)/pki---pkcs12.1.in \
+ $(srcdir)/pki---print.1.in $(srcdir)/pki---pub.1.in \
+ $(srcdir)/pki---req.1.in $(srcdir)/pki---self.1.in \
+ $(srcdir)/pki---signcrl.1.in $(srcdir)/pki---acert.1.in \
+ $(srcdir)/pki---verify.1.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/ltoptions.m4 \
@@ -101,8 +102,9 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES = pki.1 pki---gen.1 pki---issue.1 pki---keyid.1 \
- pki---pkcs7.1 pki---print.1 pki---pub.1 pki---req.1 \
- pki---self.1 pki---signcrl.1 pki---acert.1 pki---verify.1
+ pki---pkcs7.1 pki---pkcs12.1 pki---print.1 pki---pub.1 \
+ pki---req.1 pki---self.1 pki---signcrl.1 pki---acert.1 \
+ pki---verify.1
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -181,6 +183,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -241,10 +244,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
PTHREADLIB = @PTHREADLIB@
PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
RUBY = @RUBY@
@@ -318,6 +323,8 @@ json_CFLAGS = @json_CFLAGS@
json_LIBS = @json_LIBS@
libdir = @libdir@
libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
@@ -434,6 +441,8 @@ pki---keyid.1: $(top_builddir)/config.status $(srcdir)/pki---keyid.1.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
pki---pkcs7.1: $(top_builddir)/config.status $(srcdir)/pki---pkcs7.1.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+pki---pkcs12.1: $(top_builddir)/config.status $(srcdir)/pki---pkcs12.1.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
pki---print.1: $(top_builddir)/config.status $(srcdir)/pki---print.1.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
pki---pub.1: $(top_builddir)/config.status $(srcdir)/pki---pub.1.in
diff --git a/src/pki/man/pki---acert.1.in b/src/pki/man/pki---acert.1.in
index ec1d8be6e..d7460fd1f 100644
--- a/src/pki/man/pki---acert.1.in
+++ b/src/pki/man/pki---acert.1.in
@@ -99,8 +99,8 @@ Serial number in hex. It is randomly allocated by default.
.TP
.BI "\-g, \-\-digest " digest
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is
+determined based on the type and size of the signature key.
.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
diff --git a/src/pki/man/pki---issue.1.in b/src/pki/man/pki---issue.1.in
index 375cb2fe4..3a89059c8 100644
--- a/src/pki/man/pki---issue.1.in
+++ b/src/pki/man/pki---issue.1.in
@@ -122,8 +122,8 @@ Add extendedKeyUsage flag. One of \fIserverAuth\fR, \fIclientAuth\fR,
.TP
.BI "\-g, \-\-digest " digest
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is
+determined based on the type and size of the signature key.
.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
@@ -147,10 +147,22 @@ times.
Set path length constraint.
.TP
.BI "\-n, \-\-nc-permitted " name
-Add permitted NameConstraint extension to certificate.
+Add permitted NameConstraint extension to certificate. For DNS or email
+constraints, the identity type is not always detectable by the given name. Use
+the
+.B dns:
+or
+.B email:
+prefix to force a constraint type.
.TP
.BI "\-N, \-\-nc-excluded " name
-Add excluded NameConstraint extension to certificate.
+Add excluded NameConstraint extension to certificate. For DNS or email
+constraints, the identity type is not always detectable by the given name. Use
+the
+.B dns:
+or
+.B email:
+prefix to force a constraint type.
.TP
.BI "\-M, \-\-policy-mapping " issuer-oid:subject-oid
Add policyMapping from issuer to subject OID.
diff --git a/src/pki/man/pki---pkcs12.1.in b/src/pki/man/pki---pkcs12.1.in
new file mode 100644
index 000000000..470a66389
--- /dev/null
+++ b/src/pki/man/pki---pkcs12.1.in
@@ -0,0 +1,62 @@
+.TH "PKI \-\-PKCS12" 1 "2014-10-17" "@PACKAGE_VERSION@" "strongSwan"
+.
+.SH "NAME"
+.
+pki \-\-pkcs12 \- Provides PKCS#12 functions
+.
+.SH "SYNOPSIS"
+.
+.SY pki\ \-\-pkcs12
+.BR \-\-list
+.OP \-\-in file
+.OP \-\-debug level
+.YS
+.
+.SY pki\ \-\-pkcs12
+.BI \-\-export\~ index
+.OP \-\-in file
+.OP \-\-outform encoding
+.OP \-\-debug level
+.YS
+.
+.SY pki\ \-\-pkcs12
+.BI \-\-options\~ file
+.YS
+.
+.SY "pki \-\-pkcs12"
+.B \-h
+|
+.B \-\-help
+.YS
+.
+.SH "DESCRIPTION"
+.
+This sub-command of
+.BR pki (1)
+provides functions to work with PKCS#12 containers.
+.
+.SH "OPTIONS"
+.
+.TP
+.B "\-h, \-\-help"
+Print usage information with a summary of the available options.
+.TP
+.BI "\-v, \-\-debug " level
+Set debug level, default: 1.
+.TP
+.BI "\-+, \-\-options " file
+Read command line options from \fIfile\fR.
+.TP
+.BI "\-l, \-\-list"
+List certificates and keys contained in a PKCS#12 container.
+.TP
+.BI "\-e, \-\-export " index
+Export the credential with the given \fIindex\fR. Use \fI\-\-list\fR to
+determine the index of certificates and keys.
+.TP
+.BI "\-i, \-\-in " file
+PKCS#12 input file. If not given the input is read from \fISTDIN\fR.
+.
+.SH "SEE ALSO"
+.
+.BR pki (1) \ No newline at end of file
diff --git a/src/pki/man/pki---req.1.in b/src/pki/man/pki---req.1.in
index ab144ce2a..a6f6a480a 100644
--- a/src/pki/man/pki---req.1.in
+++ b/src/pki/man/pki---req.1.in
@@ -62,8 +62,8 @@ The challengePassword to include in the certificate request.
.TP
.BI "\-g, \-\-digest " digest
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is
+determined based on the type and size of the signature key.
.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
diff --git a/src/pki/man/pki---self.1.in b/src/pki/man/pki---self.1.in
index 5e6e78bd0..53f53f816 100644
--- a/src/pki/man/pki---self.1.in
+++ b/src/pki/man/pki---self.1.in
@@ -109,8 +109,8 @@ Add extendedKeyUsage flag. One of \fIserverAuth\fR, \fIclientAuth\fR,
.TP
.BI "\-g, \-\-digest " digest
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is
+determined based on the type and size of the signature key.
.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
@@ -127,10 +127,22 @@ times.
Set path length constraint.
.TP
.BI "\-n, \-\-nc-permitted " name
-Add permitted NameConstraint extension to certificate.
+Add permitted NameConstraint extension to certificate. For DNS or email
+constraints, the identity type is not always detectable by the given name. Use
+the
+.B dns:
+or
+.B email:
+prefix to force a constraint type.
.TP
.BI "\-N, \-\-nc-excluded " name
-Add excluded NameConstraint extension to certificate.
+Add excluded NameConstraint extension to certificate. For DNS or email
+constraints, the identity type is not always detectable by the given name. Use
+the
+.B dns:
+or
+.B email:
+prefix to force a constraint type.
.TP
.BI "\-M, \-\-policy-mapping " issuer-oid:subject-oid
Add policyMapping from issuer to subject OID.
diff --git a/src/pki/man/pki---signcrl.1.in b/src/pki/man/pki---signcrl.1.in
index bd6cba547..b930bfa3c 100644
--- a/src/pki/man/pki---signcrl.1.in
+++ b/src/pki/man/pki---signcrl.1.in
@@ -98,8 +98,8 @@ Freshest delta CRL URI to include in CRL. Can be used multiple times.
.TP
.BI "\-g, \-\-digest " digest
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is
+determined based on the type and size of the signature key.
.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
diff --git a/src/pki/pki.c b/src/pki/pki.c
index 434287de6..472704945 100644
--- a/src/pki/pki.c
+++ b/src/pki/pki.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2012-2014 Tobias Brunner
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -22,6 +23,7 @@
#include <fcntl.h>
#include <utils/debug.h>
+#include <credentials/sets/mem_cred.h>
#include <credentials/sets/callback_cred.h>
/**
@@ -235,12 +237,40 @@ void set_file_mode(FILE *stream, cred_encoding_type_t enc)
#endif
}
+/*
+ * Described in header
+ */
+hash_algorithm_t get_default_digest(private_key_t *private)
+{
+ enumerator_t *enumerator;
+ signature_scheme_t scheme;
+ hash_algorithm_t alg = HASH_UNKNOWN;
+
+ enumerator = signature_schemes_for_key(private->get_type(private),
+ private->get_keysize(private));
+ if (enumerator->enumerate(enumerator, &scheme))
+ {
+ alg = hasher_from_signature_scheme(scheme);
+ }
+ enumerator->destroy(enumerator);
+
+ /* default to SHA-256 */
+ return alg == HASH_UNKNOWN ? HASH_SHA256 : alg;
+}
+
/**
* Callback credential set pki uses
*/
static callback_cred_t *cb_set;
/**
+ * Credential set to cache entered secrets
+ */
+static mem_cred_t *cb_creds;
+
+static shared_key_type_t prompted;
+
+/**
* Callback function to receive credentials
*/
static shared_key_t* cb(void *data, shared_key_type_t type,
@@ -248,7 +278,12 @@ static shared_key_t* cb(void *data, shared_key_type_t type,
id_match_t *match_me, id_match_t *match_other)
{
char buf[64], *label, *secret = NULL;
+ shared_key_t *shared;
+ if (prompted == type)
+ {
+ return NULL;
+ }
switch (type)
{
case SHARED_PIN:
@@ -266,6 +301,7 @@ static shared_key_t* cb(void *data, shared_key_type_t type,
#endif
if (secret && strlen(secret))
{
+ prompted = type;
if (match_me)
{
*match_me = ID_MATCH_PERFECT;
@@ -274,8 +310,10 @@ static shared_key_t* cb(void *data, shared_key_type_t type,
{
*match_other = ID_MATCH_NONE;
}
- return shared_key_create(type,
- chunk_clone(chunk_create(secret, strlen(secret))));
+ shared = shared_key_create(type, chunk_clone(chunk_from_str(secret)));
+ /* cache password in case it is required more than once */
+ cb_creds->add_shared(cb_creds, shared, NULL);
+ return shared->get_ref(shared);
}
return NULL;
}
@@ -287,6 +325,8 @@ static void add_callback()
{
cb_set = callback_cred_create_shared(cb, NULL);
lib->credmgr->add_set(lib->credmgr, &cb_set->set);
+ cb_creds = mem_cred_create();
+ lib->credmgr->add_set(lib->credmgr, &cb_creds->set);
}
/**
@@ -294,6 +334,8 @@ static void add_callback()
*/
static void remove_callback()
{
+ lib->credmgr->remove_set(lib->credmgr, &cb_creds->set);
+ cb_creds->destroy(cb_creds);
lib->credmgr->remove_set(lib->credmgr, &cb_set->set);
cb_set->destroy(cb_set);
}
diff --git a/src/pki/pki.h b/src/pki/pki.h
index 1f0827733..017e61df6 100644
--- a/src/pki/pki.h
+++ b/src/pki/pki.h
@@ -55,4 +55,12 @@ bool calculate_lifetime(char *format, char *nbstr, char *nastr, time_t span,
*/
void set_file_mode(FILE *stream, cred_encoding_type_t enc);
+/**
+ * Select default digest for signatures with the given key
+ *
+ * @param private private key
+ * @return hash algorithm
+ */
+hash_algorithm_t get_default_digest(private_key_t *private);
+
#endif /** PKI_H_ @}*/