@@ -11009,6 +11009,8 @@ int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
1100911009#ifndef WOLFSSL_ASN_TEMPLATE
1101011010 int ret = 0;
1101111011 int length = 0;
11012+ int firstLen = 0;
11013+ word32 seqEndIdx = 0;
1101211014#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
1101311015 word32 localIdx;
1101411016 byte tag;
@@ -11066,16 +11068,19 @@ int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
1106611068 }
1106711069#endif /* OPENSSL_EXTRA */
1106811070
11071+ /* Calculate where the sequence should end for public key validation */
11072+ seqEndIdx = *inOutIdx + (word32)length;
11073+
1106911074 /* Get modulus */
11070- ret = GetASNInt(input, inOutIdx, &length , inSz);
11075+ ret = GetASNInt(input, inOutIdx, &firstLen , inSz);
1107111076 if (ret < 0) {
1107211077 return ASN_RSA_KEY_E;
1107311078 }
1107411079 if (nSz)
11075- *nSz = (word32)length ;
11080+ *nSz = (word32)firstLen ;
1107611081 if (n)
1107711082 *n = &input[*inOutIdx];
11078- *inOutIdx += (word32)length ;
11083+ *inOutIdx += (word32)firstLen ;
1107911084
1108011085 /* Get exponent */
1108111086 ret = GetASNInt(input, inOutIdx, &length, inSz);
@@ -11088,6 +11093,18 @@ int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
1108811093 *e = &input[*inOutIdx];
1108911094 *inOutIdx += (word32)length;
1109011095
11096+ /* Detect if this is an RSA private key being passed as public key.
11097+ * An RSA private key has: version (small), modulus (large), exponent,
11098+ * followed by more integers (d, p, q, etc.).
11099+ * An RSA public key has: modulus (large), exponent, and nothing more.
11100+ * If the first integer is small (like version 0) AND there is more data
11101+ * remaining in the sequence, this is likely a private key. */
11102+ if (firstLen <= MAX_VERSION_SZ && *inOutIdx < seqEndIdx) {
11103+ /* First integer is small and there's more data - looks like
11104+ * version field of a private key, not a modulus */
11105+ return ASN_RSA_KEY_E;
11106+ }
11107+
1109111108 return ret;
1109211109#else
1109311110 DECL_ASNGETDATA(dataASN, rsaPublicKeyASN_Length);
@@ -11157,6 +11174,21 @@ int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
1115711174 }
1115811175 }
1115911176#endif
11177+ if (ret == 0) {
11178+ /* Detect if this is an RSA private key being passed as public key.
11179+ * An RSA private key has: version (small int), modulus, exponent, ...
11180+ * An RSA public key has: modulus (large int), exponent, nothing more.
11181+ * If the first integer is small (like version 0) and there's more data
11182+ * after what we consumed, this is likely a private key. */
11183+ word32 nLen = dataASN[RSAPUBLICKEYASN_IDX_PUBKEY_RSA_N].data.ref.length;
11184+ if (nLen <= MAX_VERSION_SZ && *inOutIdx < inSz) {
11185+ /* Check if next byte could be an INTEGER tag - indicating more
11186+ * fields like in a private key structure */
11187+ if (input[*inOutIdx] == ASN_INTEGER) {
11188+ ret = ASN_RSA_KEY_E;
11189+ }
11190+ }
11191+ }
1116011192 if (ret == 0) {
1116111193 /* Return the buffers and lengths asked for. */
1116211194 if (n != NULL) {
0 commit comments