From bba05a3017677caa04f541e34443a40af8e303d0 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Mon, 17 Sep 2007 17:02:58 -0700 Subject: [PATCH] Use simpler form for internal time decoding functions --- dlls/crypt32/decode.c | 300 ++++++++++++++++++++++++++----------------------- 1 files changed, 159 insertions(+), 141 deletions(-) diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c index 01d1092..c5cf989 100644 --- a/dlls/crypt32/decode.c +++ b/dlls/crypt32/decode.c @@ -3444,166 +3444,166 @@ static BOOL CRYPT_AsnDecodeTimeZone(cons #define MIN_ENCODED_TIME_LENGTH 10 -static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType, - LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, - PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) { - BOOL ret; + BOOL ret = FALSE; - if (!pvStructInfo) + if (pbEncoded[0] == ASN_UTCTIME) { - *pcbStructInfo = sizeof(FILETIME); - return TRUE; - } - __TRY - { - ret = TRUE; - if (pbEncoded[0] == ASN_UTCTIME) + if (cbEncoded <= 1) + SetLastError(CRYPT_E_ASN1_EOD); + else if (pbEncoded[1] > 0x7f) { - if (cbEncoded <= 1) - { - SetLastError(CRYPT_E_ASN1_EOD); - ret = FALSE; - } - else if (pbEncoded[1] > 0x7f) - { - /* long-form date strings really can't be valid */ + /* long-form date strings really can't be valid */ + SetLastError(CRYPT_E_ASN1_CORRUPT); + } + else + { + SYSTEMTIME sysTime = { 0 }; + BYTE len = pbEncoded[1]; + + if (len < MIN_ENCODED_TIME_LENGTH) SetLastError(CRYPT_E_ASN1_CORRUPT); - ret = FALSE; - } else { - SYSTEMTIME sysTime = { 0 }; - BYTE len = pbEncoded[1]; - - if (len < MIN_ENCODED_TIME_LENGTH) + ret = TRUE; + pbEncoded += 2; + CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear); + if (sysTime.wYear >= 50) + sysTime.wYear += 1900; + else + sysTime.wYear += 2000; + CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth); + CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay); + CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour); + CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute); + if (ret && len > 0) { - SetLastError(CRYPT_E_ASN1_CORRUPT); - ret = FALSE; + if (len >= 2 && isdigit(*pbEncoded) && + isdigit(*(pbEncoded + 1))) + CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, + sysTime.wSecond); + else if (isdigit(*pbEncoded)) + CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1, + sysTime.wSecond); + if (ret) + ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len, + &sysTime); } - else + if (ret) { - pbEncoded += 2; - CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear); - if (sysTime.wYear >= 50) - sysTime.wYear += 1900; - else - sysTime.wYear += 2000; - CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth); - CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay); - CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour); - CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute); - if (ret && len > 0) - { - if (len >= 2 && isdigit(*pbEncoded) && - isdigit(*(pbEncoded + 1))) - CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, - sysTime.wSecond); - else if (isdigit(*pbEncoded)) - CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1, - sysTime.wSecond); - if (ret) - ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len, - &sysTime); - } - if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, - pDecodePara, pvStructInfo, pcbStructInfo, - sizeof(FILETIME)))) - { - if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) - pvStructInfo = *(BYTE **)pvStructInfo; + if (!pvStructInfo) + *pcbStructInfo = sizeof(FILETIME); + else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, + pvStructInfo, pcbStructInfo, sizeof(FILETIME)))) ret = SystemTimeToFileTime(&sysTime, (FILETIME *)pvStructInfo); - } } } } - else + } + else + SetLastError(CRYPT_E_ASN1_BADTAG); + return ret; +} + +static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +{ + BOOL ret = FALSE; + + __TRY + { + DWORD bytesNeeded; + + ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded, + dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL); + if (ret) { - SetLastError(CRYPT_E_ASN1_BADTAG); - ret = FALSE; + if (!pvStructInfo) + *pcbStructInfo = bytesNeeded; + else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, + pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded))) + { + if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) + pvStructInfo = *(BYTE **)pvStructInfo; + ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded, + dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, + &bytesNeeded, NULL); + } } } __EXCEPT_PAGE_FAULT { SetLastError(STATUS_ACCESS_VIOLATION); - ret = FALSE; } __ENDTRY return ret; } -static BOOL WINAPI CRYPT_AsnDecodeGeneralizedTime(DWORD dwCertEncodingType, - LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, - PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) { - BOOL ret; + BOOL ret = FALSE; - if (!pvStructInfo) + if (pbEncoded[0] == ASN_GENERALTIME) { - *pcbStructInfo = sizeof(FILETIME); - return TRUE; - } - __TRY - { - ret = TRUE; - if (pbEncoded[0] == ASN_GENERALTIME) + if (cbEncoded <= 1) + SetLastError(CRYPT_E_ASN1_EOD); + else if (pbEncoded[1] > 0x7f) { - if (cbEncoded <= 1) - { - SetLastError(CRYPT_E_ASN1_EOD); - ret = FALSE; - } - else if (pbEncoded[1] > 0x7f) - { - /* long-form date strings really can't be valid */ + /* long-form date strings really can't be valid */ + SetLastError(CRYPT_E_ASN1_CORRUPT); + } + else + { + BYTE len = pbEncoded[1]; + + if (len < MIN_ENCODED_TIME_LENGTH) SetLastError(CRYPT_E_ASN1_CORRUPT); - ret = FALSE; - } else { - BYTE len = pbEncoded[1]; + SYSTEMTIME sysTime = { 0 }; - if (len < MIN_ENCODED_TIME_LENGTH) - { - SetLastError(CRYPT_E_ASN1_CORRUPT); - ret = FALSE; - } - else + ret = TRUE; + pbEncoded += 2; + CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear); + CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth); + CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay); + CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour); + if (ret && len > 0) { - SYSTEMTIME sysTime = { 0 }; - - pbEncoded += 2; - CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear); - CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth); - CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay); - CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour); + CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, + sysTime.wMinute); if (ret && len > 0) - { CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, - sysTime.wMinute); - if (ret && len > 0) - CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, - sysTime.wSecond); - if (ret && len > 0 && (*pbEncoded == '.' || - *pbEncoded == ',')) - { - BYTE digits; - - pbEncoded++; - len--; - /* workaround macro weirdness */ - digits = min(len, 3); - CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits, - sysTime.wMilliseconds); - } - if (ret) - ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len, - &sysTime); + sysTime.wSecond); + if (ret && len > 0 && (*pbEncoded == '.' || + *pbEncoded == ',')) + { + BYTE digits; + + pbEncoded++; + len--; + /* workaround macro weirdness */ + digits = min(len, 3); + CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits, + sysTime.wMilliseconds); } - if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, - pDecodePara, pvStructInfo, pcbStructInfo, - sizeof(FILETIME)))) + if (ret) + ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len, + &sysTime); + } + if (ret) + { + if (!pvStructInfo) + *pcbStructInfo = sizeof(FILETIME); + else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, + pvStructInfo, pcbStructInfo, sizeof(FILETIME)))) { if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) pvStructInfo = *(BYTE **)pvStructInfo; @@ -3613,18 +3613,31 @@ static BOOL WINAPI CRYPT_AsnDecodeGenera } } } - else - { - SetLastError(CRYPT_E_ASN1_BADTAG); - ret = FALSE; - } } - __EXCEPT_PAGE_FAULT + else + SetLastError(CRYPT_E_ASN1_BADTAG); + return ret; +} + +static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret; + InternalDecodeFunc decode = NULL; + + if (pbEncoded[0] == ASN_UTCTIME) + decode = CRYPT_AsnDecodeUtcTimeInternal; + else if (pbEncoded[0] == ASN_GENERALTIME) + decode = CRYPT_AsnDecodeGeneralizedTime; + if (decode) + ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo, + pcbStructInfo, pcbDecoded); + else { - SetLastError(STATUS_ACCESS_VIOLATION); + SetLastError(CRYPT_E_ASN1_BADTAG); ret = FALSE; } - __ENDTRY return ret; } @@ -3636,18 +3649,23 @@ static BOOL WINAPI CRYPT_AsnDecodeChoice __TRY { - if (pbEncoded[0] == ASN_UTCTIME) - ret = CRYPT_AsnDecodeUtcTime(dwCertEncodingType, lpszStructType, - pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, - pcbStructInfo); - else if (pbEncoded[0] == ASN_GENERALTIME) - ret = CRYPT_AsnDecodeGeneralizedTime(dwCertEncodingType, - lpszStructType, pbEncoded, cbEncoded, dwFlags, pDecodePara, - pvStructInfo, pcbStructInfo); - else + DWORD bytesNeeded; + + ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded, + dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL); + if (ret) { - SetLastError(CRYPT_E_ASN1_BADTAG); - ret = FALSE; + if (!pvStructInfo) + *pcbStructInfo = bytesNeeded; + else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, + pvStructInfo, pcbStructInfo, bytesNeeded))) + { + if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) + pvStructInfo = *(BYTE **)pvStructInfo; + ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded, + dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, + &bytesNeeded, NULL); + } } } __EXCEPT_PAGE_FAULT -- 1.4.1