From: Nikos Mavrogiannopoulos Date: Wed, 1 Apr 2015 16:29:08 +0000 (+0200) Subject: p11tool: added the --test-sign parameter X-Git-Tag: gnutls_3_4_0~53 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=683f834cc840a9cd4472efe665169be7dda13c7a;p=thirdparty%2Fgnutls.git p11tool: added the --test-sign parameter That allows to check an existing key for signing/verification. --- diff --git a/src/p11tool-args.def b/src/p11tool-args.def index db9f42a3f4..ade9c3e98c 100644 --- a/src/p11tool-args.def +++ b/src/p11tool-args.def @@ -92,6 +92,14 @@ flag = { doc = ""; }; +flag = { + name = test-sign; + descrip = "Tests the signature operation of the provided object"; + doc = "It can be used to test the correct operation of the signature operation. +If both a private and a public key are available this operation will sign and verify +the signed data."; +}; + flag = { name = write; descrip = "Writes the loaded objects to a PKCS #11 token"; diff --git a/src/p11tool.c b/src/p11tool.c index 563fda34ea..105c5b9b5c 100644 --- a/src/p11tool.c +++ b/src/p11tool.c @@ -275,6 +275,8 @@ static void cmd_parser(int argc, char **argv) } else if (HAVE_OPT(WRITE)) { pkcs11_write(outfile, url, label, id, flags, &cinfo); + } else if (HAVE_OPT(TEST_SIGN)) { + pkcs11_test_sign(outfile, url, flags, &cinfo); } else if (HAVE_OPT(INITIALIZE)) pkcs11_init(outfile, url, label, &cinfo); else if (HAVE_OPT(DELETE)) diff --git a/src/p11tool.h b/src/p11tool.h index fe72a4a8a0..e80c875476 100644 --- a/src/p11tool.h +++ b/src/p11tool.h @@ -40,6 +40,8 @@ pkcs11_export_chain(FILE * outfile, const char *url, unsigned int flags, void pkcs11_token_list(FILE * outfile, unsigned int detailed, common_info_st *, unsigned brief); +void pkcs11_test_sign(FILE * outfile, const char *pkcs11_url, + unsigned int flags, common_info_st *); void pkcs11_write(FILE * outfile, const char *pkcs11_url, const char *label, const char *id, unsigned int flags, common_info_st *); diff --git a/src/pkcs11.c b/src/pkcs11.c index b9758874c1..d6cd7440fb 100644 --- a/src/pkcs11.c +++ b/src/pkcs11.c @@ -232,6 +232,105 @@ pkcs11_list(FILE * outfile, const char *url, int type, unsigned int flags, return; } +#define TEST_DATA "Test data to sign" + +void +pkcs11_test_sign(FILE * outfile, const char *url, unsigned int flags, + common_info_st * info) +{ + gnutls_privkey_t privkey; + gnutls_pubkey_t pubkey; + int ret; + gnutls_datum_t data, sig = {NULL, 0}; + int pk; + + pkcs11_common(info); + + FIX(url, outfile, 0, info); + + data.data = (void*)TEST_DATA; + data.size = sizeof(TEST_DATA)-1; + + ret = gnutls_privkey_init(&privkey); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_pubkey_init(&pubkey); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_privkey_import_url(privkey, url, flags); + if (ret < 0) { + fprintf(stderr, "Cannot import private key: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_pubkey_import_privkey(pubkey, privkey, GNUTLS_KEY_DIGITAL_SIGNATURE, flags); + if (ret < 0) { + fprintf(stderr, "Cannot import public key: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, &data, &sig); + if (ret < 0) { + fprintf(stderr, "Cannot sign data: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL); + + fprintf(stderr, "Verifying against private key... "); + ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1), + 0, &data, &sig); + if (ret < 0) { + fprintf(stderr, "Cannot verify signed data: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + fprintf(stderr, "ok\n"); + + /* now try to verify against a public key within the token */ + gnutls_pubkey_deinit(pubkey); + ret = gnutls_pubkey_init(&pubkey); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, + __LINE__, gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_pubkey_import_url(pubkey, url, flags); + if (ret < 0) { + fprintf(stderr, "Cannot import public key: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + fprintf(stderr, "Verifying against public key in the token... "); + ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1), + 0, &data, &sig); + if (ret < 0) { + fprintf(stderr, "Cannot verify signed data: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + fprintf(stderr, "ok\n"); + + gnutls_free(sig.data); + gnutls_pubkey_deinit(pubkey); + gnutls_privkey_deinit(privkey); +} + void pkcs11_export(FILE * outfile, const char *url, unsigned int flags, common_info_st * info)