Skip to content

Commit a5eb03c

Browse files
yosuke-wolfsslejohnstown
authored andcommitted
Add integration test for wrong ECC signature scenario
1 parent 60de6ff commit a5eb03c

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

tests/auth.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,66 @@ static void test_pubkey_auth_ecc(void)
707707

708708
run_pubkey_test(&sCtx, &cCtx, WS_SUCCESS);
709709
}
710+
711+
/* Negative test: correct ECC public key presented (passes the authorized-key
712+
* hash check) but the client signs with a corrupted private key. The wrong
713+
* signature must reach and be rejected by DoUserAuthRequestEcc rather than
714+
* failing on the earlier key-type mismatch path.
715+
*/
716+
static void test_pubkey_auth_ecc_bad_sig(void)
717+
{
718+
PubkeyServerCtx sCtx;
719+
PubkeyClientCtx cCtx;
720+
byte pubKeyBuf[256];
721+
byte* p = pubKeyBuf;
722+
word32 pubKeySz = sizeof(pubKeyBuf);
723+
const byte* pubKeyType = NULL;
724+
word32 pubKeyTypeSz = 0;
725+
/* Flip one byte inside the private scalar of the DER blob to produce a
726+
* structurally valid ECC key whose signatures won't verify against the
727+
* original public key.
728+
*
729+
* Per-curve scalar layout in the RFC 5915 ECPrivateKey DER encoding:
730+
* P-256: header "30 77 02 01 01 04 20" = 7 bytes; scalar at offset 7.
731+
* Byte 10 = scalar[3]. Original 0xd3; after ^0xFF: 0x2c.
732+
* P-384: header "30 81 a4 02 01 01 04 30" = 8 bytes; scalar at offset 8.
733+
* Byte 10 = scalar[2]. Original 0xae; after ^0xFF: 0x51.
734+
* P-521: header "30 81 dc 02 01 01 04 42" = 8 bytes; scalar at offset 8.
735+
* Byte 10 = scalar[2]. Original 0x40; after ^0xFF: 0xbf.
736+
*
737+
* In all three cases the leading byte(s) of the scalar are far below the
738+
* high-order byte of n, so the modified value stays within [1, n-1] and
739+
* wc_EccPrivateKeyDecode accepts it without error. */
740+
byte badPrivDer[sizeof(hanselPrivateEcc)];
741+
byte badPrivBuf[256];
742+
byte* badPrivPtr = badPrivBuf;
743+
word32 badPrivSz = sizeof(badPrivBuf);
744+
const byte* badPrivType = NULL; /* required by API; value not used */
745+
word32 badPrivTypeSz = 0;
746+
747+
printf("Testing ECC pubkey auth rejection with tampered signature\n");
748+
749+
AssertIntEQ(wolfSSH_ReadKey_buffer((const byte*)hanselPublicEcc,
750+
(word32)WSTRLEN(hanselPublicEcc), WOLFSSH_FORMAT_SSH,
751+
&p, &pubKeySz, &pubKeyType, &pubKeyTypeSz, NULL), WS_SUCCESS);
752+
AssertIntEQ(wc_Sha256Hash(pubKeyBuf, pubKeySz, sCtx.hash), 0);
753+
754+
WMEMCPY(badPrivDer, hanselPrivateEcc, hanselPrivateEccSz);
755+
badPrivDer[10] ^= 0xFF;
756+
AssertIntEQ(wolfSSH_ReadKey_buffer(badPrivDer, hanselPrivateEccSz,
757+
WOLFSSH_FORMAT_ASN1,
758+
&badPrivPtr, &badPrivSz, &badPrivType, &badPrivTypeSz, NULL),
759+
WS_SUCCESS);
760+
761+
cCtx.publicKeyType = pubKeyType;
762+
cCtx.publicKeyTypeSz = pubKeyTypeSz;
763+
cCtx.publicKey = pubKeyBuf;
764+
cCtx.publicKeySz = pubKeySz;
765+
cCtx.privateKey = badPrivBuf;
766+
cCtx.privateKeySz = badPrivSz;
767+
768+
run_pubkey_test(&sCtx, &cCtx, WS_FATAL_ERROR);
769+
}
710770
#endif /* WOLFSSH_NO_ECC */
711771

712772
#if !defined(WOLFSSH_NO_RSA) && !defined(WOLFSSH_NO_ECC)
@@ -1511,6 +1571,7 @@ int wolfSSH_AuthTest(int argc, char** argv)
15111571
#endif
15121572
#ifndef WOLFSSH_NO_ECC
15131573
test_pubkey_auth_ecc();
1574+
test_pubkey_auth_ecc_bad_sig();
15141575
#endif
15151576
#if !defined(WOLFSSH_NO_RSA) && !defined(WOLFSSH_NO_ECC)
15161577
test_pubkey_auth_wrong_key();

0 commit comments

Comments
 (0)