pkcs11-tool: Let the user choose the ECDSA signature format
Instead of hard-coding the format depending on whether OpenSC was compiled with OpenSSL or not, the user should be able to choose the format himself. The default format now is the normal concatenation of R,S both for CKM_ECDSA and CKM_ECDSA_SHA1.
This commit is contained in:
parent
f93835add9
commit
fa045d44ec
|
@ -166,6 +166,7 @@ static const struct option options[] = {
|
||||||
{ "attr-from", 1, NULL, OPT_ATTR_FROM },
|
{ "attr-from", 1, NULL, OPT_ATTR_FROM },
|
||||||
{ "input-file", 1, NULL, 'i' },
|
{ "input-file", 1, NULL, 'i' },
|
||||||
{ "output-file", 1, NULL, 'o' },
|
{ "output-file", 1, NULL, 'o' },
|
||||||
|
{ "signature-format", 1, NULL, 'f' },
|
||||||
|
|
||||||
{ "test", 0, NULL, 't' },
|
{ "test", 0, NULL, 't' },
|
||||||
{ "test-hotplug", 0, NULL, OPT_TEST_HOTPLUG },
|
{ "test-hotplug", 0, NULL, OPT_TEST_HOTPLUG },
|
||||||
|
@ -223,6 +224,7 @@ static const char *option_help[] = {
|
||||||
"Use <arg> to create some attributes when writing an object",
|
"Use <arg> to create some attributes when writing an object",
|
||||||
"Specify the input file",
|
"Specify the input file",
|
||||||
"Specify the output file",
|
"Specify the output file",
|
||||||
|
"Format for ECDSA signature <arg>: 'rs' (default), 'sequence', 'openssl'",
|
||||||
|
|
||||||
"Test (best used with the --login or --pin option)",
|
"Test (best used with the --login or --pin option)",
|
||||||
"Test hotplug capabilities (C_GetSlotList + C_WaitForSlotEvent)",
|
"Test hotplug capabilities (C_GetSlotList + C_WaitForSlotEvent)",
|
||||||
|
@ -262,6 +264,7 @@ static char * opt_application_id = NULL;
|
||||||
static char * opt_issuer = NULL;
|
static char * opt_issuer = NULL;
|
||||||
static char * opt_subject = NULL;
|
static char * opt_subject = NULL;
|
||||||
static char * opt_key_type = NULL;
|
static char * opt_key_type = NULL;
|
||||||
|
static char * opt_sig_format = NULL;
|
||||||
static int opt_is_private = 0;
|
static int opt_is_private = 0;
|
||||||
static int opt_test_hotplug = 0;
|
static int opt_test_hotplug = 0;
|
||||||
static int opt_login_type = -1;
|
static int opt_login_type = -1;
|
||||||
|
@ -420,7 +423,7 @@ int main(int argc, char * argv[])
|
||||||
CRYPTO_malloc_init();
|
CRYPTO_malloc_init();
|
||||||
#endif
|
#endif
|
||||||
while (1) {
|
while (1) {
|
||||||
c = getopt_long(argc, argv, "ILMOTa:bd:e:hi:klm:o:p:scvty:w:z:r",
|
c = getopt_long(argc, argv, "ILMOTa:bd:e:hi:klm:o:p:scvf:ty:w:z:r",
|
||||||
options, &long_optind);
|
options, &long_optind);
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
|
@ -543,6 +546,9 @@ int main(int argc, char * argv[])
|
||||||
do_sign = 1;
|
do_sign = 1;
|
||||||
action_count++;
|
action_count++;
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
opt_sig_format = optarg;
|
||||||
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
need_session |= NEED_SESSION_RO;
|
need_session |= NEED_SESSION_RO;
|
||||||
do_test = 1;
|
do_test = 1;
|
||||||
|
@ -1424,33 +1430,23 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session,
|
||||||
util_fatal("failed to open %s: %m", opt_output);
|
util_fatal("failed to open %s: %m", opt_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ENABLE_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA)
|
if (opt_mechanism == CKM_ECDSA || opt_mechanism == CKM_ECDSA_SHA1) {
|
||||||
/*
|
if (opt_sig_format && (!strcmp(opt_sig_format, "openssl") || !strcmp(opt_sig_format, "sequence"))) {
|
||||||
* PKCS11 implies the ECDSA sig is 2nLen,
|
unsigned char *seq;
|
||||||
* OpenSSL expects sequence of {integer, integer}
|
size_t seqlen;
|
||||||
* so we will write it for OpenSSL if built with OpenSSL
|
|
||||||
*/
|
|
||||||
if (opt_mechanism == CKM_ECDSA) {
|
|
||||||
int nLen;
|
|
||||||
ECDSA_SIG * ecsig = NULL;
|
|
||||||
unsigned char *p = NULL;
|
|
||||||
int der_len;
|
|
||||||
|
|
||||||
nLen = sig_len/2;
|
if (sc_asn1_sig_value_rs_to_sequence(NULL, sig_buffer, sig_len, &seq, &seqlen)) {
|
||||||
|
util_fatal("Failed to convert signature to ASN.1 sequence format.");
|
||||||
|
}
|
||||||
|
|
||||||
ecsig = ECDSA_SIG_new();
|
memcpy(sig_buffer, seq, seqlen);
|
||||||
ecsig->r = BN_bin2bn(sig_buffer, nLen, ecsig->r);
|
sig_len = seqlen;
|
||||||
ecsig->s = BN_bin2bn(sig_buffer + nLen, nLen, ecsig->s);
|
|
||||||
|
|
||||||
der_len = i2d_ECDSA_SIG(ecsig, &p);
|
free(seq);
|
||||||
printf("Writing OpenSSL ECDSA_SIG\n");
|
}
|
||||||
r = write(fd, p, der_len);
|
}
|
||||||
free(p);
|
|
||||||
ECDSA_SIG_free(ecsig);
|
|
||||||
|
|
||||||
} else
|
|
||||||
#endif /* ENABLE_OPENSSL && !OPENSSL_NO_EC && !OPENSSL_NO_ECDSA */
|
|
||||||
r = write(fd, sig_buffer, sig_len);
|
r = write(fd, sig_buffer, sig_len);
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
util_fatal("Failed to write to %s: %m", opt_output);
|
util_fatal("Failed to write to %s: %m", opt_output);
|
||||||
if (fd != 1)
|
if (fd != 1)
|
||||||
|
|
Loading…
Reference in New Issue