diff options
Diffstat (limited to 'src/pki')
-rw-r--r-- | src/pki/Makefile.am | 1 | ||||
-rw-r--r-- | src/pki/Makefile.in | 11 | ||||
-rw-r--r-- | src/pki/command.h | 2 | ||||
-rw-r--r-- | src/pki/commands/acert.c | 11 | ||||
-rw-r--r-- | src/pki/commands/gen.c | 14 | ||||
-rw-r--r-- | src/pki/commands/issue.c | 12 | ||||
-rw-r--r-- | src/pki/commands/keyid.c | 7 | ||||
-rw-r--r-- | src/pki/commands/pkcs12.c | 247 | ||||
-rw-r--r-- | src/pki/commands/print.c | 34 | ||||
-rw-r--r-- | src/pki/commands/pub.c | 10 | ||||
-rw-r--r-- | src/pki/commands/req.c | 17 | ||||
-rw-r--r-- | src/pki/commands/self.c | 20 | ||||
-rw-r--r-- | src/pki/commands/signcrl.c | 8 | ||||
-rw-r--r-- | src/pki/man/Makefile.in | 21 | ||||
-rw-r--r-- | src/pki/man/pki---acert.1.in | 4 | ||||
-rw-r--r-- | src/pki/man/pki---issue.1.in | 20 | ||||
-rw-r--r-- | src/pki/man/pki---pkcs12.1.in | 62 | ||||
-rw-r--r-- | src/pki/man/pki---req.1.in | 4 | ||||
-rw-r--r-- | src/pki/man/pki---self.1.in | 20 | ||||
-rw-r--r-- | src/pki/man/pki---signcrl.1.in | 4 | ||||
-rw-r--r-- | src/pki/pki.c | 46 | ||||
-rw-r--r-- | src/pki/pki.h | 8 |
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_ @}*/ |