@@ -714,6 +714,12 @@ static void test_wolfSSH_CTX_UseCert_buffer(void)
714714 WOLFSSH_CTX * ctx = NULL ;
715715 byte * cert = NULL ;
716716 word32 certSz = 0 ;
717+ #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
718+ byte * key = NULL ;
719+ word32 keySz = 0 ;
720+ word32 count = 0 ;
721+ byte lastFmt = ID_NONE ;
722+ #endif
717723
718724 ctx = wolfSSH_CTX_new (WOLFSSH_ENDPOINT_SERVER , NULL );
719725 AssertNotNull (ctx );
@@ -732,6 +738,8 @@ static void test_wolfSSH_CTX_UseCert_buffer(void)
732738#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
733739 AssertIntEQ (WS_SUCCESS ,
734740 wolfSSH_CTX_UseCert_buffer (ctx , cert , certSz , WOLFSSH_FORMAT_PEM ));
741+ AssertIntEQ (1 , ctx -> privateKeyCount );
742+ AssertNotNull (ctx -> privateKey [0 ].cert );
735743#endif
736744
737745 AssertIntEQ (WS_BAD_FILETYPE_E ,
@@ -756,17 +764,63 @@ static void test_wolfSSH_CTX_UseCert_buffer(void)
756764 free (cert );
757765 cert = NULL ;
758766
759- AssertIntEQ (0 , load_file ("./keys/server-cert.der" , & cert , & certSz ));
767+ #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
768+ /* A matching private key seeds a key copy in the cert slot. */
769+ AssertIntEQ (0 , load_file ("./keys/server-key-ecc.der" , & key , & keySz ));
770+ AssertIntEQ (WS_SUCCESS ,
771+ wolfSSH_CTX_UsePrivateKey_buffer (ctx , key , keySz ,
772+ WOLFSSH_FORMAT_ASN1 ));
773+ count = ctx -> privateKeyCount ;
774+ AssertIntEQ (2 , count );
775+ #endif
776+
777+ /* A different certificate, so the reload shows in the stored DER. */
778+ AssertIntEQ (0 , load_file ("./keys/fred-cert.der" , & cert , & certSz ));
760779 AssertNotNull (cert );
761780 AssertIntNE (0 , certSz );
762781
763782#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
764783 AssertIntEQ (WS_SUCCESS ,
765784 wolfSSH_CTX_UseCert_buffer (ctx , cert , certSz , WOLFSSH_FORMAT_ASN1 ));
785+ /* Reloading replaces the slot instead of appending a duplicate. */
786+ AssertIntEQ (count , ctx -> privateKeyCount );
787+ AssertIntEQ (certSz , ctx -> privateKey [0 ].certSz );
788+ AssertIntEQ (0 , XMEMCMP (ctx -> privateKey [0 ].cert , cert , certSz ));
789+ AssertIntEQ (2 , ctx -> publicKeyAlgoCount );
790+ /* The replaced slot keeps a fresh copy of the matching key. */
791+ AssertIntEQ (ctx -> privateKey [1 ].keySz , ctx -> privateKey [0 ].keySz );
792+ AssertIntEQ (0 , XMEMCMP (ctx -> privateKey [0 ].key , ctx -> privateKey [1 ].key ,
793+ ctx -> privateKey [0 ].keySz ));
794+
795+ /* A full table still replaces the matching slot rather than rejecting;
796+ * a third certificate keeps the stored-DER checks honest. */
797+ free (cert );
798+ cert = NULL ;
799+ AssertIntEQ (0 , load_file ("./keys/server-cert.der" , & cert , & certSz ));
800+ ctx -> privateKeyCount = WOLFSSH_MAX_PVT_KEYS ;
801+ AssertIntEQ (WS_SUCCESS ,
802+ wolfSSH_CTX_UseCert_buffer (ctx , cert , certSz , WOLFSSH_FORMAT_ASN1 ));
803+ AssertIntEQ (certSz , ctx -> privateKey [0 ].certSz );
804+ AssertIntEQ (0 , XMEMCMP (ctx -> privateKey [0 ].cert , cert , certSz ));
805+ /* publicKeyAlgo stays stale from the fabricated count; ctx freed below. */
806+ ctx -> privateKeyCount = count ;
807+
808+ /* No matching slot and no room: rejected, and the DER is freed. */
809+ lastFmt = ctx -> privateKey [0 ].publicKeyFmt ;
810+ ctx -> privateKey [0 ].publicKeyFmt = ID_NONE ;
811+ ctx -> privateKeyCount = WOLFSSH_MAX_PVT_KEYS ;
812+ AssertIntEQ (WS_CTX_KEY_COUNT_E ,
813+ wolfSSH_CTX_UseCert_buffer (ctx , cert , certSz , WOLFSSH_FORMAT_ASN1 ));
814+ AssertIntEQ (WOLFSSH_MAX_PVT_KEYS , ctx -> privateKeyCount );
815+ ctx -> privateKeyCount = count ;
816+ ctx -> privateKey [0 ].publicKeyFmt = lastFmt ;
766817#endif
767818
768819 wolfSSH_CTX_free (ctx );
769820 free (cert );
821+ #ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
822+ free (key );
823+ #endif
770824#endif /* WOLFSSH_CERTS */
771825}
772826
0 commit comments