@@ -1750,7 +1750,120 @@ static const byte unitTestRsaPrivKey[] = {
17501750};
17511751static const word32 unitTestRsaPrivKeySz =
17521752 (word32 )sizeof (unitTestRsaPrivKey );
1753+ #endif /* WOLFSSH_NO_RSA */
1754+
1755+ /* Keys for test_IdentifyAsn1Key: inline DER so the test is self-contained
1756+ * in both filesystem and NO_FILESYSTEM builds. Each array matches the
1757+ * corresponding file under keys/. */
1758+ #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
1759+ /* keys/server-key-ecc.der — P-256 RFC-5915 ECPrivateKey */
1760+ static const byte unitTestEcc256PrivKey [] = {
1761+ 0x30 , 0x77 , 0x02 , 0x01 , 0x01 , 0x04 , 0x20 , 0x61 , 0x09 , 0x99 ,
1762+ 0x0B , 0x79 , 0xD2 , 0x5F , 0x28 , 0x5A , 0x0F , 0x5D , 0x15 , 0xCC ,
1763+ 0xA1 , 0x56 , 0x54 , 0xF9 , 0x2B , 0x39 , 0x87 , 0x21 , 0x2D , 0xA7 ,
1764+ 0x7D , 0x85 , 0x7B , 0xB8 , 0x7F , 0x38 , 0xC6 , 0x6D , 0xD5 , 0xA0 ,
1765+ 0x0A , 0x06 , 0x08 , 0x2A , 0x86 , 0x48 , 0xCE , 0x3D , 0x03 , 0x01 ,
1766+ 0x07 , 0xA1 , 0x44 , 0x03 , 0x42 , 0x00 , 0x04 , 0x81 , 0x13 , 0xFF ,
1767+ 0xA4 , 0x2B , 0xB7 , 0x9C , 0x45 , 0x74 , 0x7A , 0x83 , 0x4C , 0x61 ,
1768+ 0xF3 , 0x3F , 0xAD , 0x26 , 0xCF , 0x22 , 0xCD , 0xA9 , 0xA3 , 0xBC ,
1769+ 0xA5 , 0x61 , 0xB4 , 0x7C , 0xE6 , 0x62 , 0xD4 , 0xC2 , 0xF7 , 0x55 ,
1770+ 0x43 , 0x9A , 0x31 , 0xFB , 0x80 , 0x11 , 0x20 , 0xB5 , 0x12 , 0x4B ,
1771+ 0x24 , 0xF5 , 0x78 , 0xD7 , 0xFD , 0x22 , 0xEF , 0x46 , 0x35 , 0xF0 ,
1772+ 0x05 , 0x58 , 0x6B , 0x5F , 0x63 , 0xC8 , 0xDA , 0x1B , 0xC4 , 0xF5 ,
1773+ 0x69
1774+ };
1775+ #endif /* WOLFSSH_NO_ECDSA_SHA2_NISTP256 */
1776+
1777+ #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384
1778+ /* keys/server-key-ecc-384.der — P-384 RFC-5915 ECPrivateKey */
1779+ static const byte unitTestEcc384PrivKey [] = {
1780+ 0x30 , 0x81 , 0xA4 , 0x02 , 0x01 , 0x01 , 0x04 , 0x30 , 0x3E , 0xAD ,
1781+ 0xD2 , 0xBB , 0xBF , 0x05 , 0xA7 , 0xBE , 0x3A , 0x3F , 0x7C , 0x28 ,
1782+ 0x15 , 0x12 , 0x89 , 0xDE , 0x5B , 0xB3 , 0x64 , 0x4D , 0x70 , 0x11 ,
1783+ 0x76 , 0x1D , 0xB5 , 0x6F , 0x2A , 0x03 , 0x62 , 0xFB , 0xA6 , 0x4F ,
1784+ 0x98 , 0xE6 , 0x4F , 0xF9 , 0x86 , 0xDC , 0x4F , 0xB8 , 0xEF , 0xDB ,
1785+ 0x2D , 0x6B , 0x8D , 0xA5 , 0x71 , 0x42 , 0xA0 , 0x07 , 0x06 , 0x05 ,
1786+ 0x2B , 0x81 , 0x04 , 0x00 , 0x22 , 0xA1 , 0x64 , 0x03 , 0x62 , 0x00 ,
1787+ 0x04 , 0x38 , 0xD6 , 0x2B , 0xE4 , 0x18 , 0xFF , 0x57 , 0x3F , 0xD0 ,
1788+ 0xE0 , 0x20 , 0xD4 , 0x88 , 0x76 , 0xC4 , 0xE1 , 0x12 , 0x1D , 0xFB ,
1789+ 0x2D , 0x6E , 0xBE , 0xE4 , 0x89 , 0x5D , 0x77 , 0x24 , 0x31 , 0x6D ,
1790+ 0x46 , 0xA2 , 0x31 , 0x05 , 0x87 , 0x3F , 0x29 , 0x86 , 0xD5 , 0xC7 ,
1791+ 0x12 , 0x80 , 0x3A , 0x6F , 0x47 , 0x1A , 0xB8 , 0x68 , 0x50 , 0xEB ,
1792+ 0x06 , 0x3E , 0x10 , 0x89 , 0x61 , 0x34 , 0x9C , 0xF8 , 0xB4 , 0xC6 ,
1793+ 0xA4 , 0xCF , 0x5E , 0x97 , 0xBD , 0x7E , 0x51 , 0xE9 , 0x75 , 0xE3 ,
1794+ 0xE9 , 0x21 , 0x72 , 0x61 , 0x50 , 0x6E , 0xB9 , 0xCF , 0x3C , 0x49 ,
1795+ 0x3D , 0x3E , 0xB8 , 0x8D , 0x46 , 0x7B , 0x5F , 0x27 , 0xEB , 0xAB ,
1796+ 0x21 , 0x61 , 0xC0 , 0x00 , 0x66 , 0xFE , 0xBD
1797+ };
1798+ #endif /* WOLFSSH_NO_ECDSA_SHA2_NISTP384 */
1799+
1800+ #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521
1801+ /* keys/server-key-ecc-521.der — P-521 RFC-5915 ECPrivateKey */
1802+ static const byte unitTestEcc521PrivKey [] = {
1803+ 0x30 , 0x81 , 0xDC , 0x02 , 0x01 , 0x01 , 0x04 , 0x42 , 0x00 , 0x4C ,
1804+ 0xA4 , 0xD8 , 0x64 , 0x28 , 0xD9 , 0x40 , 0x0E , 0x7B , 0x2D , 0xF3 ,
1805+ 0x91 , 0x2E , 0xB9 , 0x96 , 0xC1 , 0x95 , 0x89 , 0x50 , 0x43 , 0xAF ,
1806+ 0x92 , 0xE8 , 0x6D , 0xE7 , 0x0A , 0xE4 , 0xDF , 0x46 , 0xF2 , 0x2A ,
1807+ 0x29 , 0x1A , 0x6B , 0xB2 , 0x74 , 0x8A , 0xAE , 0x82 , 0x58 , 0x0D ,
1808+ 0xF6 , 0xC3 , 0x9F , 0x49 , 0xB3 , 0xED , 0x82 , 0xF1 , 0x78 , 0x9E ,
1809+ 0xCE , 0x1B , 0x65 , 0x7D , 0x45 , 0x43 , 0x8C , 0xFF , 0x15 , 0x65 ,
1810+ 0x34 , 0x35 , 0x45 , 0x75 , 0xA0 , 0x07 , 0x06 , 0x05 , 0x2B , 0x81 ,
1811+ 0x04 , 0x00 , 0x23 , 0xA1 , 0x81 , 0x89 , 0x03 , 0x81 , 0x86 , 0x00 ,
1812+ 0x04 , 0x01 , 0xF8 , 0xD0 , 0xA7 , 0xC3 , 0xC5 , 0x8D , 0x84 , 0x19 ,
1813+ 0x57 , 0x96 , 0x9F , 0x21 , 0x3A , 0x94 , 0xF3 , 0xDA , 0x55 , 0x0E ,
1814+ 0xDF , 0x76 , 0xD8 , 0xDD , 0x17 , 0x15 , 0x31 , 0xF3 , 0x5B , 0xB0 ,
1815+ 0x69 , 0xC8 , 0xBC , 0x30 , 0x0D , 0x6F , 0x6B , 0x37 , 0xD1 , 0x80 ,
1816+ 0x46 , 0xA9 , 0x71 , 0x7F , 0x2C , 0x6F , 0x59 , 0x51 , 0x9C , 0x82 ,
1817+ 0x70 , 0x95 , 0xB2 , 0x9A , 0x63 , 0x13 , 0x30 , 0x62 , 0x18 , 0xC2 ,
1818+ 0x35 , 0x76 , 0x94 , 0x00 , 0xD0 , 0xF9 , 0x6D , 0x00 , 0x0A , 0x19 ,
1819+ 0x3B , 0xA3 , 0x46 , 0x65 , 0x2B , 0xEB , 0x40 , 0x9A , 0x9A , 0x45 ,
1820+ 0xC5 , 0x97 , 0xA3 , 0xED , 0x93 , 0x2D , 0xD5 , 0xAA , 0xAE , 0x96 ,
1821+ 0xBF , 0x2F , 0x31 , 0x7E , 0x5A , 0x7A , 0xC7 , 0x45 , 0x8B , 0x3C ,
1822+ 0x6C , 0xDB , 0xAA , 0x90 , 0xC3 , 0x55 , 0x38 , 0x2C , 0xDF , 0xCD ,
1823+ 0xCA , 0x73 , 0x77 , 0xD9 , 0x2E , 0xB2 , 0x0A , 0x5E , 0x8C , 0x74 ,
1824+ 0x23 , 0x7C , 0xA5 , 0xA3 , 0x45 , 0xB1 , 0x9E , 0x3F , 0x1A , 0x22 ,
1825+ 0x90 , 0xB1 , 0x54
1826+ };
1827+ #endif /* WOLFSSH_NO_ECDSA_SHA2_NISTP521 */
1828+
1829+ #if !defined(WOLFSSH_NO_ED25519 )
1830+ /* keys/server-key-ed25519.der — Ed25519 OneAsymmetricKey (RFC 8410) */
1831+ static const byte unitTestEd25519PrivKey [] = {
1832+ 0x30 , 0x50 , 0x02 , 0x01 , 0x00 , 0x30 , 0x05 , 0x06 , 0x03 , 0x2b ,
1833+ 0x65 , 0x70 , 0x04 , 0x22 , 0x04 , 0x20 , 0x6a , 0x67 , 0xf3 , 0x0e ,
1834+ 0x64 , 0xea , 0x52 , 0xfe , 0xf4 , 0xad , 0x65 , 0x4d , 0x45 , 0x60 ,
1835+ 0x61 , 0x38 , 0x58 , 0x11 , 0x07 , 0x84 , 0xf0 , 0x03 , 0x94 , 0x93 ,
1836+ 0x14 , 0x7b , 0x7b , 0x33 , 0x1a , 0xba , 0xf6 , 0x19 , 0x81 , 0x20 ,
1837+ 0x0f , 0x56 , 0x0c , 0x9f , 0x7d , 0x7a , 0x62 , 0x87 , 0xf0 , 0x26 ,
1838+ 0x16 , 0x19 , 0x31 , 0xe4 , 0xb2 , 0x1d , 0xe9 , 0xbd , 0xee , 0x4a ,
1839+ 0x7f , 0x55 , 0xae , 0x26 , 0x2d , 0xa1 , 0x25 , 0xe4 , 0xee , 0x4a ,
1840+ 0x51 , 0x00
1841+ };
1842+ #endif /* !WOLFSSH_NO_ED25519 */
17531843
1844+ #ifndef WOLFSSH_NO_ECDSA
1845+ /* P-256 DER with the OID last byte changed 0x07→0x01 (secp192r1).
1846+ * Forces wc_EccPrivateKeyDecode to fail or to return an unsupported curve id,
1847+ * exercising the wc_ecc_free cleanup in both the default: and else paths. */
1848+ static const byte unitTestEccUnsupportedCurveKey [] = {
1849+ 0x30 , 0x77 , 0x02 , 0x01 , 0x01 , 0x04 , 0x20 , 0x61 , 0x09 , 0x99 ,
1850+ 0x0B , 0x79 , 0xD2 , 0x5F , 0x28 , 0x5A , 0x0F , 0x5D , 0x15 , 0xCC ,
1851+ 0xA1 , 0x56 , 0x54 , 0xF9 , 0x2B , 0x39 , 0x87 , 0x21 , 0x2D , 0xA7 ,
1852+ 0x7D , 0x85 , 0x7B , 0xB8 , 0x7F , 0x38 , 0xC6 , 0x6D , 0xD5 , 0xA0 ,
1853+ 0x0A , 0x06 , 0x08 , 0x2A , 0x86 , 0x48 , 0xCE , 0x3D , 0x03 , 0x01 ,
1854+ 0x01 , /* 0x07 (secp256r1) changed to 0x01 (secp192r1) */
1855+ 0xA1 , 0x44 , 0x03 , 0x42 , 0x00 , 0x04 , 0x81 , 0x13 , 0xFF ,
1856+ 0xA4 , 0x2B , 0xB7 , 0x9C , 0x45 , 0x74 , 0x7A , 0x83 , 0x4C , 0x61 ,
1857+ 0xF3 , 0x3F , 0xAD , 0x26 , 0xCF , 0x22 , 0xCD , 0xA9 , 0xA3 , 0xBC ,
1858+ 0xA5 , 0x61 , 0xB4 , 0x7C , 0xE6 , 0x62 , 0xD4 , 0xC2 , 0xF7 , 0x55 ,
1859+ 0x43 , 0x9A , 0x31 , 0xFB , 0x80 , 0x11 , 0x20 , 0xB5 , 0x12 , 0x4B ,
1860+ 0x24 , 0xF5 , 0x78 , 0xD7 , 0xFD , 0x22 , 0xEF , 0x46 , 0x35 , 0xF0 ,
1861+ 0x05 , 0x58 , 0x6B , 0x5F , 0x63 , 0xC8 , 0xDA , 0x1B , 0xC4 , 0xF5 ,
1862+ 0x69
1863+ };
1864+ #endif /* WOLFSSH_NO_ECDSA */
1865+
1866+ #ifndef WOLFSSH_NO_RSA
17541867/* wolfSSH_RsaVerify unit test
17551868 *
17561869 * Verifies that wolfSSH_RsaVerify returns WS_RSA_E when given a signature
@@ -1826,6 +1939,99 @@ static int test_RsaVerify_BadDigest(void)
18261939}
18271940
18281941#endif /* !WOLFSSH_NO_RSA */
1942+
1943+ /* IdentifyAsn1Key unit test
1944+ *
1945+ * Exercises every new wc_Free* error-path added in IdentifyAsn1Key:
1946+ * - wc_FreeRsaKey on RSA decode failure
1947+ * - wc_ecc_free on ECC decode failure
1948+ * - wc_ecc_free in the default: branch (unsupported curve)
1949+ * - wc_ed25519_free on Ed25519 decode failure
1950+ * Each happy-path call implicitly exercises the failure-path frees for the
1951+ * other key types.
1952+ */
1953+ static int test_IdentifyAsn1Key (void )
1954+ {
1955+ int result = 0 ;
1956+ int ret ;
1957+
1958+ #ifndef WOLFSSH_NO_RSA
1959+ ret = IdentifyAsn1Key (unitTestRsaPrivKey , unitTestRsaPrivKeySz ,
1960+ 1 , NULL , NULL );
1961+ if (ret != ID_SSH_RSA ) {
1962+ printf ("IdentifyAsn1Key: RSA priv failed, ret=%d\n" , ret );
1963+ result = -600 ; goto done ;
1964+ }
1965+ #endif
1966+
1967+ #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
1968+ ret = IdentifyAsn1Key (unitTestEcc256PrivKey ,
1969+ (word32 )sizeof (unitTestEcc256PrivKey ),
1970+ 1 , NULL , NULL );
1971+ if (ret != ID_ECDSA_SHA2_NISTP256 ) {
1972+ printf ("IdentifyAsn1Key: ECC P-256 priv failed, ret=%d\n" , ret );
1973+ result = -601 ; goto done ;
1974+ }
1975+ #endif
1976+
1977+ #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384
1978+ ret = IdentifyAsn1Key (unitTestEcc384PrivKey ,
1979+ (word32 )sizeof (unitTestEcc384PrivKey ),
1980+ 1 , NULL , NULL );
1981+ if (ret != ID_ECDSA_SHA2_NISTP384 ) {
1982+ printf ("IdentifyAsn1Key: ECC P-384 priv failed, ret=%d\n" , ret );
1983+ result = -602 ; goto done ;
1984+ }
1985+ #endif
1986+
1987+ #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521
1988+ ret = IdentifyAsn1Key (unitTestEcc521PrivKey ,
1989+ (word32 )sizeof (unitTestEcc521PrivKey ),
1990+ 1 , NULL , NULL );
1991+ if (ret != ID_ECDSA_SHA2_NISTP521 ) {
1992+ printf ("IdentifyAsn1Key: ECC P-521 priv failed, ret=%d\n" , ret );
1993+ result = -603 ; goto done ;
1994+ }
1995+ #endif
1996+
1997+ #if !defined(WOLFSSH_NO_ED25519 )
1998+ ret = IdentifyAsn1Key (unitTestEd25519PrivKey ,
1999+ (word32 )sizeof (unitTestEd25519PrivKey ),
2000+ 1 , NULL , NULL );
2001+ if (ret != ID_ED25519 ) {
2002+ printf ("IdentifyAsn1Key: Ed25519 priv failed, ret=%d\n" , ret );
2003+ result = -604 ; goto done ;
2004+ }
2005+ #endif
2006+
2007+ /* Unsupported ECC curve: triggers wc_ecc_free in the default: branch
2008+ * (wolfSSL has P-192) or the else branch (wolfSSL lacks P-192).
2009+ * Either way the key must be freed and WS_UNIMPLEMENTED_E returned. */
2010+ #ifndef WOLFSSH_NO_ECDSA
2011+ ret = IdentifyAsn1Key (unitTestEccUnsupportedCurveKey ,
2012+ (word32 )sizeof (unitTestEccUnsupportedCurveKey ),
2013+ 1 , NULL , NULL );
2014+ if (ret != WS_UNIMPLEMENTED_E ) {
2015+ printf ("IdentifyAsn1Key: unsupported ECC curve expected "
2016+ "WS_UNIMPLEMENTED_E, got %d\n" , ret );
2017+ result = -605 ; goto done ;
2018+ }
2019+ #endif
2020+
2021+ /* Garbage: all decode attempts fail, all wc_Free* cleanup paths hit */
2022+ {
2023+ static const byte garbage [] = {0x00 , 0x01 , 0x02 , 0x03 };
2024+ ret = IdentifyAsn1Key (garbage , (word32 )sizeof (garbage ), 1 , NULL , NULL );
2025+ if (ret != WS_UNIMPLEMENTED_E ) {
2026+ printf ("IdentifyAsn1Key: garbage expected WS_UNIMPLEMENTED_E, "
2027+ "got %d\n" , ret );
2028+ result = -606 ; goto done ;
2029+ }
2030+ }
2031+
2032+ done :
2033+ return result ;
2034+ }
18292035#endif /* WOLFSSH_TEST_INTERNAL */
18302036
18312037/* Error Code And Message Test */
@@ -1949,6 +2155,10 @@ int wolfSSH_UnitTest(int argc, char** argv)
19492155 (unitResult == 0 ? "SUCCESS" : "FAILED" ));
19502156 testResult = testResult || unitResult ;
19512157
2158+ unitResult = test_IdentifyAsn1Key ();
2159+ printf ("IdentifyAsn1Key: %s\n" , (unitResult == 0 ? "SUCCESS" : "FAILED" ));
2160+ testResult = testResult || unitResult ;
2161+
19522162#endif
19532163
19542164#ifdef WOLFSSH_KEYGEN
0 commit comments