From 2872f7782990e8d1e98f8fa04579425aa9f4b33f Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 17 Mar 2015 14:40:02 +0100 Subject: [PATCH] pki: Choose default digest based on the signature key --- src/pki/commands/acert.c | 8 ++++++-- src/pki/commands/issue.c | 8 ++++++-- src/pki/commands/req.c | 8 ++++++-- src/pki/commands/self.c | 8 ++++++-- src/pki/commands/signcrl.c | 8 ++++++-- src/pki/man/pki---acert.1.in | 4 ++-- src/pki/man/pki---issue.1.in | 4 ++-- src/pki/man/pki---req.1.in | 4 ++-- src/pki/man/pki---self.1.in | 4 ++-- src/pki/man/pki---signcrl.1.in | 4 ++-- src/pki/pki.c | 21 +++++++++++++++++++++ src/pki/pki.h | 8 ++++++++ 12 files changed, 69 insertions(+), 20 deletions(-) diff --git a/src/pki/commands/acert.c b/src/pki/commands/acert.c index 3a35b06d8..7099977f2 100644 --- a/src/pki/commands/acert.c +++ b/src/pki/commands/acert.c @@ -32,7 +32,7 @@ static int acert() { cred_encoding_type_t form = CERT_ASN1_DER; - hash_algorithm_t digest = HASH_SHA256; + hash_algorithm_t digest = HASH_UNKNOWN; certificate_t *ac = NULL, *cert = NULL, *issuer =NULL; private_key_t *private = NULL; public_key_t *public = NULL; @@ -162,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"; @@ -287,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: sha256"}, + {"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/issue.c b/src/pki/commands/issue.c index 050ead77c..6a2d09d78 100644 --- a/src/pki/commands/issue.c +++ b/src/pki/commands/issue.c @@ -60,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_SHA256; + 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; @@ -357,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"; @@ -591,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: sha256"}, + {"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/req.c b/src/pki/commands/req.c index 13ef1c9d8..da991b505 100644 --- a/src/pki/commands/req.c +++ b/src/pki/commands/req.c @@ -31,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_SHA256; + hash_algorithm_t digest = HASH_UNKNOWN; certificate_t *cert = NULL; private_key_t *private = NULL; char *file = NULL, *dn = NULL, *error = NULL; @@ -139,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, @@ -200,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: sha256"}, + {"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 13374e2de..a785c2a0c 100644 --- a/src/pki/commands/self.c +++ b/src/pki/commands/self.c @@ -50,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_SHA256; + hash_algorithm_t digest = HASH_UNKNOWN; certificate_t *cert = NULL; private_key_t *private = NULL; public_key_t *public = NULL; @@ -314,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) { @@ -447,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: sha256"}, + {"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 aa403229f..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_SHA256; + 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: sha256"}, + {"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/pki---acert.1.in b/src/pki/man/pki---acert.1.in index 48a5203ce..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 -\fIsha256\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 d4e20fd9b..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 -\fIsha256\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---req.1.in b/src/pki/man/pki---req.1.in index 397d2e282..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 -\fIsha256\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 da3363202..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 -\fIsha256\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---signcrl.1.in b/src/pki/man/pki---signcrl.1.in index eae3f81c4..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 -\fIsha256\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 16f5325fd..472704945 100644 --- a/src/pki/pki.c +++ b/src/pki/pki.c @@ -237,6 +237,27 @@ 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 */ 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_ @}*/