diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c index 5601862b629..669b1251d16 100644 --- a/dlls/crypt32/decode.c +++ b/dlls/crypt32/decode.c @@ -4168,7 +4168,37 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo); else - SetLastError(ERROR_FILE_NOT_FOUND); + { + static HCRYPTOIDFUNCSET decodeObjectSet = NULL; + CryptDecodeObjectFunc pCryptDecodeObject; + + /* Try CryptDecodeObject function. Don't call CryptDecodeObject + * directly, as that could cause an infinite loop. + */ + if (!decodeObjectSet) + decodeObjectSet = + CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0); + CryptGetOIDFunctionAddress(decodeObjectSet, dwCertEncodingType, + lpszStructType, 0, (void **)&pCryptDecodeObject, &hFunc); + if (pCryptDecodeObject) + { + if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) + { + ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType, + pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo); + if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, + pvStructInfo, pcbStructInfo, *pcbStructInfo))) + ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType, + pbEncoded, cbEncoded, dwFlags, *(BYTE **)pvStructInfo, + pcbStructInfo); + } + else + ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType, + pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo); + } + else + SetLastError(ERROR_FILE_NOT_FOUND); + } if (hFunc) CryptFreeOIDFunctionAddress(hFunc, 0); return ret; diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c index 591a1e0b690..aa650bd457e 100644 --- a/dlls/crypt32/encode.c +++ b/dlls/crypt32/encode.c @@ -3513,7 +3513,37 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, ret = encodeFunc(dwCertEncodingType, lpszStructType, pvStructInfo, dwFlags, pEncodePara, pvEncoded, pcbEncoded); else - SetLastError(ERROR_FILE_NOT_FOUND); + { + static HCRYPTOIDFUNCSET encodeObjectSet = NULL; + CryptEncodeObjectFunc pCryptEncodeObject; + + /* Try CryptEncodeObject function. Don't call CryptEncodeObject + * directly, as that could cause an infinite loop. + */ + if (!encodeObjectSet) + encodeObjectSet = + CryptInitOIDFunctionSet(CRYPT_OID_ENCODE_OBJECT_FUNC, 0); + CryptGetOIDFunctionAddress(encodeObjectSet, dwCertEncodingType, + lpszStructType, 0, (void **)&pCryptEncodeObject, &hFunc); + if (pCryptEncodeObject) + { + if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) + { + ret = pCryptEncodeObject(dwCertEncodingType, lpszStructType, + pvStructInfo, NULL, pcbEncoded); + if (ret && (ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, + pvEncoded, pcbEncoded, *pcbEncoded))) + ret = pCryptEncodeObject(dwCertEncodingType, + lpszStructType, pvStructInfo, *(BYTE **)pvEncoded, + pcbEncoded); + } + else + ret = pCryptEncodeObject(dwCertEncodingType, lpszStructType, + pvStructInfo, pvEncoded, pcbEncoded); + } + else + SetLastError(ERROR_FILE_NOT_FOUND); + } if (hFunc) CryptFreeOIDFunctionAddress(hFunc, 0); return ret;