|
|
71e593 |
From d64d9cfbe9dc44db04b253aa08c05e645e10708a Mon Sep 17 00:00:00 2001
|
|
|
71e593 |
From: Sumit Bose <sbose@redhat.com>
|
|
|
71e593 |
Date: Fri, 9 Nov 2018 14:01:46 +0100
|
|
|
71e593 |
Subject: [PATCH 70/74] p11_child(openssl): add support for EC keys
|
|
|
71e593 |
|
|
|
71e593 |
Add support for EC keys to the OpenSSL version of p11_child. Please see
|
|
|
71e593 |
comments in the code for some technical details.
|
|
|
71e593 |
|
|
|
71e593 |
Related to https://pagure.io/SSSD/sssd/issue/3887
|
|
|
71e593 |
|
|
|
71e593 |
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
71e593 |
---
|
|
|
71e593 |
src/p11_child/p11_child_openssl.c | 319 +++++++++++++++++++++++++++++-
|
|
|
71e593 |
1 file changed, 309 insertions(+), 10 deletions(-)
|
|
|
71e593 |
|
|
|
71e593 |
diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c
|
|
|
71e593 |
index af55523a7..0f8ba3d3c 100644
|
|
|
71e593 |
--- a/src/p11_child/p11_child_openssl.c
|
|
|
71e593 |
+++ b/src/p11_child/p11_child_openssl.c
|
|
|
71e593 |
@@ -137,6 +137,7 @@ static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host,
|
|
|
71e593 |
#define X509_STORE_get0_objects(store) (store->objs)
|
|
|
71e593 |
#define X509_OBJECT_get_type(object) (object->type)
|
|
|
71e593 |
#define X509_OBJECT_get0_X509(object) (object->data.x509)
|
|
|
71e593 |
+#define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
|
|
71e593 |
#endif
|
|
|
71e593 |
|
|
|
71e593 |
OCSP_RESPONSE *process_responder(OCSP_REQUEST *req,
|
|
|
71e593 |
@@ -860,6 +861,243 @@ done:
|
|
|
71e593 |
return ret;
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
+/* Currently this funtion is only used the print the curve type in the debug
|
|
|
71e593 |
+ * messages. */
|
|
|
71e593 |
+static void get_ec_curve_type(CK_FUNCTION_LIST *module,
|
|
|
71e593 |
+ CK_SESSION_HANDLE session,
|
|
|
71e593 |
+ CK_OBJECT_HANDLE key_handle)
|
|
|
71e593 |
+{
|
|
|
71e593 |
+ CK_ATTRIBUTE attribute;
|
|
|
71e593 |
+ CK_RV rv;
|
|
|
71e593 |
+ EC_GROUP *ec_group;
|
|
|
71e593 |
+ const unsigned char *p;
|
|
|
71e593 |
+ int len;
|
|
|
71e593 |
+ char der_buf[128]; /* FIXME: any other size ?? */
|
|
|
71e593 |
+ char oid_buf[128]; /* FIXME: any other size ?? */
|
|
|
71e593 |
+
|
|
|
71e593 |
+ attribute.type = CKA_ECDSA_PARAMS;
|
|
|
71e593 |
+ attribute.pValue = &der_buf;
|
|
|
71e593 |
+ attribute.ulValueLen = sizeof(der_buf);
|
|
|
71e593 |
+
|
|
|
71e593 |
+ rv = module->C_GetAttributeValue(session, key_handle, &attribute, 1);
|
|
|
71e593 |
+ if (rv != CKR_OK) {
|
|
|
71e593 |
+ free(attribute.pValue);
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
71e593 |
+ "C_GetAttributeValue failed [%lu][%s].\n",
|
|
|
71e593 |
+ rv, p11_kit_strerror(rv));
|
|
|
71e593 |
+ return;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ p = (const unsigned char *) attribute.pValue;
|
|
|
71e593 |
+ ec_group = d2i_ECPKParameters(NULL, &p, attribute.ulValueLen);
|
|
|
71e593 |
+ len = OBJ_obj2txt(oid_buf, sizeof(oid_buf),
|
|
|
71e593 |
+ OBJ_nid2obj(EC_GROUP_get_curve_name(ec_group)), 1);
|
|
|
71e593 |
+ DEBUG(SSSDBG_TRACE_ALL, "Curve name [%s][%s][%.*s].\n",
|
|
|
71e593 |
+ OBJ_nid2sn(EC_GROUP_get_curve_name(ec_group)),
|
|
|
71e593 |
+ OBJ_nid2ln(EC_GROUP_get_curve_name(ec_group)),
|
|
|
71e593 |
+ len, oid_buf);
|
|
|
71e593 |
+
|
|
|
71e593 |
+ return;
|
|
|
71e593 |
+}
|
|
|
71e593 |
+
|
|
|
71e593 |
+static CK_KEY_TYPE get_key_type(CK_FUNCTION_LIST *module,
|
|
|
71e593 |
+ CK_SESSION_HANDLE session,
|
|
|
71e593 |
+ CK_OBJECT_HANDLE key_handle)
|
|
|
71e593 |
+{
|
|
|
71e593 |
+ CK_ATTRIBUTE attribute;
|
|
|
71e593 |
+ CK_RV rv;
|
|
|
71e593 |
+ CK_KEY_TYPE type;
|
|
|
71e593 |
+
|
|
|
71e593 |
+ attribute.type = CKA_KEY_TYPE;
|
|
|
71e593 |
+ attribute.pValue = &type;
|
|
|
71e593 |
+ attribute.ulValueLen = sizeof(CK_KEY_TYPE);
|
|
|
71e593 |
+
|
|
|
71e593 |
+ rv = module->C_GetAttributeValue(session, key_handle, &attribute, 1);
|
|
|
71e593 |
+ if (rv != CKR_OK) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
71e593 |
+ "C_GetAttributeValue failed [%lu][%s].\n",
|
|
|
71e593 |
+ rv, p11_kit_strerror(rv));
|
|
|
71e593 |
+ return CK_UNAVAILABLE_INFORMATION;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ if (attribute.ulValueLen == -1) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
71e593 |
+ "Key type attribute cannot be read.\n");
|
|
|
71e593 |
+ return CK_UNAVAILABLE_INFORMATION;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ if (type == CKK_EC && DEBUG_IS_SET(SSSDBG_TRACE_ALL)) {
|
|
|
71e593 |
+ get_ec_curve_type(module, session, key_handle);
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ return type;
|
|
|
71e593 |
+}
|
|
|
71e593 |
+
|
|
|
71e593 |
+static int do_hash(TALLOC_CTX *mem_ctx, const EVP_MD *evp_md,
|
|
|
71e593 |
+ CK_BYTE *in, size_t in_len,
|
|
|
71e593 |
+ CK_BYTE **hash, size_t *hash_len)
|
|
|
71e593 |
+{
|
|
|
71e593 |
+ EVP_MD_CTX *md_ctx = NULL;
|
|
|
71e593 |
+ int ret;
|
|
|
71e593 |
+ unsigned char md_value[EVP_MAX_MD_SIZE];
|
|
|
71e593 |
+ unsigned int md_len;
|
|
|
71e593 |
+ CK_BYTE *out = NULL;
|
|
|
71e593 |
+
|
|
|
71e593 |
+ md_ctx = EVP_MD_CTX_create();
|
|
|
71e593 |
+ if (md_ctx == NULL) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE, "EVP_MD_CTX_create failed.\n");
|
|
|
71e593 |
+ ret = ENOMEM;
|
|
|
71e593 |
+ goto done;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ ret = EVP_DigestInit(md_ctx, evp_md);
|
|
|
71e593 |
+ if (ret != 1) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE, "EVP_DigestInit failed.\n");
|
|
|
71e593 |
+ ret = EINVAL;
|
|
|
71e593 |
+ goto done;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ ret = EVP_DigestUpdate(md_ctx, in, in_len);
|
|
|
71e593 |
+ if (ret != 1) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE, "EVP_DigestUpdate failed.\n");
|
|
|
71e593 |
+ ret = EINVAL;
|
|
|
71e593 |
+ goto done;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ ret = EVP_DigestFinal_ex(md_ctx, md_value, &md_len);
|
|
|
71e593 |
+ if (ret != 1) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE, "EVP_DigestFinal failed.\n");
|
|
|
71e593 |
+ ret = EINVAL;
|
|
|
71e593 |
+ goto done;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ out = talloc_size(mem_ctx, md_len * sizeof(CK_BYTE));
|
|
|
71e593 |
+ if (out == NULL) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n");
|
|
|
71e593 |
+ ret = ENOMEM;
|
|
|
71e593 |
+ goto done;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ memcpy(out, md_value, md_len);
|
|
|
71e593 |
+
|
|
|
71e593 |
+ *hash = out;
|
|
|
71e593 |
+ *hash_len = md_len;
|
|
|
71e593 |
+
|
|
|
71e593 |
+ ret = EOK;
|
|
|
71e593 |
+
|
|
|
71e593 |
+done:
|
|
|
71e593 |
+
|
|
|
71e593 |
+ if (ret != EOK) {
|
|
|
71e593 |
+ free(out);
|
|
|
71e593 |
+ EVP_MD_CTX_free(md_ctx);
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ return ret;
|
|
|
71e593 |
+}
|
|
|
71e593 |
+
|
|
|
71e593 |
+/* A ECDSA signature consists of 2 integer values r and s. According to the
|
|
|
71e593 |
+ * "PKCS #11 Cryptographic Token Interface Current Mechanisms Specification":
|
|
|
71e593 |
+ *
|
|
|
71e593 |
+ * """
|
|
|
71e593 |
+ * For the purposes of these mechanisms, an ECDSA signature is an octet string
|
|
|
71e593 |
+ * of even length which is at most two times nLen octets, where nLen is the
|
|
|
71e593 |
+ * length in octets of the base point order n. The signature octets correspond
|
|
|
71e593 |
+ * to the concatenation of the ECDSA values r and s, both represented as an
|
|
|
71e593 |
+ * octet string of equal length of at most nLen with the most significant byte
|
|
|
71e593 |
+ * first. If r and s have different octet length, the shorter of both must be
|
|
|
71e593 |
+ * padded with leading zero octets such that both have the same octet length.
|
|
|
71e593 |
+ * Loosely spoken, the first half of the signature is r and the second half is
|
|
|
71e593 |
+ * s. For signatures created by a token, the resulting signature is always of
|
|
|
71e593 |
+ * length 2nLen.
|
|
|
71e593 |
+ * """
|
|
|
71e593 |
+ *
|
|
|
71e593 |
+ * Unfortunately OpenSSL expects the 2 integer values r and s DER encoded as
|
|
|
71e593 |
+ * specified in X9.62 "Public Key Cryptography For The Financial Services
|
|
|
71e593 |
+ * Industry: The Elliptic Curve Digital Signature Algorithm (ECDSA)":
|
|
|
71e593 |
+ *
|
|
|
71e593 |
+ * """
|
|
|
71e593 |
+ * When a digital signature is identified by the OID ecdsa-with-SHA1 , the
|
|
|
71e593 |
+ * digital signature shall be ASN.1 encoded using the following syntax:
|
|
|
71e593 |
+ * ECDSA-Sig-Value ::= SEQUENCE {
|
|
|
71e593 |
+ * r INTEGER,
|
|
|
71e593 |
+ * s INTEGER
|
|
|
71e593 |
+ * }
|
|
|
71e593 |
+ * """
|
|
|
71e593 |
+ *
|
|
|
71e593 |
+ * The following function translates from the PKCS#11 to the X9.62 format by
|
|
|
71e593 |
+ * manually creating the DER sequence after splitting the PKCS#11 signature.
|
|
|
71e593 |
+ * Since r and s are positive values we have to make sure that the leading
|
|
|
71e593 |
+ * bit is not set in the DER encoding by prepending a 0-byte if needed.
|
|
|
71e593 |
+ */
|
|
|
71e593 |
+static int rs_to_seq(TALLOC_CTX *mem_ctx, CK_BYTE *rs_sig, CK_ULONG rs_sig_len,
|
|
|
71e593 |
+ CK_BYTE **seq_sig, CK_ULONG *seq_sig_len)
|
|
|
71e593 |
+{
|
|
|
71e593 |
+ CK_BYTE *r;
|
|
|
71e593 |
+ size_t r_len;
|
|
|
71e593 |
+ CK_BYTE *s;
|
|
|
71e593 |
+ size_t s_len;
|
|
|
71e593 |
+ size_t r_add = 0;
|
|
|
71e593 |
+ size_t s_add = 0;
|
|
|
71e593 |
+ CK_BYTE *out;
|
|
|
71e593 |
+ size_t out_len;
|
|
|
71e593 |
+
|
|
|
71e593 |
+ if (rs_sig_len % 2 != 0) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected signature size [%lu].\n",
|
|
|
71e593 |
+ rs_sig_len);
|
|
|
71e593 |
+ return EINVAL;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ r_len = s_len = rs_sig_len / 2;
|
|
|
71e593 |
+ r = rs_sig;
|
|
|
71e593 |
+ s = rs_sig + r_len;
|
|
|
71e593 |
+
|
|
|
71e593 |
+ /* Remove padding */
|
|
|
71e593 |
+ while(r_len > 1 && *r == 0x00) {
|
|
|
71e593 |
+ r++;
|
|
|
71e593 |
+ r_len--;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+ while(s_len > 1 && *s == 0x00) {
|
|
|
71e593 |
+ s++;
|
|
|
71e593 |
+ s_len--;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ /* r and s are positive, check if the highest bit is set which would
|
|
|
71e593 |
+ * indicate a negative value. In this case a 0x00 must be added. */
|
|
|
71e593 |
+ if ( *r & 0x80 ) {
|
|
|
71e593 |
+ r_add = 1;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+ if ( *s & 0x80 ) {
|
|
|
71e593 |
+ s_add = 1;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ out_len = r_len + r_add + s_len + s_add + 6;
|
|
|
71e593 |
+ out = talloc_size(mem_ctx, out_len * sizeof(CK_BYTE));
|
|
|
71e593 |
+ if (out == NULL) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n");
|
|
|
71e593 |
+ return ENOMEM;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ out[0] = 0x30;
|
|
|
71e593 |
+ out[1] = (CK_BYTE) (out_len - 2);
|
|
|
71e593 |
+ out[2] = 0x02;
|
|
|
71e593 |
+ out[3] = (CK_BYTE) (r_len + r_add);
|
|
|
71e593 |
+ if (r_add == 1) {
|
|
|
71e593 |
+ out[4] = 0x00;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+ memcpy(&out[4 + r_add], r, r_len);
|
|
|
71e593 |
+ out[4 + r_add + r_len] = 0x02;
|
|
|
71e593 |
+ out[5 + r_add + r_len] = (CK_BYTE) (s_len + s_add);
|
|
|
71e593 |
+ if (s_add == 1) {
|
|
|
71e593 |
+ out[6 + r_add + r_len] = 0x00;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+ memcpy(&out[6 + r_add + r_len + s_add], s, s_len);
|
|
|
71e593 |
+
|
|
|
71e593 |
+ *seq_sig = out;
|
|
|
71e593 |
+ *seq_sig_len = out_len;
|
|
|
71e593 |
+
|
|
|
71e593 |
+ return EOK;
|
|
|
71e593 |
+}
|
|
|
71e593 |
+
|
|
|
71e593 |
static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session,
|
|
|
71e593 |
struct cert_list *cert)
|
|
|
71e593 |
{
|
|
|
71e593 |
@@ -870,17 +1108,25 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session,
|
|
|
71e593 |
{CKA_SIGN, &key_sign, sizeof(key_sign)},
|
|
|
71e593 |
{CKA_ID, NULL, 0}
|
|
|
71e593 |
};
|
|
|
71e593 |
- CK_MECHANISM mechanism = { CKM_SHA1_RSA_PKCS, NULL, 0 };
|
|
|
71e593 |
+ CK_MECHANISM mechanism = { CK_UNAVAILABLE_INFORMATION, NULL, 0 };
|
|
|
71e593 |
CK_OBJECT_HANDLE priv_key_object;
|
|
|
71e593 |
CK_ULONG object_count;
|
|
|
71e593 |
CK_BYTE random_value[128];
|
|
|
71e593 |
CK_BYTE *signature = NULL;
|
|
|
71e593 |
CK_ULONG signature_size = 0;
|
|
|
71e593 |
+ CK_BYTE *seq_sig = NULL;
|
|
|
71e593 |
+ CK_ULONG seq_sig_size = 0;
|
|
|
71e593 |
CK_RV rv;
|
|
|
71e593 |
CK_RV rv_f;
|
|
|
71e593 |
EVP_PKEY *cert_pub_key = NULL;
|
|
|
71e593 |
EVP_MD_CTX *md_ctx;
|
|
|
71e593 |
int ret;
|
|
|
71e593 |
+ const EVP_MD *evp_md = NULL;
|
|
|
71e593 |
+ CK_BYTE *hash_val = NULL;
|
|
|
71e593 |
+ size_t hash_len = 0;
|
|
|
71e593 |
+ CK_BYTE *val_to_sign = NULL;
|
|
|
71e593 |
+ size_t val_to_sign_len = 0;
|
|
|
71e593 |
+ bool card_does_hash = false;
|
|
|
71e593 |
|
|
|
71e593 |
key_template[2].pValue = cert->attributes[ATTR_ID].pValue;
|
|
|
71e593 |
key_template[2].ulValueLen = cert->attributes[ATTR_ID].ulValueLen;
|
|
|
71e593 |
@@ -910,9 +1156,31 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session,
|
|
|
71e593 |
return EINVAL;
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
+ switch (get_key_type(module, session, priv_key_object)) {
|
|
|
71e593 |
+ case CKK_RSA:
|
|
|
71e593 |
+ DEBUG(SSSDBG_TRACE_ALL, "Found RSA key using CKM_SHA1_RSA_PKCS.\n");
|
|
|
71e593 |
+ mechanism.mechanism = CKM_SHA1_RSA_PKCS;
|
|
|
71e593 |
+ evp_md = EVP_sha1();
|
|
|
71e593 |
+ card_does_hash = true;
|
|
|
71e593 |
+ break;
|
|
|
71e593 |
+ case CKK_EC:
|
|
|
71e593 |
+ DEBUG(SSSDBG_TRACE_ALL, "Found ECC key using CKM_ECDSA.\n");
|
|
|
71e593 |
+ mechanism.mechanism = CKM_ECDSA;
|
|
|
71e593 |
+ evp_md = EVP_sha1();
|
|
|
71e593 |
+ card_does_hash = false;
|
|
|
71e593 |
+ break;
|
|
|
71e593 |
+ case CK_UNAVAILABLE_INFORMATION:
|
|
|
71e593 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "get_key_type failed.\n");
|
|
|
71e593 |
+ return EIO;
|
|
|
71e593 |
+ break;
|
|
|
71e593 |
+ default:
|
|
|
71e593 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported key type.\n");
|
|
|
71e593 |
+ return EIO;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
rv = module->C_SignInit(session, &mechanism, priv_key_object);
|
|
|
71e593 |
if (rv != CKR_OK) {
|
|
|
71e593 |
- DEBUG(SSSDBG_OP_FAILURE, "C_SignInit failed [%lu][%s].",
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE, "C_SignInit failed [%lu][%s].\n",
|
|
|
71e593 |
rv, p11_kit_strerror(rv));
|
|
|
71e593 |
return EIO;
|
|
|
71e593 |
}
|
|
|
71e593 |
@@ -923,7 +1191,22 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session,
|
|
|
71e593 |
return EINVAL;
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
- rv = module->C_Sign(session, random_value, sizeof(random_value), NULL,
|
|
|
71e593 |
+ if (card_does_hash) {
|
|
|
71e593 |
+ val_to_sign = random_value;
|
|
|
71e593 |
+ val_to_sign_len = sizeof(random_value);
|
|
|
71e593 |
+ } else {
|
|
|
71e593 |
+ ret = do_hash(cert, evp_md, random_value, sizeof(random_value),
|
|
|
71e593 |
+ &hash_val, &hash_len);
|
|
|
71e593 |
+ if (ret != EOK) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "do_hash failed.\n");
|
|
|
71e593 |
+ return ret;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ val_to_sign = hash_val;
|
|
|
71e593 |
+ val_to_sign_len = hash_len;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ rv = module->C_Sign(session, val_to_sign, val_to_sign_len, NULL,
|
|
|
71e593 |
&signature_size);
|
|
|
71e593 |
if (rv != CKR_OK || signature_size == 0) {
|
|
|
71e593 |
DEBUG(SSSDBG_OP_FAILURE, "C_Sign failed [%lu][%s].\n",
|
|
|
71e593 |
@@ -937,7 +1220,7 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session,
|
|
|
71e593 |
return ENOMEM;
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
- rv = module->C_Sign(session, random_value, sizeof(random_value), signature,
|
|
|
71e593 |
+ rv = module->C_Sign(session, val_to_sign, val_to_sign_len, signature,
|
|
|
71e593 |
&signature_size);
|
|
|
71e593 |
if (rv != CKR_OK) {
|
|
|
71e593 |
DEBUG(SSSDBG_OP_FAILURE, "C_Sign failed [%lu][%s].\n",
|
|
|
71e593 |
@@ -958,7 +1241,7 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session,
|
|
|
71e593 |
ret = ENOMEM;
|
|
|
71e593 |
goto done;
|
|
|
71e593 |
}
|
|
|
71e593 |
- ret = EVP_VerifyInit(md_ctx, EVP_sha1());
|
|
|
71e593 |
+ ret = EVP_VerifyInit(md_ctx, evp_md);
|
|
|
71e593 |
if (ret != 1) {
|
|
|
71e593 |
DEBUG(SSSDBG_OP_FAILURE, "EVP_VerifyInit failed.\n");
|
|
|
71e593 |
ret = EINVAL;
|
|
|
71e593 |
@@ -972,11 +1255,27 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session,
|
|
|
71e593 |
goto done;
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
- ret = EVP_VerifyFinal(md_ctx, signature, signature_size, cert_pub_key);
|
|
|
71e593 |
- if (ret != 1) {
|
|
|
71e593 |
- DEBUG(SSSDBG_OP_FAILURE, "EVP_VerifyFinal failed.\n");
|
|
|
71e593 |
- ret = EINVAL;
|
|
|
71e593 |
- goto done;
|
|
|
71e593 |
+ if (mechanism.mechanism == CKM_ECDSA) {
|
|
|
71e593 |
+ ret = rs_to_seq(signature, signature, signature_size,
|
|
|
71e593 |
+ &seq_sig, &seq_sig_size);
|
|
|
71e593 |
+ if (ret != EOK) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "rs_to_seq failed.\n");
|
|
|
71e593 |
+ goto done;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ ret = EVP_VerifyFinal(md_ctx, seq_sig, seq_sig_size, cert_pub_key);
|
|
|
71e593 |
+ if (ret != 1) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE, "EVP_VerifyFinal failed.\n");
|
|
|
71e593 |
+ ret = EINVAL;
|
|
|
71e593 |
+ goto done;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+ } else {
|
|
|
71e593 |
+ ret = EVP_VerifyFinal(md_ctx, signature, signature_size, cert_pub_key);
|
|
|
71e593 |
+ if (ret != 1) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE, "EVP_VerifyFinal failed.\n");
|
|
|
71e593 |
+ ret = EINVAL;
|
|
|
71e593 |
+ goto done;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
ret = EOK;
|
|
|
71e593 |
--
|
|
|
71e593 |
2.19.1
|
|
|
71e593 |
|