/**
* 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;
{
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;
char *datenb = NULL, *datena = NULL, *dateform = NULL;
rng_t *rng;
char *arg;
+ bool pss = FALSE;
groups = linked_list_create();
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;
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";
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,
BUILD_AC_GROUP_STRINGS, groups,
BUILD_SIGNING_CERT, issuer,
BUILD_SIGNING_KEY, private,
- BUILD_DIGEST_ALG, digest,
+ BUILD_SIGNATURE_SCHEME, scheme,
BUILD_END);
if (!ac)
{
DESTROY_IF(public);
DESTROY_IF(private);
groups->destroy(groups);
+ signature_params_destroy(scheme);
free(encoding.ptr);
free(serial.ptr);
" --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"},
{"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"},
}
});
{
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;
credential_type_t type = CRED_PUBLIC_KEY;
key_type_t subtype = KEY_ANY;
- bool pkcs10 = FALSE;
+ bool pkcs10 = FALSE, pss = FALSE;
char *file = NULL, *dn = NULL, *hex = NULL, *cacert = NULL, *cakey = NULL;
char *error = NULL, *keyid = NULL;
identification_t *id = NULL;
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;
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";
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,
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)
{
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);
"[--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"},
{"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"},
}
});
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;
chunk_t encoding = chunk_empty;
chunk_t challenge_password = chunk_empty;
char *arg;
+ bool pss = FALSE;
san = linked_list_create();
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;
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)
{
DESTROY_IF(cert);
DESTROY_IF(private);
san->destroy_offset(san, offsetof(identification_t, destroy));
+ signature_params_destroy(scheme);
free(encoding.ptr);
if (error)
{"[--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"},
}
});
}
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;
x509_cert_policy_t *policy = NULL;
traffic_selector_t *ts;
char *arg;
+ bool pss = FALSE;
san = linked_list_create();
ocsp = linked_list_create();
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;
error = "loading private key failed";
goto end;
}
- if (digest == HASH_UNKNOWN)
- {
- digest = get_default_digest(private);
- }
public = private->get_public_key(private);
if (!public)
{
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,
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);
"[--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"},
{"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"},
}
});
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;
x509_cdp_t *cdp;
chunk_t crl_serial = chunk_empty, baseCrlNumber = chunk_empty;
chunk_t encoding = chunk_empty;
+ bool pss = FALSE;
list = linked_list_create();
cdps = linked_list_create();
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;
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";
/* 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,
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);
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);
" 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"},
{"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"},
}
});
.OP \-\-not-after datetime
.OP \-\-serial hex
.OP \-\-digest digest
+.OP \-\-rsa\-padding padding
.OP \-\-outform encoding
.OP \-\-debug level
.YS
\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.
.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
\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.
.OP \-\-san subjectAltName
.OP \-\-password password
.OP \-\-digest digest
+.OP \-\-rsa\-padding padding
.OP \-\-outform encoding
.OP \-\-debug level
.YS
\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.
.OP \-\-serial hex
.OP \-\-flag flag
.OP \-\-digest digest
+.OP \-\-rsa\-padding padding
.OP \-\-ca
.OP \-\-ocsp uri
.OP \-\-pathlen len
\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.
.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
\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.
/*
- * 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
#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_params_t *params;
/*
* 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;
/*
+ * 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
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.