@@ -4300,60 +4300,61 @@ static int ParseECCPubKey(WOLFSSH *ssh,
43004300
43014301
43024302#ifdef WOLFSSH_CERTS
4303- /* finds the leaf certificate and verifies it with known CA's
4303+ /* finds the leaf certificate and optionally the bounds of the cert chain,
43044304 * returns WS_SUCCESS on success */
4305- static int ParseAndVerifyCert (WOLFSSH * ssh , byte * in , word32 inSz ,
4306- byte * * leafOut , word32 * leafOutSz )
4305+ static int ParseCertChain (byte * in , word32 inSz ,
4306+ byte * * certChain , word32 * certChainSz , word32 * certCount ,
4307+ byte * * leafOut , word32 * leafOutSz )
43074308{
43084309 int ret ;
4309- word32 l = 0 , m = 0 ;
4310+ word32 sz = 0 , idx = 0 ;
43104311 word32 ocspCount = 0 ;
4311- word32 certCount = 0 ;
4312- byte * certChain = NULL ;
4313- word32 certChainSz = 0 ;
4314- word32 count ;
4312+ byte * chain = NULL ;
4313+ word32 chainSz = 0 ;
4314+ word32 count , countIdx ;
43154315
43164316 /* Skip the name */
4317- ret = GetSize (& l , in , inSz , & m );
4318- m += l ;
4317+ ret = GetSize (& sz , in , inSz , & idx );
43194318
43204319 if (ret == WS_SUCCESS ) {
4320+ idx += sz ;
4321+
43214322 /* Get the cert count */
4322- ret = GetUint32 (& certCount , in , inSz , & m );
4323+ ret = GetUint32 (& count , in , inSz , & idx );
43234324 }
43244325
43254326 if (ret == WS_SUCCESS ) {
4326- WLOG (WS_LOG_INFO , "Peer sent certificate count of %d" , certCount );
4327- certChain = in + m ;
4328-
4329- for (count = certCount ; count > 0 ; count -- ) {
4330- word32 certSz = 0 ;
4327+ WLOG (WS_LOG_INFO , "Peer sent certificate count of %d" , count );
4328+ chain = in + idx ;
43314329
4332- ret = GetSize (& certSz , in , inSz , & m );
4330+ for (countIdx = count ; countIdx > 0 ; countIdx -- ) {
4331+ ret = GetSize (& sz , in , inSz , & idx );
43334332 if (ret != WS_SUCCESS ) {
43344333 break ;
43354334 }
4336- WLOG (WS_LOG_INFO , "Adding certificate size %u" , certSz );
4335+ WLOG (WS_LOG_INFO , "Adding certificate size %u" , sz );
43374336
43384337 /* store leaf cert size to present to user callback */
4339- if (count == certCount && leafOut != NULL ) {
4340- * leafOutSz = certSz ;
4341- * leafOut = in + m ;
4338+ if (countIdx == count ) {
4339+ if (leafOut != NULL && leafOutSz != NULL ) {
4340+ * leafOutSz = sz ;
4341+ * leafOut = in + idx ;
4342+ }
43424343 }
4343- certChainSz += certSz + UINT32_SZ ;
4344- m += certSz ;
4344+ chainSz += sz + UINT32_SZ ;
4345+ idx += sz ;
43454346 }
43464347
43474348 /* get OCSP count */
43484349 if (ret == WS_SUCCESS ) {
4349- ret = GetUint32 (& ocspCount , in , inSz , & m );
4350+ ret = GetUint32 (& ocspCount , in , inSz , & idx );
43504351 }
43514352
43524353 if (ret == WS_SUCCESS ) {
43534354 WLOG (WS_LOG_INFO , "Peer sent OCSP count of %u" , ocspCount );
43544355
43554356 /* RFC 6187 section 2.1 OCSP count must not exceed cert count */
4356- if (ocspCount > certCount ) {
4357+ if (ocspCount > count ) {
43574358 WLOG (WS_LOG_ERROR , "Error more OCSP then Certs" );
43584359 ret = WS_FATAL_ERROR ;
43594360 }
@@ -4367,7 +4368,36 @@ static int ParseAndVerifyCert(WOLFSSH* ssh, byte* in, word32 inSz,
43674368 }
43684369 }
43694370
4370- /* verify the certificate chain */
4371+ if (ret == WS_SUCCESS ) {
4372+ if (certChain != NULL && certChainSz != NULL && certCount != NULL ) {
4373+ * certChain = chain ;
4374+ * certChainSz = chainSz ;
4375+ * certCount = count ;
4376+ }
4377+ }
4378+
4379+ return ret ;
4380+ }
4381+
4382+
4383+ static int ParseLeafCert (byte * in , word32 inSz ,
4384+ byte * * leafOut , word32 * leafOutSz )
4385+ {
4386+ return ParseCertChain (in , inSz , NULL , NULL , NULL , leafOut , leafOutSz );
4387+ }
4388+
4389+
4390+ static int ParseCertChainVerify (WOLFSSH * ssh , byte * in , word32 inSz ,
4391+ byte * * leafOut , word32 * leafOutSz )
4392+ {
4393+ byte * certChain = NULL ;
4394+ word32 certChainSz = 0 , certCount = 0 ;
4395+ int ret ;
4396+
4397+ ret = ParseCertChain (in , inSz ,
4398+ & certChain , & certChainSz , & certCount ,
4399+ leafOut , leafOutSz );
4400+
43714401 if (ret == WS_SUCCESS ) {
43724402 ret = wolfSSH_CERTMAN_VerifyCerts_buffer (ssh -> ctx -> certMan ,
43734403 certChain , certChainSz , certCount );
@@ -4388,7 +4418,7 @@ static int ParsePubKeyCert(WOLFSSH* ssh, byte* in, word32 inSz, byte** out,
43884418 byte * leaf = NULL ;
43894419 word32 leafSz = 0 ;
43904420
4391- ret = ParseAndVerifyCert (ssh , in , inSz , & leaf , & leafSz );
4421+ ret = ParseCertChainVerify (ssh , in , inSz , & leaf , & leafSz );
43924422 if (ret == WS_SUCCESS ) {
43934423 int error = 0 ;
43944424 struct DecodedCert dCert ;
@@ -6549,22 +6579,29 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
65496579
65506580 #ifdef WOLFSSH_CERTS
65516581 if (ret == WS_SUCCESS && !authFailure ) {
6552- if (pkTypeId == ID_X509V3_SSH_RSA ||
6553- pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP256 ||
6554- pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP384 ||
6555- pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP521 ) {
6556- byte * cert = NULL ;
6582+ if (pkTypeId == ID_X509V3_SSH_RSA
6583+ || pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP256
6584+ || pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP384
6585+ || pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP521 ) {
6586+ byte * cert = NULL ;
65576587 word32 certSz = 0 ;
65586588
6559- ret = ParseAndVerifyCert (ssh , (byte * )pubKeyBlob , pubKeyBlobSz ,
6560- & cert , & certSz );
6589+ if (hasSig ) {
6590+ ret = ParseCertChainVerify (ssh ,
6591+ (byte * )pubKeyBlob , pubKeyBlobSz , & cert , & certSz );
6592+ }
6593+ else {
6594+ ret = ParseLeafCert ((byte * )pubKeyBlob , pubKeyBlobSz ,
6595+ & cert , & certSz );
6596+ }
65616597 if (ret == WS_SUCCESS ) {
65626598 authData -> sf .publicKey .publicKey = cert ;
65636599 authData -> sf .publicKey .publicKeySz = certSz ;
65646600 authData -> sf .publicKey .isCert = 1 ;
65656601 }
65666602 else {
6567- WLOG (WS_LOG_DEBUG , "DUARPK: client cert not verified" );
6603+ WLOG (WS_LOG_DEBUG , "DUARPK: cannot parse client cert chain" );
6604+ ret = WS_SUCCESS ;
65686605 authFailure = 1 ;
65696606 }
65706607 }
@@ -6757,13 +6794,11 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
67576794 }
67586795 }
67596796
6760- if (ret == WS_SUCCESS ) {
6761- if (authFailure ) {
6762- ret = SendUserAuthFailure (ssh , 0 );
6763- }
6764- else if (partialSuccess && hasSig ) {
6765- ret = SendUserAuthFailure (ssh , 1 );
6766- }
6797+ if (authFailure ) {
6798+ ret = SendUserAuthFailure (ssh , 0 );
6799+ }
6800+ else if (partialSuccess && hasSig ) {
6801+ ret = SendUserAuthFailure (ssh , 1 );
67676802 }
67686803
67696804 WLOG (WS_LOG_DEBUG , "Leaving DoUserAuthRequestPublicKey(), ret = %d" , ret );
0 commit comments