pki: Choose default digest based on the signature key
authorTobias Brunner <tobias@strongswan.org>
Tue, 17 Mar 2015 13:40:02 +0000 (14:40 +0100)
committerTobias Brunner <tobias@strongswan.org>
Mon, 23 Mar 2015 16:22:31 +0000 (17:22 +0100)
12 files changed:
src/pki/commands/acert.c
src/pki/commands/issue.c
src/pki/commands/req.c
src/pki/commands/self.c
src/pki/commands/signcrl.c
src/pki/man/pki---acert.1.in
src/pki/man/pki---issue.1.in
src/pki/man/pki---req.1.in
src/pki/man/pki---self.1.in
src/pki/man/pki---signcrl.1.in
src/pki/pki.c
src/pki/pki.h

index 3a35b06..7099977 100644 (file)
@@ -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"},
                }
        });
index 050ead7..6a2d09d 100644 (file)
@@ -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"},
                }
        });
index 13ef1c9..da991b5 100644 (file)
@@ -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"},
                }
        });
index 13374e2..a785c2a 100644 (file)
@@ -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"},
                }
        });
index aa40322..720dfd8 100644 (file)
@@ -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"},
                }
        });
index 48a5203..d7460fd 100644 (file)
@@ -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
index d4e20fd..3a89059 100644 (file)
@@ -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
index 397d2e2..a6f6a48 100644 (file)
@@ -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
index da33632..53f53f8 100644 (file)
@@ -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
index eae3f81..b930bfa 100644 (file)
@@ -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
index 16f5325..4727049 100644 (file)
@@ -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
  */
index 1f08277..017e61d 100644 (file)
@@ -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_ @}*/