Skip to content

Commit aaffe9a

Browse files
authored
Merge pull request #124 from padelsbach/wp_rsa_bind9_tests
Add test cases for EVP_PKEY_fromdata, fix incompatibility in wp_rsa_mport_key_data().
2 parents 1d1b1b3 + b401bb5 commit aaffe9a

File tree

7 files changed

+222
-34
lines changed

7 files changed

+222
-34
lines changed

include/wolfprovider/wp_params.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,6 @@ int wp_params_set_mp(OSSL_PARAM params[], const char* key, mp_int* mp,
7575
int allow);
7676
int wp_params_set_octet_string_be(OSSL_PARAM params[], const char* key,
7777
unsigned char* data, size_t len);
78-
78+
int wp_params_count(const OSSL_PARAM *p);
7979
#endif /* WP_PARAMS_H */
8080

scripts/utils-wolfssl.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ install_wolfssl() {
8181
CONF_ARGS="-prefix=${WOLFSSL_INSTALL_DIR}"
8282

8383
if [ "$WOLFPROV_DEBUG" = "1" ]; then
84-
CONF_ARGS+=" --enable-debug --enable-debug-trace-errcodes=backtrace --enable-keylog-export"
84+
CONF_ARGS+=" --enable-debug --enable-keylog-export"
85+
if [[ "$OSTYPE" != "darwin"* ]]; then
86+
# macOS doesn't support backtrace
87+
CONF_ARGS+=" --enable-debug-trace-errcodes=backtrace"
88+
fi
8589
WOLFSSL_CONFIG_CFLAGS+=" -DWOLFSSL_LOGGINGENABLED_DEFAULT=1"
8690
fi
8791
if [ -n "$WOLFSSL_FIPS_BUNDLE" ]; then

src/wp_params.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,3 +662,18 @@ int wp_params_set_octet_string_be(OSSL_PARAM params[], const char* key,
662662
return ok;
663663
}
664664

665+
/**
666+
* Count the number of parameters in the array, not including the end marker.
667+
*
668+
* @param [in] params Array of parameters.
669+
* @return number of parameters in the array.
670+
*/
671+
int wp_params_count(const OSSL_PARAM *p)
672+
{
673+
int cnt = 0;
674+
while ((p != NULL) && (p->key != NULL)) {
675+
cnt++;
676+
p++;
677+
}
678+
return cnt;
679+
}

src/wp_rsa_kmgmt.c

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, NULL, 0)
7777
#define OFFSETOF(type, field) ((size_t)&(((type *)0)->field))
7878
#endif
7979

80+
#ifndef ARRAY_SIZE
81+
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
82+
#endif
8083

8184
/** SHA-256 Algorithm ID DER encoding in PSS parameters. */
8285
static const byte sha256AlgId[] = {
@@ -1064,16 +1067,6 @@ static int wp_rsa_validate(const wp_Rsa* rsa, int selection, int checkType)
10641067
return ok;
10651068
}
10661069

1067-
static int wp_params_count(const OSSL_PARAM *p)
1068-
{
1069-
int cnt = 0;
1070-
while ((p != NULL) && (p->key != NULL)) {
1071-
cnt++;
1072-
p++;
1073-
}
1074-
return cnt;
1075-
}
1076-
10771070
/**
10781071
* Import the key data into RSA key object from parameters.
10791072
*
@@ -1087,28 +1080,48 @@ static int wp_rsa_import_key_data(wp_Rsa* rsa, const OSSL_PARAM params[],
10871080
int priv)
10881081
{
10891082
int ok = 1;
1090-
int i;
1091-
int cnt;
1092-
1093-
if (priv && (wp_params_count(params) > 2)) {
1094-
cnt = WP_RSA_PARAM_NUMS_CNT;
1095-
rsa->key.type = RSA_PRIVATE;
1096-
}
1097-
else {
1098-
cnt = WP_RSA_PARAM_PUB_NUMS_CNT;
1099-
rsa->key.type = RSA_PUBLIC;
1083+
int i, j, index = -1;
1084+
int cnt = 0;
1085+
mp_int* mp = NULL;
1086+
const OSSL_PARAM* p = NULL;
1087+
1088+
/* N and E params are the only ones required by OSSL, so match that.
1089+
* See ossl_rsa_fromdata() and RSA_set0_key() in OpenSSL. */
1090+
if (OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_N) == NULL ||
1091+
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E) == NULL) {
1092+
WOLFPROV_MSG(WP_LOG_PK, "Param N or E is missing");
1093+
ok = 0;
11001094
}
11011095

1102-
for (i = 0; ok && (i < cnt); i++) {
1103-
const OSSL_PARAM* p = OSSL_PARAM_locate_const(params,
1104-
wp_rsa_param_key[i]);
1105-
if (p == NULL) {
1106-
ok = 0;
1107-
}
1108-
if (ok) {
1109-
mp_int* mp = (mp_int*)(((byte*)&rsa->key) + wp_rsa_offset[i]);
1110-
if (!wp_mp_read_unsigned_bin_le(mp, p->data, p->data_size)) {
1111-
ok = 0;
1096+
if (ok) {
1097+
cnt = wp_params_count(params);
1098+
rsa->key.type = priv ? RSA_PRIVATE : RSA_PUBLIC;
1099+
1100+
for (i = 0; i < cnt; i++) {
1101+
/* Use the table to look up the offset in the rsa struct */
1102+
p = &params[i];
1103+
index = -1;
1104+
for (j = 0; j < (int)ARRAY_SIZE(wp_rsa_param_key); j++) {
1105+
if (XSTRNCMP(p->key, wp_rsa_param_key[j], p->data_size) == 0) {
1106+
index = j;
1107+
break;
1108+
}
1109+
}
1110+
if (index < 0) {
1111+
/* Follow OSSL implementation and ignore irrelevant fields. */
1112+
WOLFPROV_MSG(WP_LOG_PK, "Unexpected param %s, skipping.",
1113+
p->key);
1114+
continue;
1115+
}
1116+
1117+
/* Read the value into the rsa struct */
1118+
if (ok) {
1119+
mp = (mp_int*)(((byte*)&rsa->key) + wp_rsa_offset[index]);
1120+
if (!wp_mp_read_unsigned_bin_le(mp, p->data, p->data_size)) {
1121+
WOLFPROV_MSG(WP_LOG_PK,
1122+
"Failed to read %s from parameters", p->key);
1123+
ok = 0;
1124+
}
11121125
}
11131126
}
11141127
}

test/test_rsa.c

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626

2727
#ifdef WP_HAVE_RSA
2828

29+
#ifndef ARRAY_SIZE
30+
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
31+
#endif
32+
2933
static const unsigned char rsa_key_der_256[] =
3034
{
3135
0x30, 0x81, 0xC1, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86,
@@ -1025,4 +1029,154 @@ int test_rsa_load_cert(void* data)
10251029
OSSL_STORE_close(ctx);
10261030
return err;
10271031
}
1032+
1033+
int test_rsa_fromdata(void* data)
1034+
{
1035+
(void)data;
1036+
int err = 0;
1037+
EVP_PKEY_CTX *ctx_wolf = NULL;
1038+
EVP_PKEY_CTX *ctx_ossl = NULL;
1039+
1040+
PRINT_MSG("Testing EVP_PKEY_fromdata");
1041+
1042+
ctx_wolf = EVP_PKEY_CTX_new_from_name(wpLibCtx, "RSA", NULL);
1043+
ctx_ossl = EVP_PKEY_CTX_new_from_name(osslLibCtx, "RSA", NULL);
1044+
if (ctx_wolf == NULL || ctx_ossl == NULL) {
1045+
err = 1;
1046+
}
1047+
1048+
if (err == 0) {
1049+
/* EVP_PKEY_fromdata_init returns 1 on success */
1050+
err |= EVP_PKEY_fromdata_init(ctx_wolf) != 1;
1051+
err |= EVP_PKEY_fromdata_init(ctx_ossl) != 1;
1052+
}
1053+
1054+
if (err == 0) {
1055+
EVP_PKEY *pkey_wolf = NULL;
1056+
EVP_PKEY *pkey_ossl = NULL;
1057+
1058+
/* Permutations of the selection field to test */
1059+
static const int selections[] = {
1060+
EVP_PKEY_KEYPAIR,
1061+
EVP_PKEY_PUBLIC_KEY,
1062+
EVP_PKEY_PRIVATE_KEY,
1063+
};
1064+
1065+
/* Parameter data fields */
1066+
unsigned long rsa_n = 0xbc747fc5;
1067+
unsigned long rsa_e = 0x10001;
1068+
unsigned long rsa_d = 0x7b133399;
1069+
const char *foo = "some string";
1070+
size_t foo_l = strlen(foo);
1071+
const char bar[] = "some other string";
1072+
1073+
/* Permutations of the params field to test */
1074+
OSSL_PARAM params_none[] = {
1075+
OSSL_PARAM_END
1076+
};
1077+
OSSL_PARAM params_n[] = {
1078+
OSSL_PARAM_ulong("n", &rsa_n),
1079+
OSSL_PARAM_END
1080+
};
1081+
OSSL_PARAM params_e[] = {
1082+
OSSL_PARAM_ulong("e", &rsa_e),
1083+
OSSL_PARAM_END
1084+
};
1085+
OSSL_PARAM params_d[] = {
1086+
OSSL_PARAM_ulong("d", &rsa_d),
1087+
OSSL_PARAM_END
1088+
};
1089+
OSSL_PARAM params_ne[] = {
1090+
OSSL_PARAM_ulong("n", &rsa_n),
1091+
OSSL_PARAM_ulong("e", &rsa_e),
1092+
OSSL_PARAM_END
1093+
};
1094+
OSSL_PARAM params_nd[] = {
1095+
OSSL_PARAM_ulong("n", &rsa_n),
1096+
OSSL_PARAM_ulong("d", &rsa_d),
1097+
OSSL_PARAM_END
1098+
};
1099+
OSSL_PARAM params_ed[] = {
1100+
OSSL_PARAM_ulong("e", &rsa_e),
1101+
OSSL_PARAM_ulong("d", &rsa_d),
1102+
OSSL_PARAM_END
1103+
};
1104+
OSSL_PARAM params_ned[] = {
1105+
OSSL_PARAM_ulong("n", &rsa_n),
1106+
OSSL_PARAM_ulong("e", &rsa_e),
1107+
OSSL_PARAM_ulong("d", &rsa_d),
1108+
OSSL_PARAM_END
1109+
};
1110+
OSSL_PARAM params_extra_ulong[] = {
1111+
OSSL_PARAM_ulong("n", &rsa_n),
1112+
OSSL_PARAM_ulong("e", &rsa_e),
1113+
OSSL_PARAM_ulong("d", &rsa_d),
1114+
OSSL_PARAM_ulong("asdf", &rsa_d),
1115+
OSSL_PARAM_END
1116+
};
1117+
OSSL_PARAM params_extra_str[] = {
1118+
OSSL_PARAM_ulong("n", &rsa_n),
1119+
OSSL_PARAM_ulong("e", &rsa_e),
1120+
OSSL_PARAM_ulong("d", &rsa_d),
1121+
{ "foo", OSSL_PARAM_UTF8_PTR, &foo, foo_l, 0 },
1122+
{ "bar", OSSL_PARAM_UTF8_STRING, (void *)&bar, sizeof(bar) - 1, 0 },
1123+
OSSL_PARAM_END
1124+
};
1125+
OSSL_PARAM* params_table[] = {
1126+
params_none,
1127+
params_n,
1128+
params_e,
1129+
params_d,
1130+
params_ne,
1131+
params_nd,
1132+
params_ed,
1133+
params_ned,
1134+
params_extra_ulong,
1135+
params_extra_str,
1136+
};
1137+
1138+
for (unsigned i = 0; i < ARRAY_SIZE(selections); i++) {
1139+
for (unsigned j = 0; j < ARRAY_SIZE(params_table); j++) {
1140+
int status_wolf = EVP_PKEY_fromdata(ctx_wolf, &pkey_wolf,
1141+
selections[i], &params_table[j][0]);
1142+
int status_ossl = EVP_PKEY_fromdata(ctx_ossl, &pkey_ossl,
1143+
selections[i], &params_table[j][0]);
1144+
1145+
if (status_wolf != status_ossl) {
1146+
PRINT_MSG("EVP_PKEY_fromdata (wolf=%d) and (ossl=%d) status "
1147+
"mismatch for selection %d (0x%08X) and params %d",
1148+
status_wolf, status_ossl, i, selections[i], j);
1149+
err = 1;
1150+
}
1151+
else if (status_wolf == 1) {
1152+
PRINT_MSG("EVP_PKEY_fromdata (wolf) succeeded for "
1153+
"selection %d (0x%08X) and params %d",
1154+
i, selections[i], j);
1155+
1156+
if (EVP_PKEY_cmp(pkey_wolf, pkey_ossl) != 1) {
1157+
PRINT_MSG("EVP_PKEY_cmp failed for selection %d "
1158+
"(0x%08X)", i, selections[i]);
1159+
err = 1;
1160+
}
1161+
if (EVP_PKEY_cmp_parameters(pkey_wolf, pkey_ossl) != 1) {
1162+
PRINT_MSG("EVP_PKEY_cmp_parameters failed for "
1163+
"selection %d (0x%08X)", i, selections[i]);
1164+
err = 1;
1165+
}
1166+
}
1167+
1168+
EVP_PKEY_free(pkey_wolf);
1169+
EVP_PKEY_free(pkey_ossl);
1170+
pkey_wolf = NULL;
1171+
pkey_ossl = NULL;
1172+
}
1173+
}
1174+
}
1175+
1176+
EVP_PKEY_CTX_free(ctx_wolf);
1177+
EVP_PKEY_CTX_free(ctx_ossl);
1178+
1179+
return err;
1180+
}
1181+
10281182
#endif /* WP_HAVE_RSA */

test/unit.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ TEST_CASE test_case[] = {
165165
TEST_DECL(test_rsa_get_params, NULL),
166166
TEST_DECL(test_rsa_load_key, NULL),
167167
TEST_DECL(test_rsa_load_cert, NULL),
168+
TEST_DECL(test_rsa_fromdata, NULL),
168169
#endif /* WP_HAVE_RSA */
169170
#ifdef WP_HAVE_EC_P192
170171
#ifdef WP_HAVE_ECKEYGEN

test/unit.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@
4747
#define PRINT_MSG(str)
4848
#define PRINT_ERR_MSG(str)
4949
#else
50-
#define PRINT_MSG(str) printf("MSG: %s\n", str)
51-
#define PRINT_ERR_MSG(str) printf("ERR: %s\n", str)
50+
#define PRINT_MSG(str, ...) printf("MSG: " str "\n", ##__VA_ARGS__)
51+
#define PRINT_ERR_MSG(str, ...) printf("ERR: " str "\n", ##__VA_ARGS__)
5252
#endif
5353
#ifdef WOLFPROV_DEBUG
5454
void print_buffer(const char *desc, const unsigned char *buffer, size_t len);
@@ -244,6 +244,7 @@ int test_rsa_get_params(void *data);
244244

245245
int test_rsa_load_key(void* data);
246246
int test_rsa_load_cert(void* data);
247+
int test_rsa_fromdata(void* data);
247248
#endif /* WP_HAVE_RSA */
248249

249250
#ifdef WP_HAVE_DH

0 commit comments

Comments
 (0)