summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-08-25 10:53:51 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-08-27 15:58:28 +0200
commit8c71c2d9bcd72a9b3b6d0e69fa0a1362d18ce350 (patch)
tree13a1a2299e881edd06e73be823854ed681c5efa8
parent4ef8f85693eeb11279aa418d9ef25a79e32c27ce (diff)
downloadgnutls-8c71c2d9bcd72a9b3b6d0e69fa0a1362d18ce350.tar.gz
p11tool: allow signing with RSA-PSS and specifying an explicit hash
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--src/p11tool-args.def16
-rw-r--r--src/p11tool.c11
-rw-r--r--src/pkcs11.c38
3 files changed, 59 insertions, 6 deletions
diff --git a/src/p11tool-args.def b/src/p11tool-args.def
index ded9f3e3e7..be97aeddc8 100644
--- a/src/p11tool-args.def
+++ b/src/p11tool-args.def
@@ -424,6 +424,22 @@ the signed data.";
};
flag = {
+ name = sign-params;
+ arg-type = string;
+ descrip = "Sign with a specific signature algorithm";
+ doc = "This option can be combined with --test-sign, to sign with
+a specific signature algorithm variant. The only option supported is 'RSA-PSS', and should be
+specified in order to use RSA-PSS signature on RSA keys.";
+};
+
+flag = {
+ name = hash;
+ arg-type = string;
+ descrip = "Hash algorithm to use for signing";
+ doc = "This option can be combined with test-sign. Available hash functions are SHA1, RMD160, SHA256, SHA384, SHA512, SHA3-224, SHA3-256, SHA3-384, SHA3-512.";
+};
+
+flag = {
name = generate-random;
descrip = "Generate random data";
arg-type = number;
diff --git a/src/p11tool.c b/src/p11tool.c
index a149756281..2e9c80074c 100644
--- a/src/p11tool.c
+++ b/src/p11tool.c
@@ -202,6 +202,17 @@ static void cmd_parser(int argc, char **argv)
memset(&cinfo, 0, sizeof(cinfo));
+ if (HAVE_OPT(HASH)) {
+ cinfo.hash = hash_to_id(OPT_ARG(HASH));
+ if (cinfo.hash == GNUTLS_DIG_UNKNOWN) {
+ fprintf(stderr, "invalid hash: %s\n", OPT_ARG(HASH));
+ app_exit(1);
+ }
+ }
+
+ if (HAVE_OPT(SIGN_PARAMS))
+ sign_params_to_flags(&cinfo, OPT_ARG(SIGN_PARAMS));
+
if (HAVE_OPT(SECRET_KEY))
cinfo.secret_key = OPT_ARG(SECRET_KEY);
diff --git a/src/pkcs11.c b/src/pkcs11.c
index ab2b81d601..4453343941 100644
--- a/src/pkcs11.c
+++ b/src/pkcs11.c
@@ -262,6 +262,8 @@ pkcs11_test_sign(FILE * outfile, const char *url, unsigned int flags,
int ret;
gnutls_datum_t data, sig = {NULL, 0};
int pk;
+ gnutls_digest_algorithm_t hash;
+ gnutls_sign_algorithm_t sig_algo;
pkcs11_common(info);
@@ -298,18 +300,42 @@ pkcs11_test_sign(FILE * outfile, const char *url, unsigned int flags,
app_exit(1);
}
- ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0, &data, &sig);
+ pk = gnutls_privkey_get_pk_algorithm(privkey, NULL);
+
+ if (info->hash == GNUTLS_DIG_UNKNOWN)
+ hash = GNUTLS_DIG_SHA256;
+ else
+ hash = info->hash;
+
+ if (info->rsa_pss_sign && pk == GNUTLS_PK_RSA)
+ pk = GNUTLS_PK_RSA_PSS;
+
+ sig_algo = gnutls_pk_to_sign(pk, hash);
+ if (sig_algo == GNUTLS_SIGN_UNKNOWN) {
+ fprintf(stderr, "No supported signature algorithm for %s and %s\n",
+ gnutls_pk_get_name(pk), gnutls_digest_get_name(hash));
+ app_exit(1);
+ }
+
+ fprintf(stderr, "Signing using %s... ", gnutls_sign_get_name(sig_algo));
+
+ ret = gnutls_privkey_sign_data2(privkey, sig_algo, 0, &data, &sig);
if (ret < 0) {
fprintf(stderr, "Cannot sign data: %s\n",
gnutls_strerror(ret));
+ /* in case of unsupported signature algorithm allow
+ * calling apps to distinguish error codes (used
+ * by testpkcs11.sh */
+ if (ret == GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM)
+ app_exit(2);
app_exit(1);
}
- pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);
+ fprintf(stderr, "ok\n");
fprintf(stderr, "Verifying against private key parameters... ");
- ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA256),
- 0, &data, &sig);
+ ret = gnutls_pubkey_verify_data2(pubkey, sig_algo,
+ 0, &data, &sig);
if (ret < 0) {
fprintf(stderr, "Cannot verify signed data: %s\n",
gnutls_strerror(ret));
@@ -337,8 +363,8 @@ pkcs11_test_sign(FILE * outfile, const char *url, unsigned int flags,
}
fprintf(stderr, "Verifying against public key in the token... ");
- ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA256),
- 0, &data, &sig);
+ ret = gnutls_pubkey_verify_data2(pubkey, sig_algo,
+ 0, &data, &sig);
if (ret < 0) {
fprintf(stderr, "Cannot verify signed data: %s\n",
gnutls_strerror(ret));