@@ -5062,11 +5062,8 @@ static int ParseECCPubKey(WOLFSSH *ssh,
50625062{
50635063 int ret;
50645064#ifndef WOLFSSH_NO_ECDSA
5065- const byte* q;
5066- word32 qSz, pubKeyIdx = 0;
5065+ word32 pubKeyIdx = 0;
50675066 int primeId = 0;
5068- const char* algoName;
5069- const char* curveName;
50705067
50715068 ret = wc_ecc_init_ex(&sigKeyBlock_ptr->sk.ecc.key, ssh->ctx->heap,
50725069 INVALID_DEVID);
@@ -5077,50 +5074,73 @@ static int ParseECCPubKey(WOLFSSH *ssh,
50775074 if (ret != 0)
50785075 ret = WS_ECC_E;
50795076 else
5080- ret = GetStringRef(&qSz, &q, pubKey, pubKeySz, &pubKeyIdx) ;
5077+ ret = WS_SUCCESS ;
50815078
5082- /* The algorithm name in the key blob must match the negotiated host key
5083- * algorithm. A MitM must not be able to swap in a different curve by
5084- * lying in the blob, so don't trust the blob to choose the curve. */
5079+ /* Get the algorithm name in the key block. It must match the
5080+ * negotiated host key algorithm. Do not trust the key blob to
5081+ * choose the curve. */
50855082 if (ret == WS_SUCCESS) {
5086- algoName = IdToName(ssh->handshake->pubKeyId);
5087- if (qSz != (word32)WSTRLEN(algoName)
5088- || WMEMCMP(q, algoName, qSz) != 0)
5089- ret = WS_INVALID_ALGO_ID;
5083+ const char* algoName;
5084+ const byte* keyAlgoName;
5085+ word32 keyAlgoNameSz;
5086+
5087+ ret = GetStringRef(&keyAlgoNameSz, &keyAlgoName,
5088+ pubKey, pubKeySz, &pubKeyIdx);
5089+
5090+ if (ret == WS_SUCCESS) {
5091+ algoName = IdToName(ssh->handshake->pubKeyId);
5092+ if (keyAlgoNameSz != (word32)WSTRLEN(algoName)
5093+ || WMEMCMP(keyAlgoName, algoName, keyAlgoNameSz) != 0) {
5094+ ret = WS_INVALID_ALGO_ID;
5095+ }
5096+ }
50905097 }
50915098
50925099 /* Derive the curve from the negotiated algorithm, not from the blob. */
50935100 if (ret == WS_SUCCESS) {
50945101 primeId = wcPrimeForId(ssh->handshake->pubKeyId);
5095- if (primeId == ECC_CURVE_INVALID)
5102+ if (primeId == ECC_CURVE_INVALID) {
50965103 ret = WS_INVALID_PRIME_CURVE;
5104+ }
50975105 }
50985106
50995107 /* The curve name (RFC 5656 section 3.1) in the blob must match the
51005108 * curve of the negotiated algorithm. */
5101- if (ret == WS_SUCCESS)
5102- ret = GetStringRef(&qSz, &q, pubKey, pubKeySz, &pubKeyIdx);
5103-
51045109 if (ret == WS_SUCCESS) {
5105- curveName = PrimeNameForId(ssh->handshake->pubKeyId);
5106- if (qSz != (word32)WSTRLEN(curveName)
5107- || WMEMCMP(q, curveName, qSz) != 0)
5108- ret = WS_INVALID_PRIME_CURVE;
5110+ const char* curveName;
5111+ const byte* keyCurveName;
5112+ word32 keyCurveNameSz;
5113+
5114+ ret = GetStringRef(&keyCurveNameSz, &keyCurveName,
5115+ pubKey, pubKeySz, &pubKeyIdx);
5116+
5117+ if (ret == WS_SUCCESS) {
5118+ curveName = PrimeNameForId(ssh->handshake->pubKeyId);
5119+ if (keyCurveNameSz != (word32)WSTRLEN(curveName)
5120+ || WMEMCMP(keyCurveName, curveName, keyCurveNameSz) != 0) {
5121+ ret = WS_INVALID_PRIME_CURVE;
5122+ }
5123+ }
51095124 }
51105125
5111- if (ret == WS_SUCCESS)
5126+ if (ret == WS_SUCCESS) {
5127+ const byte* q;
5128+ word32 qSz;
5129+
51125130 ret = GetStringRef(&qSz, &q, pubKey, pubKeySz, &pubKeyIdx);
51135131
5114- if (ret == WS_SUCCESS) {
5115- ret = wc_ecc_import_x963_ex(q, qSz,
5116- &sigKeyBlock_ptr->sk.ecc.key, primeId);
5117- if (ret == 0) {
5118- sigKeyBlock_ptr->keySz =
5119- (word32)sizeof(sigKeyBlock_ptr->sk.ecc.key);
5120- sigKeyBlock_ptr->keyAllocated = 1;
5132+ if (ret == WS_SUCCESS) {
5133+ ret = wc_ecc_import_x963_ex(q, qSz,
5134+ &sigKeyBlock_ptr->sk.ecc.key, primeId);
5135+ if (ret == 0) {
5136+ sigKeyBlock_ptr->keySz =
5137+ (word32)sizeof(sigKeyBlock_ptr->sk.ecc.key);
5138+ sigKeyBlock_ptr->keyAllocated = 1;
5139+ }
5140+ else {
5141+ ret = WS_ECC_E;
5142+ }
51215143 }
5122- else
5123- ret = WS_ECC_E;
51245144 }
51255145#else
51265146 WOLFSSH_UNUSED(ssh);
0 commit comments