On Wed, 2021-07-07 at 21:52 -0500, Aaron Hill wrote:
- ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), - pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey, - &size, NULL, NULL); + TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, *pcbStructInfo); + + ret = CRYPT_raw_decode_rsa_pub_key(&decodedKey, &size, pbEncoded, cbEncoded); + if (ret) + { + /* Header, exponent, and modulus */ + DWORD bytesNeeded = sizeof(BCRYPT_RSAKEY_BLOB) + sizeof(DWORD) + + decodedKey->modulus.cbData; + + if (!pvStructInfo) + { + *pcbStructInfo = bytesNeeded; + ret = TRUE; + } + else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, + pvStructInfo, pcbStructInfo, bytesNeeded))) + { + BCRYPT_RSAKEY_BLOB *hdr; + + if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) + pvStructInfo = *(BYTE **)pvStructInfo; + + hdr = pvStructInfo; + hdr->Magic = BCRYPT_RSAPUBLIC_MAGIC; + hdr->BitLength = decodedKey->modulus.cbData * 8; + hdr->cbPublicExp = sizeof(DWORD); + hdr->cbModulus = decodedKey->modulus.cbData; + hdr->cbPrime1 = 0; + hdr->cbPrime2 = 0; + /* CNG_RSA_PUBLIC_KEY_BLOB always stores the exponent and modulus + * in big-endian format, so we need to convert from the native + * endianness + */ + CRYPT_memcpy_be((BYTE *)pvStructInfo + sizeof(BCRYPT_RSAKEY_BLOB), + (BYTE *)&decodedKey->pubexp, sizeof(DWORD)); + CRYPT_memcpy_be((BYTE *)pvStructInfo + sizeof(BCRYPT_RSAKEY_BLOB) + + sizeof(DWORD), decodedKey->modulus.pbData, + decodedKey->modulus.cbData);
Exponent and modulus are handled as a byte arrays so native endianess is not relevant there. They should be reversed unconditionally here as well as in the encoder and the tests.