@@ -1485,7 +1485,7 @@ static int CaptureIoSendAuthSvc(WOLFSSH* ssh, void* buf, word32 sz, void* ctx)
14851485 *
14861486 * For invalid-service cases the auth-method field is intentionally omitted
14871487 * from the payload. DoUserAuthRequest must short-circuit at the service-name
1488- * check and still satisfy all three assertions — proving it never tries to
1488+ * check and still satisfy all three assertions - proving it never tries to
14891489 * parse the missing auth-method field. If the short-circuit were absent,
14901490 * GetSize() for authNameSz would hit end-of-buffer and return WS_BUFFER_E,
14911491 * failing assertion 1.
@@ -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 */
1843+
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 */
17531865
1866+ #ifndef WOLFSSH_NO_RSA
17541867/* wolfSSH_RsaVerify unit test
17551868 *
17561869 * Verifies that wolfSSH_RsaVerify returns WS_RSA_E when given a signature
@@ -2034,6 +2147,98 @@ static int test_DoUserAuthRequestEd25519(void)
20342147
20352148#endif /* Ed25519 verify test guards */
20362149
2150+ /* IdentifyAsn1Key unit test
2151+ *
2152+ * Exercises every new wc_Free* error-path added in IdentifyAsn1Key:
2153+ * - wc_FreeRsaKey on RSA decode failure
2154+ * - wc_ecc_free on ECC decode failure
2155+ * - wc_ecc_free in the default: branch (unsupported curve)
2156+ * - wc_ed25519_free on Ed25519 decode failure
2157+ * Each happy-path call implicitly exercises the failure-path frees for the
2158+ * other key types.
2159+ */
2160+ static int test_IdentifyAsn1Key (void )
2161+ {
2162+ int result = 0 ;
2163+ int ret ;
2164+
2165+ #ifndef WOLFSSH_NO_RSA
2166+ ret = IdentifyAsn1Key (unitTestRsaPrivKey , unitTestRsaPrivKeySz ,
2167+ 1 , NULL , NULL );
2168+ if (ret != ID_SSH_RSA ) {
2169+ printf ("IdentifyAsn1Key: RSA priv failed, ret=%d\n" , ret );
2170+ result = -600 ; goto done ;
2171+ }
2172+ #endif
2173+
2174+ #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
2175+ ret = IdentifyAsn1Key (unitTestEcc256PrivKey ,
2176+ (word32 )sizeof (unitTestEcc256PrivKey ),
2177+ 1 , NULL , NULL );
2178+ if (ret != ID_ECDSA_SHA2_NISTP256 ) {
2179+ printf ("IdentifyAsn1Key: ECC P-256 priv failed, ret=%d\n" , ret );
2180+ result = -601 ; goto done ;
2181+ }
2182+ #endif
2183+
2184+ #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP384
2185+ ret = IdentifyAsn1Key (unitTestEcc384PrivKey ,
2186+ (word32 )sizeof (unitTestEcc384PrivKey ),
2187+ 1 , NULL , NULL );
2188+ if (ret != ID_ECDSA_SHA2_NISTP384 ) {
2189+ printf ("IdentifyAsn1Key: ECC P-384 priv failed, ret=%d\n" , ret );
2190+ result = -602 ; goto done ;
2191+ }
2192+ #endif
2193+
2194+ #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP521
2195+ ret = IdentifyAsn1Key (unitTestEcc521PrivKey ,
2196+ (word32 )sizeof (unitTestEcc521PrivKey ),
2197+ 1 , NULL , NULL );
2198+ if (ret != ID_ECDSA_SHA2_NISTP521 ) {
2199+ printf ("IdentifyAsn1Key: ECC P-521 priv failed, ret=%d\n" , ret );
2200+ result = -603 ; goto done ;
2201+ }
2202+ #endif
2203+
2204+ #if !defined(WOLFSSH_NO_ED25519 )
2205+ ret = IdentifyAsn1Key (unitTestEd25519PrivKey ,
2206+ (word32 )sizeof (unitTestEd25519PrivKey ),
2207+ 1 , NULL , NULL );
2208+ if (ret != ID_ED25519 ) {
2209+ printf ("IdentifyAsn1Key: Ed25519 priv failed, ret=%d\n" , ret );
2210+ result = -604 ; goto done ;
2211+ }
2212+ #endif
2213+
2214+ /* Unsupported ECC curve: triggers wc_ecc_free in the default: branch
2215+ * (wolfSSL has P-192) or the else branch (wolfSSL lacks P-192).
2216+ * Either way the key must be freed and WS_UNIMPLEMENTED_E returned. */
2217+ #ifndef WOLFSSH_NO_ECDSA
2218+ ret = IdentifyAsn1Key (unitTestEccUnsupportedCurveKey ,
2219+ (word32 )sizeof (unitTestEccUnsupportedCurveKey ),
2220+ 1 , NULL , NULL );
2221+ if (ret != WS_UNIMPLEMENTED_E ) {
2222+ printf ("IdentifyAsn1Key: unsupported ECC curve expected "
2223+ "WS_UNIMPLEMENTED_E, got %d\n" , ret );
2224+ result = -605 ; goto done ;
2225+ }
2226+ #endif
2227+
2228+ /* Garbage: all decode attempts fail, all wc_Free* cleanup paths hit */
2229+ {
2230+ static const byte garbage [] = {0x00 , 0x01 , 0x02 , 0x03 };
2231+ ret = IdentifyAsn1Key (garbage , (word32 )sizeof (garbage ), 1 , NULL , NULL );
2232+ if (ret != WS_UNIMPLEMENTED_E ) {
2233+ printf ("IdentifyAsn1Key: garbage expected WS_UNIMPLEMENTED_E, "
2234+ "got %d\n" , ret );
2235+ result = -606 ; goto done ;
2236+ }
2237+ }
2238+
2239+ done :
2240+ return result ;
2241+ }
20372242#endif /* WOLFSSH_TEST_INTERNAL */
20382243
20392244/* Error Code And Message Test */
@@ -2165,6 +2370,10 @@ int wolfSSH_UnitTest(int argc, char** argv)
21652370 (unitResult == 0 ? "SUCCESS" : "FAILED" ));
21662371 testResult = testResult || unitResult ;
21672372
2373+ unitResult = test_IdentifyAsn1Key ();
2374+ printf ("IdentifyAsn1Key: %s\n" , (unitResult == 0 ? "SUCCESS" : "FAILED" ));
2375+ testResult = testResult || unitResult ;
2376+
21682377#endif
21692378
21702379#ifdef WOLFSSH_KEYGEN
0 commit comments