pki: Optionally generate RSA/PSS signatures
authorTobias Brunner <tobias@strongswan.org>
Mon, 30 Oct 2017 14:10:46 +0000 (15:10 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 8 Nov 2017 15:48:10 +0000 (16:48 +0100)
13 files changed:
src/pki/command.h
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 449252e..a7dade7 100644 (file)
@@ -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;
index bd8cb43..992237e 100644 (file)
@@ -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,7 @@ static int acert()
        char *datenb = NULL, *datena = NULL, *dateform = NULL;
        rng_t *rng;
        char *arg;
+       bool pss = FALSE;
 
        groups = linked_list_create();
 
@@ -60,6 +62,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 +175,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 +226,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,7 +237,7 @@ static int acert()
                                                        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)
        {
@@ -253,6 +263,7 @@ end:
        DESTROY_IF(public);
        DESTROY_IF(private);
        groups->destroy(groups);
+       signature_params_destroy(scheme);
        free(encoding.ptr);
        free(serial.ptr);
 
@@ -280,6 +291,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"},
@@ -294,6 +306,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"},
                }
        });
index e41c56d..ab6e97b 100644 (file)
@@ -61,12 +61,13 @@ 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;
        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;
@@ -143,6 +144,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 +408,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 +533,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 +551,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 +585,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 +625,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 +658,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"},
                }
        });
index 57f3818..4a63091 100644 (file)
@@ -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,7 @@ static int req()
        chunk_t encoding = chunk_empty;
        chunk_t challenge_password = chunk_empty;
        char *arg;
+       bool pss = FALSE;
 
        san = linked_list_create();
 
@@ -77,6 +79,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 +166,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 +197,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)
@@ -211,17 +223,19 @@ static void __attribute__ ((constructor))reg()
                {"[--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"},
                }
        });
 }
index 6433483..763f047 100644 (file)
@@ -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,7 @@ static int self()
        x509_cert_policy_t *policy = NULL;
        traffic_selector_t *ts;
        char *arg;
+       bool pss = FALSE;
 
        san = linked_list_create();
        ocsp = linked_list_create();
@@ -119,6 +121,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 +348,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 +376,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 +423,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);
 
@@ -450,6 +462,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 +491,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"},
                }
        });
index c7e1035..e0a9a1d 100644 (file)
@@ -120,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;
@@ -133,6 +134,7 @@ static int sign_crl()
        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();
@@ -150,6 +152,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;
@@ -332,10 +345,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";
@@ -390,6 +399,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,
@@ -397,7 +407,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);
@@ -427,6 +437,7 @@ 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);
@@ -458,6 +469,7 @@ static void __attribute__ ((constructor))reg()
                 "           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"},
@@ -476,6 +488,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"},
                }
        });
index c6ecbb9..6c574f2 100644 (file)
@@ -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.
index 99cc64f..8aec653 100644 (file)
@@ -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.
index 09ef086..8f7de24 100644 (file)
@@ -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.
index aa7e6fa..5f7e421 100644 (file)
@@ -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.
index b901ad0..0abd166 100644 (file)
@@ -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.
index 805a795..ec60f7d 100644 (file)
@@ -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,10 +237,10 @@ 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_params_t *params;
@@ -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;
index 54be59f..3f0793c 100644 (file)
@@ -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.