From 54ee5101177ef7bd2a683a277add1bac584576a1 Mon Sep 17 00:00:00 2001 From: Per Nilsson Date: Mon, 4 Mar 2024 13:54:26 +0100 Subject: [PATCH] Allow any valid encoding of RSA F4 --- ykcs11/mechanisms.c | 4 +--- ykcs11/objects.c | 13 ++++++------- ykcs11/openssl_utils.c | 23 ++++++++++++++++++----- ykcs11/openssl_utils.h | 3 ++- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/ykcs11/mechanisms.c b/ykcs11/mechanisms.c index 21fdd557..5719f54d 100644 --- a/ykcs11/mechanisms.c +++ b/ykcs11/mechanisms.c @@ -37,7 +37,6 @@ #include "utils.h" #include "debug.h" -#define F4 "\x01\x00\x01" #define PRIME256V1 "\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07" #define SECP384R1 "\x06\x05\x2b\x81\x04\x00\x22" @@ -604,8 +603,7 @@ CK_RV check_pubkey_template(gen_info_t *gen, CK_MECHANISM_PTR mechanism, CK_ATTR return CKR_TEMPLATE_INCONSISTENT; } - // Only support F4 - if (templ[i].ulValueLen != 3 || memcmp((CK_BYTE_PTR)templ[i].pValue, F4, 3) != 0) { + if(!do_check_public_exponent(templ[i].pValue, templ[i].ulValueLen)) { DBG("Unsupported public exponent"); return CKR_ATTRIBUTE_VALUE_INVALID; } diff --git a/ykcs11/objects.c b/ykcs11/objects.c index 11593a9a..a88f8bba 100644 --- a/ykcs11/objects.c +++ b/ykcs11/objects.c @@ -37,7 +37,6 @@ #include "utils.h" #include "debug.h" -#define F4 "\x01\x00\x01" // TODO: already define in mechanisms.c. Move #define PRIME256V1 "\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07" // TODO: already define in mechanisms.c. Move #define SECP384R1 "\x06\x05\x2b\x81\x04\x00\x22" // TODO: already define in mechanisms.c. Move @@ -758,9 +757,9 @@ static CK_RV get_proa(ykcs11_slot_t *s, piv_obj_id_t obj, CK_ATTRIBUTE_PTR templ case CKA_PUBLIC_EXPONENT: DBG("PUBLIC EXPONENT"); - len = sizeof(F4) - 1; + len = sizeof(b_tmp); - if ((rv = do_get_public_exponent(s->pkeys[piv_objects[obj].sub_id], b_tmp, len)) != CKR_OK) + if ((rv = do_get_public_exponent(s->pkeys[piv_objects[obj].sub_id], b_tmp, &len)) != CKR_OK) return rv; data = b_tmp; break; @@ -1070,9 +1069,9 @@ static CK_RV get_puoa(ykcs11_slot_t *s, piv_obj_id_t obj, CK_ATTRIBUTE_PTR templ case CKA_PUBLIC_EXPONENT: DBG("PUBLIC EXPONENT"); - len = sizeof(F4) - 1; + len = sizeof(b_tmp); - if ((rv = do_get_public_exponent(s->pkeys[piv_objects[obj].sub_id], b_tmp, len)) != CKR_OK) + if ((rv = do_get_public_exponent(s->pkeys[piv_objects[obj].sub_id], b_tmp, &len)) != CKR_OK) return rv; data = b_tmp; break; @@ -1969,8 +1968,8 @@ CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id, case CKA_PUBLIC_EXPONENT: has_e = CK_TRUE; - if (templ[i].ulValueLen != 3 || memcmp((CK_BYTE_PTR)templ[i].pValue, F4, 3) != 0) { - DBG("CKA_PUBLIC_EXPONENT must be 0x010001"); + if (!do_check_public_exponent(templ[i].pValue, templ[i].ulValueLen)) { + DBG("Unsupported public exponent"); return CKR_ATTRIBUTE_VALUE_INVALID; } break; diff --git a/ykcs11/openssl_utils.c b/ykcs11/openssl_utils.c index ba1293dc..ae801bd7 100644 --- a/ykcs11/openssl_utils.c +++ b/ykcs11/openssl_utils.c @@ -592,20 +592,33 @@ CK_RV do_get_modulus(ykcs11_pkey_t *key, CK_BYTE_PTR data, CK_ULONG len) { return CKR_OK; } -CK_RV do_get_public_exponent(ykcs11_pkey_t *key, CK_BYTE_PTR data, CK_ULONG len) { +CK_BBOOL do_check_public_exponent(CK_BYTE_PTR data, CK_ULONG len) { + BIGNUM *bn = BN_bin2bn(data, len, NULL); + BIGNUM *f4 = BN_new(); + BN_set_word(f4, 0x10001); + CK_BBOOL ret = BN_cmp(bn, f4) ? CK_FALSE : CK_TRUE; + BN_free(f4); + BN_free(bn); + return ret; +} - const RSA *rsa = NULL; - const BIGNUM *bn_e; +CK_RV do_get_public_exponent(ykcs11_pkey_t *key, CK_BYTE_PTR data, CK_ULONG_PTR len) { - rsa = key ? EVP_PKEY_get0_RSA(key) : 0; + const RSA *rsa = key ? EVP_PKEY_get0_RSA(key) : 0; if (rsa == NULL) return CKR_ATTRIBUTE_TYPE_INVALID; + const BIGNUM *bn_e = NULL; RSA_get0_key(rsa, NULL, &bn_e, NULL); - if(BN_bn2binpad(bn_e, data, len) < 0) + if (bn_e == NULL) + return CKR_ATTRIBUTE_TYPE_INVALID; + + if(*len < BN_num_bytes(bn_e)) return CKR_DATA_LEN_RANGE; + *len = BN_bn2bin(bn_e, data); + return CKR_OK; } diff --git a/ykcs11/openssl_utils.h b/ykcs11/openssl_utils.h index b4523479..b3230766 100644 --- a/ykcs11/openssl_utils.h +++ b/ykcs11/openssl_utils.h @@ -60,7 +60,8 @@ CK_ULONG do_get_key_bits(ykcs11_pkey_t *key); CK_ULONG do_get_key_size(ykcs11_pkey_t *key); CK_ULONG do_get_signature_size(ykcs11_pkey_t *key); CK_BYTE do_get_key_algorithm(ykcs11_pkey_t *key); -CK_RV do_get_public_exponent(ykcs11_pkey_t *key, CK_BYTE_PTR data, CK_ULONG len); +CK_BBOOL do_check_public_exponent(CK_BYTE_PTR data, CK_ULONG len); +CK_RV do_get_public_exponent(ykcs11_pkey_t *key, CK_BYTE_PTR data, CK_ULONG_PTR len); CK_RV do_get_public_key(ykcs11_pkey_t *key, CK_BYTE_PTR data, CK_ULONG_PTR len); CK_RV do_get_modulus(ykcs11_pkey_t *key, CK_BYTE_PTR data, CK_ULONG len); CK_RV do_get_curve_parameters(ykcs11_pkey_t *key, CK_BYTE_PTR data, CK_ULONG_PTR len);