From cb39b2dcc91943ca755661f35a954486b5d0fbde Mon Sep 17 00:00:00 2001 From: vtarasov Date: Sun, 22 May 2011 07:13:09 +0000 Subject: [PATCH] pkcs11-tool: when doing signature try at first the procedure for the short input data ... Not all PKCS#11 driver support the C_SignUpdate. So, for the short data begin with procedure "C_SignInit & C_Sign". If no success, try to applicate the procedure "C_SignInit & C_SignUpdate & ... & C_SignFinal". git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@5458 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/tools/pkcs11-tool.c | 57 ++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 2fff4750..b8035b31 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1207,43 +1207,60 @@ static int unlock_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess, int login_type) static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) { - unsigned char buffer[512]; + unsigned char in_buffer[1025], sig_buffer[512]; CK_MECHANISM mech; CK_RV rv; CK_ULONG sig_len; int fd, r; - if (!opt_mechanism_used) { + if (!opt_mechanism_used) opt_mechanism = find_mechanism(slot, CKF_SIGN|CKF_HW, 1, &opt_mechanism); - printf("Using signature algorithm %s\n", - p11_mechanism_to_name(opt_mechanism)); - } + printf("Using signature algorithm %s\n", p11_mechanism_to_name(opt_mechanism)); memset(&mech, 0, sizeof(mech)); mech.mechanism = opt_mechanism; - rv = p11->C_SignInit(session, &mech, key); - if (rv != CKR_OK) - p11_fatal("C_SignInit", rv); - if (opt_input == NULL) fd = 0; else if ((fd = open(opt_input, O_RDONLY|O_BINARY)) < 0) util_fatal("Cannot open %s: %m", opt_input); + + r = read(fd, in_buffer, sizeof(in_buffer)); + if (r < 0) + util_fatal("Cannot read from %s: %m", opt_input); - while ((r = read(fd, buffer, sizeof(buffer))) > 0) { - rv = p11->C_SignUpdate(session, buffer, r); + rv = CKR_CANCEL; + if (r < sizeof(in_buffer)) { + rv = p11->C_SignInit(session, &mech, key); if (rv != CKR_OK) - p11_fatal("C_SignUpdate", rv); + p11_fatal("C_SignInit", rv); + + sig_len = sizeof(sig_buffer); + rv = p11->C_Sign(session, in_buffer, r, sig_buffer, &sig_len); } + + if (rv != CKR_OK) { + rv = p11->C_SignInit(session, &mech, key); + if (rv != CKR_OK) + p11_fatal("C_SignInit", rv); + + do { + rv = p11->C_SignUpdate(session, in_buffer, r); + if (rv != CKR_OK) + p11_fatal("C_SignUpdate", rv); + + r = read(fd, in_buffer, sizeof(in_buffer)); + } while (r > 0); + + sig_len = sizeof(sig_buffer); + rv = p11->C_SignFinal(session, sig_buffer, &sig_len); + if (rv != CKR_OK) + p11_fatal("C_SignFinal", rv); + } + if (fd != 0) close(fd); - sig_len = sizeof(buffer); - rv = p11->C_SignFinal(session, buffer, &sig_len); - if (rv != CKR_OK) - p11_fatal("C_SignFinal", rv); - if (opt_output == NULL) fd = 1; else if ((fd = open(opt_output, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, S_IRUSR|S_IWUSR)) < 0) { @@ -1265,8 +1282,8 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, nLen = sig_len/2; ecsig = ECDSA_SIG_new(); - ecsig->r = BN_bin2bn(buffer, nLen, ecsig->r); - ecsig->s = BN_bin2bn(buffer + nLen, nLen, ecsig->s); + ecsig->r = BN_bin2bn(sig_buffer, nLen, ecsig->r); + ecsig->s = BN_bin2bn(sig_buffer + nLen, nLen, ecsig->s); der_len = i2d_ECDSA_SIG(ecsig, &p); printf("Writing OpenSSL ECDSA_SIG\n"); @@ -1276,7 +1293,7 @@ static void sign_data(CK_SLOT_ID slot, CK_SESSION_HANDLE session, } else #endif /* ENABLE_OPENSSL && !OPENSSL_NO_EC && !OPENSSL_NO_ECDSA */ - r = write(fd, buffer, sig_len); + r = write(fd, sig_buffer, sig_len); if (r < 0) util_fatal("Failed to write to %s: %m", opt_output); if (fd != 1)