@@ -4204,60 +4204,61 @@ static int ParseECCPubKey(WOLFSSH *ssh,
42044204
42054205
42064206#ifdef WOLFSSH_CERTS
4207- /* finds the leaf certificate and verifies it with known CA's
4207+ /* finds the leaf certificate and optionally the bounds of the cert chain,
42084208 * returns WS_SUCCESS on success */
4209- static int ParseAndVerifyCert (WOLFSSH * ssh , byte * in , word32 inSz ,
4210- byte * * leafOut , word32 * leafOutSz )
4209+ static int ParseCertChain (byte * in , word32 inSz ,
4210+ byte * * certChain , word32 * certChainSz , word32 * certCount ,
4211+ byte * * leafOut , word32 * leafOutSz )
42114212{
42124213 int ret ;
4213- word32 l = 0 , m = 0 ;
4214+ word32 sz = 0 , idx = 0 ;
42144215 word32 ocspCount = 0 ;
4215- word32 certCount = 0 ;
4216- byte * certChain = NULL ;
4217- word32 certChainSz = 0 ;
4218- word32 count ;
4216+ byte * chain = NULL ;
4217+ word32 chainSz = 0 ;
4218+ word32 count , countIdx ;
42194219
42204220 /* Skip the name */
4221- ret = GetSize (& l , in , inSz , & m );
4222- m += l ;
4221+ ret = GetSize (& sz , in , inSz , & idx );
42234222
42244223 if (ret == WS_SUCCESS ) {
4224+ idx += sz ;
4225+
42254226 /* Get the cert count */
4226- ret = GetUint32 (& certCount , in , inSz , & m );
4227+ ret = GetUint32 (& count , in , inSz , & idx );
42274228 }
42284229
42294230 if (ret == WS_SUCCESS ) {
4230- WLOG (WS_LOG_INFO , "Peer sent certificate count of %d" , certCount );
4231- certChain = in + m ;
4232-
4233- for (count = certCount ; count > 0 ; count -- ) {
4234- word32 certSz = 0 ;
4231+ WLOG (WS_LOG_INFO , "Peer sent certificate count of %d" , count );
4232+ chain = in + idx ;
42354233
4236- ret = GetSize (& certSz , in , inSz , & m );
4234+ for (countIdx = count ; countIdx > 0 ; countIdx -- ) {
4235+ ret = GetSize (& sz , in , inSz , & idx );
42374236 if (ret != WS_SUCCESS ) {
42384237 break ;
42394238 }
4240- WLOG (WS_LOG_INFO , "Adding certificate size %u" , certSz );
4239+ WLOG (WS_LOG_INFO , "Adding certificate size %u" , sz );
42414240
42424241 /* store leaf cert size to present to user callback */
4243- if (count == certCount && leafOut != NULL ) {
4244- * leafOutSz = certSz ;
4245- * leafOut = in + m ;
4242+ if (countIdx == count ) {
4243+ if (leafOut != NULL && leafOutSz != NULL ) {
4244+ * leafOutSz = sz ;
4245+ * leafOut = in + idx ;
4246+ }
42464247 }
4247- certChainSz += certSz + UINT32_SZ ;
4248- m += certSz ;
4248+ chainSz += sz + UINT32_SZ ;
4249+ idx += sz ;
42494250 }
42504251
42514252 /* get OCSP count */
42524253 if (ret == WS_SUCCESS ) {
4253- ret = GetUint32 (& ocspCount , in , inSz , & m );
4254+ ret = GetUint32 (& ocspCount , in , inSz , & idx );
42544255 }
42554256
42564257 if (ret == WS_SUCCESS ) {
42574258 WLOG (WS_LOG_INFO , "Peer sent OCSP count of %u" , ocspCount );
42584259
42594260 /* RFC 6187 section 2.1 OCSP count must not exceed cert count */
4260- if (ocspCount > certCount ) {
4261+ if (ocspCount > count ) {
42614262 WLOG (WS_LOG_ERROR , "Error more OCSP then Certs" );
42624263 ret = WS_FATAL_ERROR ;
42634264 }
@@ -4271,7 +4272,36 @@ static int ParseAndVerifyCert(WOLFSSH* ssh, byte* in, word32 inSz,
42714272 }
42724273 }
42734274
4274- /* verify the certificate chain */
4275+ if (ret == WS_SUCCESS ) {
4276+ if (certChain != NULL && certChainSz != NULL && certCount != NULL ) {
4277+ * certChain = chain ;
4278+ * certChainSz = chainSz ;
4279+ * certCount = count ;
4280+ }
4281+ }
4282+
4283+ return ret ;
4284+ }
4285+
4286+
4287+ static int ParseLeafCert (byte * in , word32 inSz ,
4288+ byte * * leafOut , word32 * leafOutSz )
4289+ {
4290+ return ParseCertChain (in , inSz , NULL , NULL , NULL , leafOut , leafOutSz );
4291+ }
4292+
4293+
4294+ static int ParseCertChainVerify (WOLFSSH * ssh , byte * in , word32 inSz ,
4295+ byte * * leafOut , word32 * leafOutSz )
4296+ {
4297+ byte * certChain = NULL ;
4298+ word32 certChainSz = 0 , certCount = 0 ;
4299+ int ret ;
4300+
4301+ ret = ParseCertChain (in , inSz ,
4302+ & certChain , & certChainSz , & certCount ,
4303+ leafOut , leafOutSz );
4304+
42754305 if (ret == WS_SUCCESS ) {
42764306 ret = wolfSSH_CERTMAN_VerifyCerts_buffer (ssh -> ctx -> certMan ,
42774307 certChain , certChainSz , certCount );
@@ -4292,7 +4322,7 @@ static int ParsePubKeyCert(WOLFSSH* ssh, byte* in, word32 inSz, byte** out,
42924322 byte * leaf = NULL ;
42934323 word32 leafSz = 0 ;
42944324
4295- ret = ParseAndVerifyCert (ssh , in , inSz , & leaf , & leafSz );
4325+ ret = ParseCertChainVerify (ssh , in , inSz , & leaf , & leafSz );
42964326 if (ret == WS_SUCCESS ) {
42974327 int error = 0 ;
42984328 struct DecodedCert dCert ;
@@ -6453,22 +6483,29 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
64536483
64546484 #ifdef WOLFSSH_CERTS
64556485 if (ret == WS_SUCCESS && !authFailure ) {
6456- if (pkTypeId == ID_X509V3_SSH_RSA ||
6457- pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP256 ||
6458- pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP384 ||
6459- pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP521 ) {
6460- byte * cert = NULL ;
6486+ if (pkTypeId == ID_X509V3_SSH_RSA
6487+ || pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP256
6488+ || pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP384
6489+ || pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP521 ) {
6490+ byte * cert = NULL ;
64616491 word32 certSz = 0 ;
64626492
6463- ret = ParseAndVerifyCert (ssh , (byte * )pubKeyBlob , pubKeyBlobSz ,
6464- & cert , & certSz );
6493+ if (hasSig ) {
6494+ ret = ParseCertChainVerify (ssh ,
6495+ (byte * )pubKeyBlob , pubKeyBlobSz , & cert , & certSz );
6496+ }
6497+ else {
6498+ ret = ParseLeafCert ((byte * )pubKeyBlob , pubKeyBlobSz ,
6499+ & cert , & certSz );
6500+ }
64656501 if (ret == WS_SUCCESS ) {
64666502 authData -> sf .publicKey .publicKey = cert ;
64676503 authData -> sf .publicKey .publicKeySz = certSz ;
64686504 authData -> sf .publicKey .isCert = 1 ;
64696505 }
64706506 else {
6471- WLOG (WS_LOG_DEBUG , "DUARPK: client cert not verified" );
6507+ WLOG (WS_LOG_DEBUG , "DUARPK: cannot parse client cert chain" );
6508+ ret = WS_SUCCESS ;
64726509 authFailure = 1 ;
64736510 }
64746511 }
@@ -6661,13 +6698,11 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
66616698 }
66626699 }
66636700
6664- if (ret == WS_SUCCESS ) {
6665- if (authFailure ) {
6666- ret = SendUserAuthFailure (ssh , 0 );
6667- }
6668- else if (partialSuccess && hasSig ) {
6669- ret = SendUserAuthFailure (ssh , 1 );
6670- }
6701+ if (authFailure ) {
6702+ ret = SendUserAuthFailure (ssh , 0 );
6703+ }
6704+ else if (partialSuccess && hasSig ) {
6705+ ret = SendUserAuthFailure (ssh , 1 );
66716706 }
66726707
66736708 WLOG (WS_LOG_DEBUG , "Leaving DoUserAuthRequestPublicKey(), ret = %d" , ret );
0 commit comments