summaryrefslogtreecommitdiff
path: root/src/pki
diff options
context:
space:
mode:
Diffstat (limited to 'src/pki')
-rw-r--r--src/pki/Makefile.in2
-rw-r--r--src/pki/command.c8
-rw-r--r--src/pki/command.h2
-rw-r--r--src/pki/commands/acert.c23
-rw-r--r--src/pki/commands/gen.c2
-rw-r--r--src/pki/commands/issue.c25
-rw-r--r--src/pki/commands/req.c45
-rw-r--r--src/pki/commands/self.c27
-rw-r--r--src/pki/commands/signcrl.c49
-rw-r--r--src/pki/man/Makefile.in2
-rw-r--r--src/pki/man/pki---acert.1.in5
-rw-r--r--src/pki/man/pki---issue.1.in5
-rw-r--r--src/pki/man/pki---req.1.in5
-rw-r--r--src/pki/man/pki---self.1.in5
-rw-r--r--src/pki/man/pki---signcrl.1.in5
-rw-r--r--src/pki/pki.c52
-rw-r--r--src/pki/pki.h14
17 files changed, 206 insertions, 70 deletions
diff --git a/src/pki/Makefile.in b/src/pki/Makefile.in
index 58de24aca..8b369b38d 100644
--- a/src/pki/Makefile.in
+++ b/src/pki/Makefile.in
@@ -265,9 +265,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/pki/command.c b/src/pki/command.c
index ce704dbb8..f425af7e8 100644
--- a/src/pki/command.c
+++ b/src/pki/command.c
@@ -191,7 +191,7 @@ void command_register(command_t command)
int command_usage(char *error)
{
FILE *out = stdout;
- int i;
+ int i, indent = 0;
if (error)
{
@@ -221,12 +221,12 @@ int command_usage(char *error)
{
if (i == 0)
{
- fprintf(out, " pki --%s %s\n",
- cmds[active].cmd, cmds[active].line[i]);
+ indent = fprintf(out, " pki --%s ", cmds[active].cmd);
+ fprintf(out, "%s\n", cmds[active].line[i]);
}
else
{
- fprintf(out, " %s\n", cmds[active].line[i]);
+ fprintf(out, "%*s%s\n", indent, "", cmds[active].line[i]);
}
}
for (i = 0; cmds[active].options[i].name; i++)
diff --git a/src/pki/command.h b/src/pki/command.h
index 449252eb8..a7dade758 100644
--- a/src/pki/command.h
+++ b/src/pki/command.h
@@ -34,7 +34,7 @@
/**
* Maximum number of usage summary lines (+1)
*/
-#define MAX_LINES 11
+#define MAX_LINES 12
typedef struct command_t command_t;
typedef struct command_option_t command_option_t;
diff --git a/src/pki/commands/acert.c b/src/pki/commands/acert.c
index 9e6e80938..d1ea5c65e 100644
--- a/src/pki/commands/acert.c
+++ b/src/pki/commands/acert.c
@@ -33,6 +33,7 @@ static int acert()
{
cred_encoding_type_t form = CERT_ASN1_DER;
hash_algorithm_t digest = HASH_UNKNOWN;
+ signature_params_t *scheme = NULL;
certificate_t *ac = NULL, *cert = NULL, *issuer =NULL;
private_key_t *private = NULL;
public_key_t *public = NULL;
@@ -44,6 +45,8 @@ static int acert()
char *datenb = NULL, *datena = NULL, *dateform = NULL;
rng_t *rng;
char *arg;
+ bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
+ lib->ns);
groups = linked_list_create();
@@ -60,6 +63,17 @@ static int acert()
goto usage;
}
continue;
+ case 'R':
+ if (streq(arg, "pss"))
+ {
+ pss = TRUE;
+ }
+ else if (!streq(arg, "pkcs1"))
+ {
+ error = "invalid RSA padding";
+ goto usage;
+ }
+ continue;
case 'i':
file = arg;
continue;
@@ -162,10 +176,6 @@ 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";
@@ -217,6 +227,7 @@ static int acert()
error = "parsing user certificate failed";
goto end;
}
+ scheme = get_signature_scheme(private, digest, pss);
ac = lib->creds->create(lib->creds,
CRED_CERTIFICATE, CERT_X509_AC,
@@ -227,6 +238,7 @@ static int acert()
BUILD_AC_GROUP_STRINGS, groups,
BUILD_SIGNING_CERT, issuer,
BUILD_SIGNING_KEY, private,
+ BUILD_SIGNATURE_SCHEME, scheme,
BUILD_END);
if (!ac)
{
@@ -252,6 +264,7 @@ end:
DESTROY_IF(public);
DESTROY_IF(private);
groups->destroy(groups);
+ signature_params_destroy(scheme);
free(encoding.ptr);
free(serial.ptr);
@@ -279,6 +292,7 @@ static void __attribute__ ((constructor))reg()
" --issuercert file [--serial hex] [--lifetime hours]",
" [--not-before datetime] [--not-after datetime] [--dateform form]",
"[--digest md5|sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
+ "[--rsa-padding pkcs1|pss]",
"[--outform der|pem]"},
{
{"help", 'h', 0, "show usage information"},
@@ -293,6 +307,7 @@ static void __attribute__ ((constructor))reg()
{"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: key-specific"},
+ {"rsa-padding", 'R', 1, "padding for RSA signatures, default: pkcs1"},
{"outform", 'f', 1, "encoding of generated cert, default: der"},
}
});
diff --git a/src/pki/commands/gen.c b/src/pki/commands/gen.c
index 6f14b5276..203c76542 100644
--- a/src/pki/commands/gen.c
+++ b/src/pki/commands/gen.c
@@ -166,7 +166,7 @@ static void __attribute__ ((constructor))reg()
{
command_register((command_t) {
gen, 'g', "gen", "generate a new private key",
- {" [--type rsa|ecdsa|ed25519|bliss] [--size bits] [--safe-primes]",
+ {"[--type rsa|ecdsa|ed25519|bliss] [--size bits] [--safe-primes]",
"[--shares n] [--threshold l] [--outform der|pem]"},
{
{"help", 'h', 0, "show usage information"},
diff --git a/src/pki/commands/issue.c b/src/pki/commands/issue.c
index e41c56d08..1ccbca89f 100644
--- a/src/pki/commands/issue.c
+++ b/src/pki/commands/issue.c
@@ -61,6 +61,7 @@ static int issue()
{
cred_encoding_type_t form = CERT_ASN1_DER;
hash_algorithm_t digest = HASH_UNKNOWN;
+ signature_params_t *scheme = NULL;
certificate_t *cert_req = NULL, *cert = NULL, *ca =NULL;
private_key_t *private = NULL;
public_key_t *public = NULL;
@@ -84,6 +85,8 @@ static int issue()
x509_cert_policy_t *policy = NULL;
traffic_selector_t *ts;
char *arg;
+ bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
+ lib->ns);
san = linked_list_create();
cdps = linked_list_create();
@@ -143,6 +146,17 @@ static int issue()
goto usage;
}
continue;
+ case 'R':
+ if (streq(arg, "pss"))
+ {
+ pss = TRUE;
+ }
+ else if (!streq(arg, "pkcs1"))
+ {
+ error = "invalid RSA padding";
+ goto usage;
+ }
+ continue;
case 'i':
file = arg;
continue;
@@ -396,10 +410,6 @@ 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";
@@ -525,11 +535,12 @@ static int issue()
id = identification_create_from_encoding(ID_DER_ASN1_DN,
chunk_from_chars(ASN1_SEQUENCE, 0));
}
+ scheme = get_signature_scheme(private, digest, pss);
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_SIGNING_KEY, private, BUILD_SIGNING_CERT, ca,
BUILD_PUBLIC_KEY, public, BUILD_SUBJECT, id,
- BUILD_NOT_BEFORE_TIME, not_before, BUILD_DIGEST_ALG, digest,
+ BUILD_NOT_BEFORE_TIME, not_before,
BUILD_NOT_AFTER_TIME, not_after, BUILD_SERIAL, serial,
BUILD_SUBJECT_ALTNAMES, san, BUILD_X509_FLAG, flags,
BUILD_PATHLEN, pathlen, BUILD_ADDRBLOCKS, addrblocks,
@@ -542,6 +553,7 @@ static int issue()
BUILD_POLICY_REQUIRE_EXPLICIT, require_explicit,
BUILD_POLICY_INHIBIT_MAPPING, inhibit_mapping,
BUILD_POLICY_INHIBIT_ANY, inhibit_any,
+ BUILD_SIGNATURE_SCHEME, scheme,
BUILD_END);
if (!cert)
{
@@ -575,6 +587,7 @@ end:
mappings->destroy_function(mappings, (void*)destroy_policy_mapping);
cdps->destroy_function(cdps, (void*)destroy_cdp);
ocsp->destroy(ocsp);
+ signature_params_destroy(scheme);
free(encoding.ptr);
free(serial.ptr);
@@ -614,6 +627,7 @@ static void __attribute__ ((constructor))reg()
"[--policy-explicit len] [--policy-inhibit len] [--policy-any len]",
"[--cert-policy oid [--cps-uri uri] [--user-notice text]]+",
"[--digest md5|sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
+ "[--rsa-padding pkcs1|pss]",
"[--outform der|pem]"},
{
{"help", 'h', 0, "show usage information"},
@@ -646,6 +660,7 @@ static void __attribute__ ((constructor))reg()
{"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: key-specific"},
+ {"rsa-padding", 'R', 1, "padding for RSA signatures, default: pkcs1"},
{"outform", 'f', 1, "encoding of generated cert, default: der"},
}
});
diff --git a/src/pki/commands/req.c b/src/pki/commands/req.c
index 7b87e6ca6..cfddbc455 100644
--- a/src/pki/commands/req.c
+++ b/src/pki/commands/req.c
@@ -30,6 +30,7 @@ static int req()
cred_encoding_type_t form = CERT_ASN1_DER;
key_type_t type = KEY_ANY;
hash_algorithm_t digest = HASH_UNKNOWN;
+ signature_params_t *scheme = NULL;
certificate_t *cert = NULL;
private_key_t *private = NULL;
char *file = NULL, *keyid = NULL, *dn = NULL, *error = NULL;
@@ -38,6 +39,8 @@ static int req()
chunk_t encoding = chunk_empty;
chunk_t challenge_password = chunk_empty;
char *arg;
+ bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
+ lib->ns);
san = linked_list_create();
@@ -77,6 +80,17 @@ static int req()
goto usage;
}
continue;
+ case 'R':
+ if (streq(arg, "pss"))
+ {
+ pss = TRUE;
+ }
+ else if (!streq(arg, "pkcs1"))
+ {
+ error = "invalid RSA padding";
+ goto usage;
+ }
+ continue;
case 'i':
file = arg;
continue;
@@ -153,16 +167,14 @@ static int req()
error = "parsing private key failed";
goto end;
}
- if (digest == HASH_UNKNOWN)
- {
- digest = get_default_digest(private);
- }
+ scheme = get_signature_scheme(private, digest, pss);
+
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST,
BUILD_SIGNING_KEY, private,
BUILD_SUBJECT, id,
BUILD_SUBJECT_ALTNAMES, san,
BUILD_CHALLENGE_PWD, challenge_password,
- BUILD_DIGEST_ALG, digest,
+ BUILD_SIGNATURE_SCHEME, scheme,
BUILD_END);
if (!cert)
{
@@ -186,6 +198,7 @@ end:
DESTROY_IF(cert);
DESTROY_IF(private);
san->destroy_offset(san, offsetof(identification_t, destroy));
+ signature_params_destroy(scheme);
free(encoding.ptr);
if (error)
@@ -208,20 +221,22 @@ static void __attribute__ ((constructor))reg()
command_register((command_t) {
req, 'r', "req",
"create a PKCS#10 certificate request",
- {" [--in file|--keyid hex] [--type rsa|ecdsa|bliss|priv] --dn distinguished-name",
+ {"[--in file|--keyid hex] [--type rsa|ecdsa|bliss|priv] --dn distinguished-name",
"[--san subjectAltName]+ [--password challengePassword]",
"[--digest md5|sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
+ "[--rsa-padding pkcs1|pss]",
"[--outform der|pem]"},
{
- {"help", 'h', 0, "show usage information"},
- {"in", 'i', 1, "private key input file, default: stdin"},
- {"keyid", 'x', 1, "smartcard or TPM private key object handle"},
- {"type", 't', 1, "type of input key, default: priv"},
- {"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: key-specific"},
- {"outform", 'f', 1, "encoding of generated request, default: der"},
+ {"help", 'h', 0, "show usage information"},
+ {"in", 'i', 1, "private key input file, default: stdin"},
+ {"keyid", 'x', 1, "smartcard or TPM private key object handle"},
+ {"type", 't', 1, "type of input key, default: priv"},
+ {"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: key-specific"},
+ {"rsa-padding", 'R', 1, "padding for RSA signatures, default: pkcs1"},
+ {"outform", 'f', 1, "encoding of generated request, default: der"},
}
});
}
diff --git a/src/pki/commands/self.c b/src/pki/commands/self.c
index bdb22463e..6f7adef0f 100644
--- a/src/pki/commands/self.c
+++ b/src/pki/commands/self.c
@@ -52,6 +52,7 @@ static int self()
cred_encoding_type_t form = CERT_ASN1_DER;
key_type_t type = KEY_ANY;
hash_algorithm_t digest = HASH_UNKNOWN;
+ signature_params_t *scheme = NULL;
certificate_t *cert = NULL;
private_key_t *private = NULL;
public_key_t *public = NULL;
@@ -70,6 +71,8 @@ static int self()
x509_cert_policy_t *policy = NULL;
traffic_selector_t *ts;
char *arg;
+ bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
+ lib->ns);
san = linked_list_create();
ocsp = linked_list_create();
@@ -119,6 +122,17 @@ static int self()
goto usage;
}
continue;
+ case 'R':
+ if (streq(arg, "pss"))
+ {
+ pss = TRUE;
+ }
+ else if (!streq(arg, "pkcs1"))
+ {
+ error = "invalid RSA padding";
+ goto usage;
+ }
+ continue;
case 'i':
file = arg;
continue;
@@ -335,10 +349,6 @@ 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)
{
@@ -367,11 +377,13 @@ static int self()
serial.ptr[0] &= 0x7F;
rng->destroy(rng);
}
+ scheme = get_signature_scheme(private, digest, pss);
+
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_SIGNING_KEY, private, BUILD_PUBLIC_KEY, public,
BUILD_SUBJECT, id, BUILD_NOT_BEFORE_TIME, not_before,
BUILD_NOT_AFTER_TIME, not_after, BUILD_SERIAL, serial,
- BUILD_DIGEST_ALG, digest, BUILD_X509_FLAG, flags,
+ BUILD_SIGNATURE_SCHEME, scheme, BUILD_X509_FLAG, flags,
BUILD_PATHLEN, pathlen, BUILD_SUBJECT_ALTNAMES, san,
BUILD_ADDRBLOCKS, addrblocks,
BUILD_OCSP_ACCESS_LOCATIONS, ocsp,
@@ -412,6 +424,7 @@ end:
policies->destroy_function(policies, (void*)destroy_cert_policy);
mappings->destroy_function(mappings, (void*)destroy_policy_mapping);
ocsp->destroy(ocsp);
+ signature_params_destroy(scheme);
free(encoding.ptr);
free(serial.ptr);
@@ -441,7 +454,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|ed25519|bliss|priv]",
+ {"[--in file|--keyid hex] [--type rsa|ecdsa|ed25519|bliss|priv]",
" --dn distinguished-name [--san subjectAltName]+",
"[--lifetime days] [--serial hex] [--ca] [--ocsp uri]+",
"[--flag serverAuth|clientAuth|crlSign|ocspSigning|msSmartcardLogon]+",
@@ -450,6 +463,7 @@ static void __attribute__ ((constructor))reg()
"[--policy-explicit len] [--policy-inhibit len] [--policy-any len]",
"[--cert-policy oid [--cps-uri uri] [--user-notice text]]+",
"[--digest md5|sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
+ "[--rsa-padding pkcs1|pss]",
"[--outform der|pem]"},
{
{"help", 'h', 0, "show usage information"},
@@ -478,6 +492,7 @@ static void __attribute__ ((constructor))reg()
{"flag", 'e', 1, "include extendedKeyUsage flag"},
{"ocsp", 'o', 1, "OCSP AuthorityInfoAccess URI to include"},
{"digest", 'g', 1, "digest for signature creation, default: key-specific"},
+ {"rsa-padding", 'R', 1, "padding for RSA signatures, default: pkcs1"},
{"outform", 'f', 1, "encoding of generated cert, default: der"},
}
});
diff --git a/src/pki/commands/signcrl.c b/src/pki/commands/signcrl.c
index 25a3aac52..50f939687 100644
--- a/src/pki/commands/signcrl.c
+++ b/src/pki/commands/signcrl.c
@@ -109,15 +109,6 @@ static int read_serial(char *file, char *buf, int buflen)
}
/**
- * Destroy a CDP
- */
-static void cdp_destroy(x509_cdp_t *this)
-{
- free(this->uri);
- free(this);
-}
-
-/**
* Sign a CRL
*/
static int sign_crl()
@@ -129,6 +120,7 @@ static int sign_crl()
crl_t *lastcrl = NULL;
x509_t *x509;
hash_algorithm_t digest = HASH_UNKNOWN;
+ signature_params_t *scheme = NULL;
char *arg, *cacert = NULL, *cakey = NULL, *lastupdate = NULL, *error = NULL;
char *basecrl = NULL;
char serial[512], *keyid = NULL;
@@ -142,6 +134,8 @@ static int sign_crl()
x509_cdp_t *cdp;
chunk_t crl_serial = chunk_empty, baseCrlNumber = chunk_empty;
chunk_t encoding = chunk_empty;
+ bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
+ lib->ns);
list = linked_list_create();
cdps = linked_list_create();
@@ -159,6 +153,17 @@ static int sign_crl()
goto usage;
}
continue;
+ case 'R':
+ if (streq(arg, "pss"))
+ {
+ pss = TRUE;
+ }
+ else if (!streq(arg, "pkcs1"))
+ {
+ error = "invalid RSA padding";
+ goto usage;
+ }
+ continue;
case 'c':
cacert = arg;
continue;
@@ -341,10 +346,6 @@ 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";
@@ -399,6 +400,7 @@ static int sign_crl()
/* increment the serial number by one */
chunk_increment(crl_serial);
+ scheme = get_signature_scheme(private, digest, pss);
enumerator = enumerator_create_filter(list->create_enumerator(list),
filter, NULL, NULL);
crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
@@ -406,7 +408,7 @@ static int sign_crl()
BUILD_SERIAL, crl_serial,
BUILD_NOT_BEFORE_TIME, thisUpdate, BUILD_NOT_AFTER_TIME, nextUpdate,
BUILD_REVOKED_ENUMERATOR, enumerator,
- BUILD_REVOKED_ENUMERATOR, lastenum, BUILD_DIGEST_ALG, digest,
+ BUILD_REVOKED_ENUMERATOR, lastenum, BUILD_SIGNATURE_SCHEME, scheme,
BUILD_CRL_DISTRIBUTION_POINTS, cdps, BUILD_BASE_CRL, baseCrlNumber,
BUILD_END);
enumerator->destroy(enumerator);
@@ -436,10 +438,11 @@ error:
DESTROY_IF(private);
DESTROY_IF(ca);
DESTROY_IF(crl);
+ signature_params_destroy(scheme);
free(encoding.ptr);
free(baseCrlNumber.ptr);
list->destroy_function(list, (void*)revoked_destroy);
- cdps->destroy_function(cdps, (void*)cdp_destroy);
+ cdps->destroy_function(cdps, (void*)x509_cdp_destroy);
if (error)
{
fprintf(stderr, "%s\n", error);
@@ -449,7 +452,7 @@ error:
usage:
list->destroy_function(list, (void*)revoked_destroy);
- cdps->destroy_function(cdps, (void*)cdp_destroy);
+ cdps->destroy_function(cdps, (void*)x509_cdp_destroy);
return command_usage(error);
}
@@ -462,12 +465,13 @@ static void __attribute__ ((constructor))reg()
sign_crl, 'c', "signcrl",
"issue a CRL using a CA certificate and key",
{"--cacert file --cakey file|--cakeyid hex [--lifetime days]",
- " [--lastcrl crl] [--basecrl crl] [--crluri uri]+",
- " [[--reason key-compromise|ca-compromise|affiliation-changed|",
- " superseded|cessation-of-operation|certificate-hold]",
- " [--date timestamp] --cert file|--serial hex]*",
- " [--digest md5|sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
- " [--outform der|pem]"},
+ "[--lastcrl crl] [--basecrl crl] [--crluri uri]+",
+ "[[--reason key-compromise|ca-compromise|affiliation-changed|",
+ " superseded|cessation-of-operation|certificate-hold]",
+ " [--date timestamp] --cert file|--serial hex]*",
+ "[--digest md5|sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
+ "[--rsa-padding pkcs1|pss]",
+ "[--outform der|pem]"},
{
{"help", 'h', 0, "show usage information"},
{"cacert", 'c', 1, "CA certificate file"},
@@ -485,6 +489,7 @@ static void __attribute__ ((constructor))reg()
{"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: key-specific"},
+ {"rsa-padding", 'R', 1, "padding for RSA signatures, default: pkcs1"},
{"outform", 'f', 1, "encoding of generated crl, default: der"},
}
});
diff --git a/src/pki/man/Makefile.in b/src/pki/man/Makefile.in
index bf8092bd4..533dfcab1 100644
--- a/src/pki/man/Makefile.in
+++ b/src/pki/man/Makefile.in
@@ -202,9 +202,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/pki/man/pki---acert.1.in b/src/pki/man/pki---acert.1.in
index c6ecbb989..6c574f273 100644
--- a/src/pki/man/pki---acert.1.in
+++ b/src/pki/man/pki---acert.1.in
@@ -16,6 +16,7 @@ pki \-\-acert \- Issue an attribute certificate
.OP \-\-not-after datetime
.OP \-\-serial hex
.OP \-\-digest digest
+.OP \-\-rsa\-padding padding
.OP \-\-outform encoding
.OP \-\-debug level
.YS
@@ -103,6 +104,10 @@ Digest to use for signature creation. One of \fImd5\fR, \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 "\-R, \-\-rsa\-padding " padding
+Padding to use for RSA signatures. Either \fIpkcs1\fR or \fIpss\fR, defaults
+to \fIpkcs1\fR.
+.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
\fIpem\fR (Base64 PEM), defaults to \fIder\fR.
diff --git a/src/pki/man/pki---issue.1.in b/src/pki/man/pki---issue.1.in
index 99cc64fa5..8aec65306 100644
--- a/src/pki/man/pki---issue.1.in
+++ b/src/pki/man/pki---issue.1.in
@@ -19,6 +19,7 @@ pki \-\-issue \- Issue a certificate using a CA certificate and key
.OP \-\-serial hex
.OP \-\-flag flag
.OP \-\-digest digest
+.OP \-\-rsa\-padding padding
.OP \-\-ca
.OP \-\-crl uri\ \fR[\fB\-\-crlissuer\ \fIissuer\fR]
.OP \-\-ocsp uri
@@ -129,6 +130,10 @@ Digest to use for signature creation. One of \fImd5\fR, \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 "\-R, \-\-rsa\-padding " padding
+Padding to use for RSA signatures. Either \fIpkcs1\fR or \fIpss\fR, defaults
+to \fIpkcs1\fR.
+.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
\fIpem\fR (Base64 PEM), defaults to \fIder\fR.
diff --git a/src/pki/man/pki---req.1.in b/src/pki/man/pki---req.1.in
index 09ef0862a..8f7de248c 100644
--- a/src/pki/man/pki---req.1.in
+++ b/src/pki/man/pki---req.1.in
@@ -15,6 +15,7 @@ pki \-\-req \- Create a PKCS#10 certificate request
.OP \-\-san subjectAltName
.OP \-\-password password
.OP \-\-digest digest
+.OP \-\-rsa\-padding padding
.OP \-\-outform encoding
.OP \-\-debug level
.YS
@@ -72,6 +73,10 @@ Digest to use for signature creation. One of \fImd5\fR, \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 "\-R, \-\-rsa\-padding " padding
+Padding to use for RSA signatures. Either \fIpkcs1\fR or \fIpss\fR, defaults
+to \fIpkcs1\fR.
+.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
\fIpem\fR (Base64 PEM), defaults to \fIder\fR.
diff --git a/src/pki/man/pki---self.1.in b/src/pki/man/pki---self.1.in
index aa7e6fabe..5f7e42108 100644
--- a/src/pki/man/pki---self.1.in
+++ b/src/pki/man/pki---self.1.in
@@ -19,6 +19,7 @@ pki \-\-self \- Create a self-signed certificate
.OP \-\-serial hex
.OP \-\-flag flag
.OP \-\-digest digest
+.OP \-\-rsa\-padding padding
.OP \-\-ca
.OP \-\-ocsp uri
.OP \-\-pathlen len
@@ -115,6 +116,10 @@ Digest to use for signature creation. One of \fImd5\fR, \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 "\-R, \-\-rsa\-padding " padding
+Padding to use for RSA signatures. Either \fIpkcs1\fR or \fIpss\fR, defaults
+to \fIpkcs1\fR.
+.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
\fIpem\fR (Base64 PEM), defaults to \fIder\fR.
diff --git a/src/pki/man/pki---signcrl.1.in b/src/pki/man/pki---signcrl.1.in
index b901ad084..0abd166a9 100644
--- a/src/pki/man/pki---signcrl.1.in
+++ b/src/pki/man/pki---signcrl.1.in
@@ -16,6 +16,7 @@ pki \-\-signcrl \- Issue a Certificate Revocation List (CRL) using a CA certific
.OP \-\-basecrl crl
.OP \-\-crluri uri
.OP \-\-digest digest
+.OP \-\-rsa\-padding padding
.OP \fR[\fB\-\-reason\ \fIreason\fR]\ \fR[\fB\-\-date\ \fIts\fR]\ \fB\-\-cert\ \fIfile\fB|\-\-serial\ \fIhex\fR
.OP \-\-outform encoding
.OP \-\-debug level
@@ -102,6 +103,10 @@ Digest to use for signature creation. One of \fImd5\fR, \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 "\-R, \-\-rsa\-padding " padding
+Padding to use for RSA signatures. Either \fIpkcs1\fR or \fIpss\fR, defaults
+to \fIpkcs1\fR.
+.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
\fIpem\fR (Base64 PEM), defaults to \fIder\fR.
diff --git a/src/pki/pki.c b/src/pki/pki.c
index 0fdab2aab..ec60f7d42 100644
--- a/src/pki/pki.c
+++ b/src/pki/pki.c
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2012-2014 Tobias Brunner
+ * Copyright (C) 2012-2017 Tobias Brunner
* Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * 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
@@ -237,20 +237,20 @@ void set_file_mode(FILE *stream, cred_encoding_type_t enc)
#endif
}
-/*
- * Described in header
+/**
+ * Determine a default hash algorithm for the given key
*/
-hash_algorithm_t get_default_digest(private_key_t *private)
+static hash_algorithm_t get_default_digest(private_key_t *private)
{
enumerator_t *enumerator;
- signature_scheme_t scheme;
+ signature_params_t *params;
hash_algorithm_t alg = HASH_UNKNOWN;
enumerator = signature_schemes_for_key(private->get_type(private),
private->get_keysize(private));
- if (enumerator->enumerate(enumerator, &scheme))
+ if (enumerator->enumerate(enumerator, &params))
{
- alg = hasher_from_signature_scheme(scheme);
+ alg = hasher_from_signature_scheme(params->scheme, params->params);
}
enumerator->destroy(enumerator);
@@ -261,6 +261,42 @@ hash_algorithm_t get_default_digest(private_key_t *private)
/*
* Described in header
*/
+signature_params_t *get_signature_scheme(private_key_t *private,
+ hash_algorithm_t digest, bool pss)
+{
+ signature_params_t *scheme;
+
+ if (digest == HASH_UNKNOWN)
+ {
+ digest = get_default_digest(private);
+ }
+ if (private->get_type(private) == KEY_RSA && pss)
+ {
+ rsa_pss_params_t pss_params = {
+ .hash = digest,
+ .mgf1_hash = digest,
+ .salt_len = RSA_PSS_SALT_LEN_DEFAULT,
+ };
+ signature_params_t pss_scheme = {
+ .scheme = SIGN_RSA_EMSA_PSS,
+ .params = &pss_params,
+ };
+ scheme = signature_params_clone(&pss_scheme);
+ }
+ else
+ {
+ INIT(scheme,
+ .scheme = signature_scheme_from_oid(
+ hasher_signature_algorithm_to_oid(digest,
+ private->get_type(private))),
+ );
+ }
+ return scheme;
+}
+
+/*
+ * Described in header
+ */
traffic_selector_t* parse_ts(char *str)
{
ts_type_t type = TS_IPV4_ADDR_RANGE;
diff --git a/src/pki/pki.h b/src/pki/pki.h
index 54be59f8f..3f0793cfd 100644
--- a/src/pki/pki.h
+++ b/src/pki/pki.h
@@ -1,6 +1,7 @@
/*
+ * Copyright (C) 2015-2017 Tobias Brunner
* Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * 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
@@ -57,12 +58,17 @@ 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
+ * Determine the signature scheme and parameters for the given private key and
+ * hash algorithm and whether to use PSS padding for RSA.
*
* @param private private key
- * @return hash algorithm
+ * @param digest hash algorithm (if HASH_UNKNOWN a default is determined
+ * based on the key)
+ * @param pss use PSS padding for RSA keys
+ * @return allocated signature scheme and parameters
*/
-hash_algorithm_t get_default_digest(private_key_t *private);
+signature_params_t *get_signature_scheme(private_key_t *private,
+ hash_algorithm_t digest, bool pss);
/**
* Create a traffic selector from a CIDR or range string.