Skip to content

Commit 0e6e7e7

Browse files
authored
Merge pull request #318 from padelsbach/wp-rsa-pss-pubkey-parse-fix
Fix RSA PSS public key parsing
2 parents 129fe6f + 4a353fc commit 0e6e7e7

File tree

3 files changed

+87
-24
lines changed

3 files changed

+87
-24
lines changed

.github/workflows/debian-package.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,13 @@ jobs:
288288
openssl dgst -sha256 -sign ecc_key.pem -out msg.sig msg.txt
289289
openssl dgst -sha256 -verify <(openssl pkey -in ecc_key.pem -pubout) -signature msg.sig msg.txt
290290
291+
- name: Run cmd tests
292+
shell: bash
293+
run: |
294+
# Run the do-cmd-test.sh script to execute interoperability tests
295+
echo "Running OpenSSL provider interoperability tests..."
296+
OPENSSL_BIN=$(eval which openssl) ./scripts/cmd_test/do-cmd-tests.sh
297+
291298
- name: Cleanup test environment
292299
run: |
293300
echo "Cleaning up test environment..."

scripts/cmd_test/rsa-cmd-test.sh

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,23 @@ KEY_TYPES=("RSA" "RSA-PSS")
3737
KEY_SIZES=("2048" "3072" "4096")
3838
PROVIDER_ARGS=("-provider-path $WOLFPROV_PATH -provider libwolfprov" "-provider default")
3939

40+
OPENSSL_BIN=${OPENSSL_BIN:-openssl}
41+
4042
echo "=== Running RSA Key Generation Tests ==="
4143

44+
rsa_check_force_fail() {
45+
local openssl_providers=$($OPENSSL_BIN list -providers)
46+
is_openssl_default_provider=$(echo "$openssl_providers" | grep -qi "OpenSSL Default Provider" && echo 1 || echo 0)
47+
if [ $is_openssl_default_provider -eq 1 ]; then
48+
# With the OpenSSL provider, don't expect failures
49+
echo "OPENSSL Default provider active, no forced failures expected."
50+
elif [ "${WOLFPROV_FORCE_FAIL}" = "1" ]; then
51+
echo "[PASS] Test passed when force fail was enabled"
52+
FORCE_FAIL_PASSED=1
53+
exit 1
54+
fi
55+
}
56+
4257
# Function to validate key
4358
validate_key() {
4459
local key_type=$1
@@ -61,15 +76,15 @@ validate_key() {
6176
return
6277
else
6378
echo "[PASS] ${key_type} key file exists and has content"
64-
check_force_fail
79+
rsa_check_force_fail
6580
fi
6681

6782
# Only try to extract public key if file exists and has content
6883
local pub_key_file="rsa_outputs/${key_type}_${key_size}_pub.pem"
6984
if $OPENSSL_BIN pkey -in "$key_file" -pubout -out "$pub_key_file" \
7085
${provider_args} -passin pass: >/dev/null; then
7186
echo "[PASS] ${key_type} Public key extraction successful"
72-
check_force_fail
87+
rsa_check_force_fail
7388
else
7489
echo "[FAIL] ${key_type} Public key extraction failed"
7590
FAIL=1
@@ -164,6 +179,18 @@ test_sign_verify_pkeyutl() {
164179
local key_file="rsa_outputs/${key_prefix}_${key_size}.pem"
165180
local pub_key_file="rsa_outputs/${key_prefix}_${key_size}_pub.pem"
166181
local data_file="rsa_outputs/test_data.txt"
182+
183+
if [ ! -f "$key_file" ] || [ ! -f "$pub_key_file" ]; then
184+
echo "[FAIL] Key files for ${key_type} (${key_size}) not found, cannot run sign/verify tests"
185+
FAIL=1
186+
exit 1
187+
fi
188+
189+
if [ ! -f "$data_file" ]; then
190+
echo "[FAIL] Test data file not found, cannot run sign/verify tests"
191+
FAIL=1
192+
exit 1
193+
fi
167194

168195
echo -e "\n=== Testing ${key_type} (${key_size}) Sign/Verify with pkeyutl Using ${provider_name} ==="
169196

@@ -173,10 +200,10 @@ test_sign_verify_pkeyutl() {
173200
local default_sig_file="rsa_outputs/${key_prefix}_${key_size}_default_sig.bin"
174201
if $sign_func "$key_file" "$data_file" "$default_sig_file" "$provider_args"; then
175202
echo "[PASS] Signing with OpenSSL default successful"
176-
check_force_fail
203+
rsa_check_force_fail
177204
if $verify_func "$pub_key_file" "$data_file" "$default_sig_file" "$provider_args"; then
178205
echo "[PASS] Default provider verify successful"
179-
check_force_fail
206+
rsa_check_force_fail
180207
else
181208
echo "[FAIL] Default provider verify failed"
182209
FAIL=1
@@ -192,10 +219,10 @@ test_sign_verify_pkeyutl() {
192219
local wolf_sig_file="rsa_outputs/${key_prefix}_${key_size}_wolf_sig.bin"
193220
if $sign_func "$key_file" "$data_file" "$wolf_sig_file" "$provider_args"; then
194221
echo "[PASS] Signing with wolfProvider successful"
195-
check_force_fail
222+
rsa_check_force_fail
196223
if $verify_func "$pub_key_file" "$data_file" "$wolf_sig_file" "$provider_args"; then
197224
echo "[PASS] wolfProvider sign/verify successful"
198-
check_force_fail
225+
rsa_check_force_fail
199226
else
200227
echo "[FAIL] wolfProvider verify failed"
201228
FAIL=1
@@ -207,28 +234,25 @@ test_sign_verify_pkeyutl() {
207234

208235
# Test 3: Cross-provider verification (default sign, wolf verify)
209236
if [ $FAIL -eq 0 ]; then # only verify if previous tests passed
210-
use_wolf_provider
211237
echo "Test 3: Cross-provider verification (default sign, wolf verify)"
238+
use_wolf_provider
212239
if $verify_func "$pub_key_file" "$data_file" "$default_sig_file" "$provider_args"; then
213240
echo "[PASS] wolfProvider can verify OpenSSL default signature"
214-
check_force_fail
241+
rsa_check_force_fail
215242
else
216243
echo "[FAIL] wolfProvider cannot verify OpenSSL default signature"
217244
FAIL=1
218245
fi
219-
220-
# Test 4: Cross-provider verification (wolf sign, default verify)
246+
221247
use_default_provider
222248
echo "Test 4: Cross-provider verification (wolf sign, default verify)"
223249
if $verify_func "$pub_key_file" "$data_file" "$wolf_sig_file" "$provider_args"; then
224250
echo "[PASS] OpenSSL default can verify wolfProvider signature"
225-
check_force_fail
251+
rsa_check_force_fail
226252
else
227253
echo "[FAIL] OpenSSL default cannot verify wolfProvider signature"
228254
FAIL=1
229255
fi
230-
else
231-
echo "[INFO] Cannot verify cross-provider signatures no key available"
232256
fi
233257
}
234258

@@ -239,6 +263,11 @@ generate_and_test_key() {
239263
local provider_args=$3
240264
local output_file="rsa_outputs/${key_type}_${key_size}.pem"
241265

266+
if [ -f "$output_file" ]; then
267+
echo "Output file $output_file already exists, removing it."
268+
rm -f "$output_file"
269+
fi
270+
242271
# Get the provider name
243272
provider_name=$(get_provider_name "$provider_args")
244273

@@ -254,7 +283,7 @@ generate_and_test_key() {
254283
-pkeyopt rsa_pss_keygen_saltlen:-1 \
255284
-out "$output_file" 2>/dev/null; then
256285
echo "[PASS] RSA-PSS key generation successful"
257-
check_force_fail
286+
rsa_check_force_fail
258287
else
259288
echo "[FAIL] RSA-PSS key generation failed"
260289
FAIL=1
@@ -266,7 +295,7 @@ generate_and_test_key() {
266295
-pkeyopt rsa_keygen_bits:${key_size} \
267296
-out "$output_file" 2>/dev/null; then
268297
echo "[PASS] RSA key generation successful"
269-
check_force_fail
298+
rsa_check_force_fail
270299
else
271300
echo "[FAIL] RSA key generation failed"
272301
FAIL=1
@@ -276,7 +305,7 @@ generate_and_test_key() {
276305
# Verify the key was generated
277306
if [ -s "$output_file" ]; then
278307
echo "[PASS] ${key_type} key (${key_size}) generation successful"
279-
check_force_fail
308+
rsa_check_force_fail
280309
else
281310
echo "[FAIL] ${key_type} key (${key_size}) generation failed"
282311
FAIL=1
@@ -293,7 +322,7 @@ generate_and_test_key() {
293322
if $OPENSSL_BIN pkey -in "$output_file" -check \
294323
${provider_args} -passin pass: >/dev/null; then
295324
echo "[PASS] ${provider_name} can use ${key_type} key (${key_size})"
296-
check_force_fail
325+
rsa_check_force_fail
297326
else
298327
echo "[FAIL] ${provider_name} cannot use ${key_type} key (${key_size})"
299328
FAIL=1
@@ -307,6 +336,14 @@ for key_type in "${KEY_TYPES[@]}"; do
307336
# Generate key with current provider
308337
generate_and_test_key "$key_type" "$key_size" "$test_provider"
309338

339+
# If WPFF is set, we need to run again to actually create the
340+
# key files
341+
if [ $WOLFPROV_FORCE_FAIL -ne 0 ]; then
342+
WOLFPROV_FORCE_FAIL=0
343+
generate_and_test_key "$key_type" "$key_size" "$test_provider"
344+
WOLFPROV_FORCE_FAIL=1
345+
fi
346+
310347
# Test sign/verify interoperability with appropriate function
311348
if [ "$key_type" = "RSA-PSS" ]; then
312349
test_sign_verify_pkeyutl "$key_type" "$key_size" "$test_provider" sign_rsa_pss verify_rsa_pss

src/wp_rsa_kmgmt.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,7 +1981,7 @@ static int wp_rsa_enc_dec_set_ctx_params(wp_RsaEncDecCtx* ctx,
19811981
}
19821982

19831983
/** Common base of RSA PKCS #1.5 and PSS OID. */
1984-
unsigned char rsa_pkcs1_oid[] = {
1984+
static const unsigned char rsa_pkcs1_oid[] = {
19851985
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01
19861986
};
19871987
/** Size of RSA PKCS OID. */
@@ -2002,15 +2002,15 @@ unsigned char rsa_pkcs1_oid[] = {
20022002
* @return 1 on success.
20032003
* @return 0 on failure.
20042004
*/
2005-
static int wp_rsa_find_oid(unsigned char* data, word32 len, unsigned char* oid,
2005+
static int wp_rsa_find_oid(unsigned char* data, word32 len, const unsigned char* oid,
20062006
word32 oidLen, word32* offset)
20072007
{
20082008
int ok = 0;
20092009
word32 i;
20102010

20112011
WOLFPROV_ENTER_SILENT(WP_LOG_COMP_RSA, WOLFPROV_FUNC_NAME);
20122012

2013-
for (i = 0; i < len - RSA_PKCS1_OID_SZ - 1; i++) {
2013+
for (i = 0; i + oidLen <= len; i++) {
20142014
/* Find the base OID. */
20152015
if (XMEMCMP(data + i, oid, oidLen) == 0) {
20162016
ok = 1;
@@ -2082,11 +2082,30 @@ static int wp_rsa_pss_get_params(wp_Rsa* rsa, unsigned char* data, word32 len)
20822082
/* Step over PSS algorithm. */
20832083
idx += 11;
20842084

2085-
if (data[idx] != 0x30) {
2086-
ok = 0;
2085+
/* Step over BIT STRING field */
2086+
if (data[idx] == 0x03) {
2087+
idx++;
2088+
if (data[idx] < 0x80) {
2089+
idx += 2;
2090+
}
2091+
else if (data[idx] == 0x81) {
2092+
idx += 3;
2093+
}
2094+
else if (data[idx] == 0x82) {
2095+
idx += 4;
2096+
}
2097+
else {
2098+
ok = 0;
2099+
}
20872100
}
2088-
else {
2089-
idx += 2;
2101+
2102+
if (ok) {
2103+
if (data[idx] != 0x30) {
2104+
ok = 0;
2105+
}
2106+
else {
2107+
idx += 2;
2108+
}
20902109
}
20912110
}
20922111
if (ok && (data[idx] == 0xa0)) {

0 commit comments

Comments
 (0)