|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: xmsasnx.cpp
//
// Contents:
// Encode/Decode APIs
//
// Implementation using the MS ASN1 compiler / RTS.
//
// Functions: CryptEncodeObject
// CryptDecodeObject
//
// History: 02-Nov-98 philh created
//
//--------------------------------------------------------------------------
//
// ASN1C needs to be defined so that the compiler does not pickup the ASN1 routines from
// the import table
//
#ifdef _X86_
#define ASN1C
#endif
#include "stdafx.h"
#include <windows.h>
#include <wincrypt.h>
#include <malloc.h>
#include "xenroll.h"
#include "cenroll.h"
#pragma warning(disable:4100) // 'var' : unreferenced formal parameter
#include "pkiasn1.h"
#pragma warning(default:4100) // re-enable 4100
#include "pkialloc.h"
#include "crypttls.h"
extern "C" { #include "xmsasn.h"
}
#define NO_OSS_DEBUG
#include <dbgdef.h>
// All the *pvInfo extra stuff needs to be aligned
#define INFO_LEN_ALIGN(Len) ((Len + 7) & ~7)
HCRYPTASN1MODULE hAsn1Module = NULL; HMODULE hCrypt32Dll = NULL;
typedef HCRYPTASN1MODULE (WINAPI *PFN_CRYPT_INSTALL_ASN1_MODULE) ( IN ASN1module_t pMod, IN DWORD dwFlags, IN void *pvReserved ); typedef BOOL (WINAPI *PFN_CRYPT_UNINSTALL_ASN1_MODULE) ( IN HCRYPTASN1MODULE hAsn1Module );
typedef ASN1encoding_t (WINAPI *PFN_CRYPT_GET_ASN1_ENCODER)( IN HCRYPTASN1MODULE hAsn1Module ); typedef ASN1decoding_t (WINAPI *PFN_CRYPT_GET_ASN1_DECODER)( IN HCRYPTASN1MODULE hAsn1Module );
PFN_CRYPT_INSTALL_ASN1_MODULE pfnCryptInstallAsn1Module = NULL; PFN_CRYPT_UNINSTALL_ASN1_MODULE pfnCryptUninstallAsn1Module = NULL; PFN_CRYPT_GET_ASN1_ENCODER pfnCryptGetAsn1Encoder = NULL; PFN_CRYPT_GET_ASN1_DECODER pfnCryptGetAsn1Decoder = NULL;
//+-------------------------------------------------------------------------
// Function: GetEncoder/GetDecoder
//
// Synopsis: Initialize thread local storage for the asn libs
//
// Returns: pointer to an initialized Asn1 encoder/decoder data
// structures
//--------------------------------------------------------------------------
static ASN1encoding_t GetEncoder(void) { if (hAsn1Module) return pfnCryptGetAsn1Encoder(hAsn1Module); else return NULL; }
static ASN1decoding_t GetDecoder(void) { if (hAsn1Module) return pfnCryptGetAsn1Decoder(hAsn1Module); else return NULL; }
//+-------------------------------------------------------------------------
// Cert allocation and free functions
//--------------------------------------------------------------------------
static void *CertAlloc( IN size_t cbBytes ) { void *pv; pv = malloc(cbBytes); if (pv == NULL) SetLastError((DWORD) E_OUTOFMEMORY); return pv; } static void CertFree( IN void *pv ) { free(pv); }
//+-------------------------------------------------------------------------
// Encode an ASN1 formatted info structure
//
// Called by the Asn1X509*Encode() functions.
//--------------------------------------------------------------------------
static BOOL Asn1InfoEncode( IN int pdunum, IN void *pAsn1Info, OUT BYTE *pbEncoded, IN OUT DWORD *pcbEncoded ) { ASN1encoding_t ge = GetEncoder();
if (NULL == ge) return FALSE;
return PkiAsn1EncodeInfo( ge, pdunum, pAsn1Info, pbEncoded, pcbEncoded); }
//+-------------------------------------------------------------------------
// Decode into an allocated, ASN1 formatted info structure
//
// Called by the Asn1X509*Decode() functions.
//--------------------------------------------------------------------------
static BOOL Asn1InfoDecodeAndAlloc( IN int pdunum, IN const BYTE *pbEncoded, IN DWORD cbEncoded, OUT void **ppAsn1Info ) { return PkiAsn1DecodeAndAllocInfo( GetDecoder(), pdunum, pbEncoded, cbEncoded, ppAsn1Info); }
//+-------------------------------------------------------------------------
// Free an allocated, ASN1 formatted info structure
//
// Called by the Asn1X509*Decode() functions.
//--------------------------------------------------------------------------
static void Asn1InfoFree( IN int pdunum, IN void *pAsn1Info ) { if (pAsn1Info) { DWORD dwErr = GetLastError();
// TlsGetValue globbers LastError
PkiAsn1FreeInfo(GetDecoder(), pdunum, pAsn1Info);
SetLastError(dwErr); } }
//+-------------------------------------------------------------------------
// ASN1 X509 v3 ASN.1 Set / Get functions
//
// Called by the ASN1 X509 encode/decode functions.
//
// Assumption: all types are UNBOUNDED.
//
// The Get functions decrement *plRemainExtra and advance
// *ppbExtra. When *plRemainExtra becomes negative, the functions continue
// with the length calculation but stop doing any copies.
// The functions don't return an error for a negative *plRemainExtra.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// Set/Get Object Identifier string
//--------------------------------------------------------------------------
static BOOL Asn1X509SetObjId( IN LPSTR pszObjId, OUT ObjectID *pAsn1 ) { pAsn1->count = sizeof(pAsn1->value) / sizeof(pAsn1->value[0]); if (PkiAsn1ToObjectIdentifier(pszObjId, &pAsn1->count, pAsn1->value)) return TRUE; else { SetLastError((DWORD) CRYPT_E_BAD_ENCODE); return FALSE; } }
static void Asn1X509GetObjId( IN ObjectID *pAsn1, IN DWORD /*dwFlags*/, OUT LPSTR *ppszObjId, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra ) { LONG lRemainExtra = *plRemainExtra; BYTE *pbExtra = *ppbExtra; LONG lAlignExtra; DWORD cbObjId;
cbObjId = lRemainExtra > 0 ? lRemainExtra : 0; PkiAsn1FromObjectIdentifier( pAsn1->count, pAsn1->value, (LPSTR) pbExtra, &cbObjId );
lAlignExtra = INFO_LEN_ALIGN(cbObjId); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { if(cbObjId) { *ppszObjId = (LPSTR) pbExtra; } else *ppszObjId = NULL; pbExtra += lAlignExtra; }
*plRemainExtra = lRemainExtra; *ppbExtra = pbExtra; }
static BOOL WINAPI Asn1X509CtlUsageEncode( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN PCTL_USAGE pInfo, OUT BYTE *pbEncoded, IN OUT DWORD *pcbEncoded );
static BOOL WINAPI Asn1X509CtlUsageDecode( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, OUT PCTL_USAGE pInfo, IN OUT DWORD *pcbInfo );
static BOOL WINAPI Asn1RequestInfoDecode( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, OUT RequestFlags * pInfo, IN OUT DWORD *pcbInfo );
static BOOL WINAPI Asn1RequestInfoEncode( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN RequestFlags * pInfo, OUT BYTE *pbEncoded, IN OUT DWORD *pcbEncoded );
static BOOL WINAPI Asn1CSPProviderEncode( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN PCRYPT_CSP_PROVIDER pCSPProvider, OUT BYTE *pbEncoded, IN OUT DWORD *pcbEncoded );
static BOOL WINAPI Asn1NameValueEncode( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN PCRYPT_ENROLLMENT_NAME_VALUE_PAIR pNameValue, OUT BYTE *pbEncoded, IN OUT DWORD *pcbEncoded );
static const CRYPT_OID_FUNC_ENTRY X509EncodeFuncTable[] = { X509_ENHANCED_KEY_USAGE, Asn1X509CtlUsageEncode, XENROLL_REQUEST_INFO, Asn1RequestInfoEncode, szOID_ENROLLMENT_CSP_PROVIDER, Asn1CSPProviderEncode, szOID_ENROLLMENT_NAME_VALUE_PAIR, Asn1NameValueEncode, };
#define X509_ENCODE_FUNC_COUNT (sizeof(X509EncodeFuncTable) / \
sizeof(X509EncodeFuncTable[0]))
static const CRYPT_OID_FUNC_ENTRY X509DecodeFuncTable[] = { X509_ENHANCED_KEY_USAGE, Asn1X509CtlUsageDecode, XENROLL_REQUEST_INFO, Asn1RequestInfoDecode };
#define X509_DECODE_FUNC_COUNT (sizeof(X509DecodeFuncTable) / \
sizeof(X509DecodeFuncTable[0]))
//+=========================================================================
// Certificate Management Messages over CMS (CMC) Encode/Decode Functions
//==========================================================================
BOOL WINAPI Asn1CmcDataEncodeEx( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN PCMC_DATA_INFO pInfo, IN DWORD dwFlags, IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara, OUT OPTIONAL void *pvEncoded, IN OUT DWORD *pcbEncoded ); BOOL WINAPI Asn1CmcDataDecodeEx( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara, OUT OPTIONAL void *pvStructInfo, IN OUT DWORD *pcbStructInfo );
BOOL WINAPI Asn1CmcResponseEncodeEx( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN PCMC_RESPONSE_INFO pInfo, IN DWORD dwFlags, IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara, OUT OPTIONAL void *pvEncoded, IN OUT DWORD *pcbEncoded ); BOOL WINAPI Asn1CmcResponseDecodeEx( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara, OUT OPTIONAL void *pvStructInfo, IN OUT DWORD *pcbStructInfo );
BOOL WINAPI Asn1CmcStatusEncodeEx( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN PCMC_STATUS_INFO pInfo, IN DWORD dwFlags, IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara, OUT OPTIONAL void *pvEncoded, IN OUT DWORD *pcbEncoded ); BOOL WINAPI Asn1CmcStatusDecodeEx( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara, OUT OPTIONAL void *pvStructInfo, IN OUT DWORD *pcbStructInfo );
BOOL WINAPI Asn1CmcAddExtensionsEncodeEx( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN PCMC_ADD_EXTENSIONS_INFO pInfo, IN DWORD dwFlags, IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara, OUT OPTIONAL void *pvEncoded, IN OUT DWORD *pcbEncoded ); BOOL WINAPI Asn1CmcAddExtensionsDecodeEx( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara, OUT OPTIONAL void *pvStructInfo, IN OUT DWORD *pcbStructInfo );
BOOL WINAPI Asn1CmcAddAttributesEncodeEx( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN PCMC_ADD_ATTRIBUTES_INFO pInfo, IN DWORD dwFlags, IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara, OUT OPTIONAL void *pvEncoded, IN OUT DWORD *pcbEncoded ); BOOL WINAPI Asn1CmcAddAttributesDecodeEx( IN DWORD dwCertEncodingType, IN LPCSTR lpszStructType, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara, OUT OPTIONAL void *pvStructInfo, IN OUT DWORD *pcbStructInfo );
static const CRYPT_OID_FUNC_ENTRY CmcEncodeExFuncTable[] = { CMC_DATA, Asn1CmcDataEncodeEx, CMC_RESPONSE, Asn1CmcResponseEncodeEx, CMC_STATUS, Asn1CmcStatusEncodeEx, CMC_ADD_EXTENSIONS, Asn1CmcAddExtensionsEncodeEx, CMC_ADD_ATTRIBUTES, Asn1CmcAddAttributesEncodeEx, }; #define CMC_ENCODE_EX_FUNC_COUNT (sizeof(CmcEncodeExFuncTable) / \
sizeof(CmcEncodeExFuncTable[0]))
static const CRYPT_OID_FUNC_ENTRY CmcDecodeExFuncTable[] = { CMC_DATA, Asn1CmcDataDecodeEx, CMC_RESPONSE, Asn1CmcResponseDecodeEx, CMC_STATUS, Asn1CmcStatusDecodeEx, CMC_ADD_EXTENSIONS, Asn1CmcAddExtensionsDecodeEx, CMC_ADD_ATTRIBUTES, Asn1CmcAddAttributesDecodeEx, }; #define CMC_DECODE_EX_FUNC_COUNT (sizeof(CmcDecodeExFuncTable) / \
sizeof(CmcDecodeExFuncTable[0]))
//+-------------------------------------------------------------------------
// Dll initialization
//--------------------------------------------------------------------------
BOOL MSAsnInit( HMODULE hInst) { BOOL fRet; DWORD dwExceptionCode;
if (NULL == (hCrypt32Dll = LoadLibraryA("crypt32.dll"))) goto LoadCrypt32DllError;
if (NULL == (pfnCryptInstallAsn1Module = (PFN_CRYPT_INSTALL_ASN1_MODULE) GetProcAddress( hCrypt32Dll, "I_CryptInstallAsn1Module"))) goto I_CryptInstallAsn1ModuleProcAddressError; if (NULL == (pfnCryptUninstallAsn1Module = (PFN_CRYPT_UNINSTALL_ASN1_MODULE) GetProcAddress( hCrypt32Dll, "I_CryptUninstallAsn1Module"))) goto I_CryptUninstallAsn1ModuleProcAddressError; if (NULL == (pfnCryptGetAsn1Encoder = (PFN_CRYPT_GET_ASN1_ENCODER) GetProcAddress( hCrypt32Dll, "I_CryptGetAsn1Encoder"))) goto I_CryptGetAsn1EncoderProcAddressError; if (NULL == (pfnCryptGetAsn1Decoder = (PFN_CRYPT_GET_ASN1_DECODER) GetProcAddress( hCrypt32Dll, "I_CryptGetAsn1Decoder"))) goto I_CryptGetAsn1DecoderProcAddressError;
__try { XMSASN_Module_Startup(); } __except(EXCEPTION_EXECUTE_HANDLER) { dwExceptionCode = GetExceptionCode(); goto MSAsn1DllException; } if (0 == (hAsn1Module = pfnCryptInstallAsn1Module(XMSASN_Module, 0, NULL))) goto InstallAsn1ModuleError;
if (!CryptInstallOIDFunctionAddress( hInst, X509_ASN_ENCODING, CRYPT_OID_ENCODE_OBJECT_FUNC, X509_ENCODE_FUNC_COUNT, X509EncodeFuncTable, 0)) // dwFlags
goto InstallOidFuncError; if (!CryptInstallOIDFunctionAddress( hInst, X509_ASN_ENCODING, CRYPT_OID_DECODE_OBJECT_FUNC, X509_DECODE_FUNC_COUNT, X509DecodeFuncTable, 0)) // dwFlags
goto InstallOidFuncError;
if (!CryptInstallOIDFunctionAddress( hInst, X509_ASN_ENCODING, CRYPT_OID_ENCODE_OBJECT_EX_FUNC, CMC_ENCODE_EX_FUNC_COUNT, CmcEncodeExFuncTable, 0)) // dwFlags
goto InstallOidFuncError; if (!CryptInstallOIDFunctionAddress( hInst, X509_ASN_ENCODING, CRYPT_OID_DECODE_OBJECT_EX_FUNC, CMC_DECODE_EX_FUNC_COUNT, CmcDecodeExFuncTable, 0)) // dwFlags
goto InstallOidFuncError;
fRet = TRUE;
CommonReturn: return fRet;
InstallOidFuncError: fRet = FALSE; goto CommonReturn;
ErrorReturn: fRet = FALSE;
if (hCrypt32Dll) { FreeLibrary(hCrypt32Dll); hCrypt32Dll = NULL; }
pfnCryptInstallAsn1Module = NULL; pfnCryptUninstallAsn1Module = NULL; pfnCryptGetAsn1Encoder = NULL; pfnCryptGetAsn1Decoder = NULL; hAsn1Module = NULL;
goto CommonReturn;
TRACE_ERROR(LoadCrypt32DllError) TRACE_ERROR(I_CryptInstallAsn1ModuleProcAddressError) TRACE_ERROR(I_CryptUninstallAsn1ModuleProcAddressError) TRACE_ERROR(I_CryptGetAsn1EncoderProcAddressError) TRACE_ERROR(I_CryptGetAsn1DecoderProcAddressError) SET_ERROR_VAR(MSAsn1DllException, dwExceptionCode) TRACE_ERROR(InstallAsn1ModuleError) }
void MSAsnTerm() { if (hAsn1Module) { pfnCryptUninstallAsn1Module(hAsn1Module); __try { XMSASN_Module_Cleanup(); } __except(EXCEPTION_EXECUTE_HANDLER) { }
hAsn1Module = NULL; }
if (hCrypt32Dll) { FreeLibrary(hCrypt32Dll); hCrypt32Dll = NULL; } }
//+-------------------------------------------------------------------------
// ASN1 X509 v3 ASN.1 Set / Get functions
//
// Called by the ASN1 X509 encode/decode functions.
//
// Assumption: all types are UNBOUNDED.
//
// The Get functions decrement *plRemainExtra and advance
// *ppbExtra. When *plRemainExtra becomes negative, the functions continue
// with the length calculation but stop doing any copies.
// The functions don't return an error for a negative *plRemainExtra.
//--------------------------------------------------------------------------
//+-------------------------------------------------------------------------
// Set/Free/Get CTL Usage object identifiers
//--------------------------------------------------------------------------
static BOOL Asn1X509SetCtlUsage( IN PCTL_USAGE pUsage, OUT EnhancedKeyUsage *pAsn1 ) { DWORD cId; LPSTR *ppszId; UsageIdentifier *pAsn1Id;
pAsn1->count = 0; pAsn1->value = NULL; cId = pUsage->cUsageIdentifier; if (0 == cId) return TRUE;
pAsn1Id = (UsageIdentifier *) CertAlloc(cId * sizeof(UsageIdentifier)); if (pAsn1Id == NULL) return FALSE;
pAsn1->count = cId; pAsn1->value = pAsn1Id; ppszId = pUsage->rgpszUsageIdentifier; for ( ; cId > 0; cId--, ppszId++, pAsn1Id++) { if (!Asn1X509SetObjId(*ppszId, pAsn1Id)) return FALSE; }
return TRUE; }
static void Asn1X509FreeCtlUsage( IN EnhancedKeyUsage *pAsn1) { if (pAsn1->value) { CertFree(pAsn1->value); pAsn1->value = NULL; } }
static void Asn1X509GetCtlUsage( IN EnhancedKeyUsage *pAsn1, IN DWORD dwFlags, OUT PCTL_USAGE pUsage, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra ) { LONG lRemainExtra = *plRemainExtra; BYTE *pbExtra = *ppbExtra; LONG lAlignExtra;
DWORD cId; UsageIdentifier *pAsn1Id; LPSTR *ppszId;
cId = pAsn1->count; lAlignExtra = INFO_LEN_ALIGN(cId * sizeof(LPSTR)); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { pUsage->cUsageIdentifier = cId; ppszId = (LPSTR *) pbExtra; pUsage->rgpszUsageIdentifier = ppszId; pbExtra += lAlignExtra; } else ppszId = NULL;
pAsn1Id = pAsn1->value; for ( ; cId > 0; cId--, pAsn1Id++, ppszId++) Asn1X509GetObjId(pAsn1Id, dwFlags, ppszId, &pbExtra, &lRemainExtra);
*plRemainExtra = lRemainExtra; *ppbExtra = pbExtra; }
//+-------------------------------------------------------------------------
// CTL Usage (Enhanced Key Usage) Encode (ASN1 X509)
//--------------------------------------------------------------------------
static BOOL WINAPI Asn1X509CtlUsageEncode( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN PCTL_USAGE pInfo, OUT BYTE *pbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; EnhancedKeyUsage Asn1Info;
if (!Asn1X509SetCtlUsage(pInfo, &Asn1Info)) { *pcbEncoded = 0; fResult = FALSE; } else fResult = Asn1InfoEncode( EnhancedKeyUsage_PDU, &Asn1Info, pbEncoded, pcbEncoded ); Asn1X509FreeCtlUsage(&Asn1Info); return fResult; }
//+-------------------------------------------------------------------------
// CTL Usage (Enhanced Key Usage) Decode (ASN1 X509)
//--------------------------------------------------------------------------
static BOOL WINAPI Asn1X509CtlUsageDecode( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, OUT PCTL_USAGE pInfo, IN OUT DWORD *pcbInfo ) { BOOL fResult; EnhancedKeyUsage *pAsn1Info = NULL; BYTE *pbExtra; LONG lRemainExtra;
if (pInfo == NULL) *pcbInfo = 0;
if (!Asn1InfoDecodeAndAlloc( EnhancedKeyUsage_PDU, pbEncoded, cbEncoded, (void **) &pAsn1Info)) goto ErrorReturn;
// for lRemainExtra < 0, LENGTH_ONLY calculation
lRemainExtra = (LONG) *pcbInfo - sizeof(CTL_USAGE); if (lRemainExtra < 0) { pbExtra = NULL; } else pbExtra = (BYTE *) pInfo + sizeof(CTL_USAGE);
Asn1X509GetCtlUsage(pAsn1Info, dwFlags, pInfo, &pbExtra, &lRemainExtra);
if (lRemainExtra >= 0) *pcbInfo = *pcbInfo - (DWORD) lRemainExtra; else { *pcbInfo = *pcbInfo + (DWORD) -lRemainExtra; if (pInfo) goto LengthError; }
fResult = TRUE; goto CommonReturn;
LengthError: SetLastError((DWORD) ERROR_MORE_DATA); fResult = FALSE; goto CommonReturn; ErrorReturn: *pcbInfo = 0; fResult = FALSE; CommonReturn: Asn1InfoFree(EnhancedKeyUsage_PDU, pAsn1Info); return fResult; }
//+-------------------------------------------------------------------------
// Request Info Encode
//--------------------------------------------------------------------------
static BOOL WINAPI Asn1RequestInfoEncode( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN RequestFlags * pInfo, OUT BYTE *pbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult;
fResult = Asn1InfoEncode( RequestFlags_PDU, pInfo, pbEncoded, pcbEncoded );
return fResult; }
//+-------------------------------------------------------------------------
// Request Info Decode
//--------------------------------------------------------------------------
static BOOL WINAPI Asn1RequestInfoDecode( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD /*dwFlags*/, OUT RequestFlags * pInfo, IN OUT DWORD *pcbInfo ) { BOOL fResult; RequestFlags * pAsn1 = NULL;
if (NULL == pInfo || NULL == pcbInfo) goto ParamError;
if( *pcbInfo < sizeof(RequestFlags) ) goto LengthError;
else if (!Asn1InfoDecodeAndAlloc( RequestFlags_PDU, pbEncoded, cbEncoded, (void **) &pAsn1) || NULL == pAsn1) goto ErrorReturn;
memcpy(pInfo, pAsn1, sizeof(RequestFlags)); fResult = TRUE; goto CommonReturn;
ParamError: SetLastError((DWORD)ERROR_INVALID_PARAMETER); fResult = FALSE; goto CommonReturn; LengthError: SetLastError((DWORD) ERROR_MORE_DATA); fResult = FALSE; goto CommonReturn; ErrorReturn: *pcbInfo = 0; fResult = FALSE; CommonReturn: if (NULL != pAsn1) { Asn1InfoFree(RequestFlags_PDU, pAsn1); } return fResult; }
static BOOL WINAPI Asn1CSPProviderEncode( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN PCRYPT_CSP_PROVIDER pCSPProvider, OUT BYTE *pbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; CSPProvider CspProvider;
CspProvider.keySpec = (int) pCSPProvider->dwKeySpec; CspProvider.cspName.length = (DWORD)wcslen(pCSPProvider->pwszProviderName); CspProvider.cspName.value = pCSPProvider->pwszProviderName;
PkiAsn1SetBitString(&pCSPProvider->Signature, &CspProvider.signature.length, &CspProvider.signature.value);
fResult = Asn1InfoEncode( CSPProvider_PDU, &CspProvider, pbEncoded, pcbEncoded );
return fResult; }
static BOOL WINAPI Asn1NameValueEncode( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN PCRYPT_ENROLLMENT_NAME_VALUE_PAIR pNameValue, OUT BYTE *pbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; EnrollmentNameValuePair NameValue;
NameValue.name.length = (DWORD)wcslen(pNameValue->pwszName); NameValue.name.value = pNameValue->pwszName;
NameValue.value.length = (DWORD)wcslen(pNameValue->pwszValue); NameValue.value.value = pNameValue->pwszValue;
fResult = Asn1InfoEncode( EnrollmentNameValuePair_PDU, &NameValue, pbEncoded, pcbEncoded );
return fResult; }
//+=========================================================================
// Certificate Management Messages over CMS (CMC) Encode/Decode Functions
//==========================================================================
//+-------------------------------------------------------------------------
// Encode an ASN1 formatted info structure
//
// Called by the Asn1X509*Encode() functions.
//--------------------------------------------------------------------------
static BOOL Asn1InfoEncodeEx( IN int pdunum, IN void *pvAsn1Info, IN DWORD dwFlags, IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara, OUT OPTIONAL void *pvEncoded, IN OUT DWORD *pcbEncoded ) { return PkiAsn1EncodeInfoEx( GetEncoder(), pdunum, pvAsn1Info, dwFlags, pEncodePara, pvEncoded, pcbEncoded); }
//+-------------------------------------------------------------------------
// Decode into an ASN1 formatted info structure. Call the callback
// function to convert into the 'C' data structure. If
// CRYPT_DECODE_ALLOC_FLAG is set, call the callback twice. First,
// to get the length of the 'C' data structure. Then after allocating,
// call again to update the 'C' data structure.
//
// Called by the Asn1X509*Decode() functions.
//--------------------------------------------------------------------------
static BOOL Asn1InfoDecodeAndAllocEx( IN int pdunum, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara, IN PFN_PKI_ASN1_DECODE_EX_CALLBACK pfnDecodeExCallback, OUT OPTIONAL void *pvStructInfo, IN OUT DWORD *pcbStructInfo ) { return PkiAsn1DecodeAndAllocInfoEx( GetDecoder(), pdunum, pbEncoded, cbEncoded, dwFlags, pDecodePara, pfnDecodeExCallback, pvStructInfo, pcbStructInfo ); }
//+-------------------------------------------------------------------------
// Set/Get CRYPT_DATA_BLOB (Octet String)
//--------------------------------------------------------------------------
inline void Asn1X509SetOctetString( IN PCRYPT_DATA_BLOB pInfo, OUT OCTETSTRING *pAsn1 ) { pAsn1->value = pInfo->pbData; pAsn1->length = pInfo->cbData; } inline void Asn1X509GetOctetString( IN OCTETSTRING *pAsn1, IN DWORD dwFlags, OUT PCRYPT_DATA_BLOB pInfo, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra ) { PkiAsn1GetOctetString(pAsn1->length, pAsn1->value, dwFlags, pInfo, ppbExtra, plRemainExtra); }
//+-------------------------------------------------------------------------
// Set/Get "Any" DER BLOB
//--------------------------------------------------------------------------
inline void Asn1X509SetAny( IN PCRYPT_OBJID_BLOB pInfo, OUT NOCOPYANY *pAsn1 ) { PkiAsn1SetAny(pInfo, pAsn1); } inline void Asn1X509GetAny( IN NOCOPYANY *pAsn1, IN DWORD dwFlags, OUT PCRYPT_OBJID_BLOB pInfo, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra ) { PkiAsn1GetAny(pAsn1, dwFlags, pInfo, ppbExtra, plRemainExtra); }
//+-------------------------------------------------------------------------
// Set/Free/Get SeqOfAny
//--------------------------------------------------------------------------
BOOL WINAPI Asn1X509SetSeqOfAny( IN DWORD cValue, IN PCRYPT_DER_BLOB pValue, OUT ASN1uint32_t *pAsn1Count, OUT NOCOPYANY **ppAsn1Value ) {
*pAsn1Count = 0; *ppAsn1Value = NULL; if (cValue > 0) { NOCOPYANY *pAsn1Value;
pAsn1Value = (NOCOPYANY *) PkiZeroAlloc(cValue * sizeof(NOCOPYANY)); if (pAsn1Value == NULL) return FALSE; *pAsn1Count = cValue; *ppAsn1Value = pAsn1Value; for ( ; cValue > 0; cValue--, pValue++, pAsn1Value++) Asn1X509SetAny(pValue, pAsn1Value); } return TRUE; }
void Asn1X509FreeSeqOfAny( IN NOCOPYANY *pAsn1Value ) { if (pAsn1Value) PkiFree(pAsn1Value); }
void Asn1X509GetSeqOfAny( IN unsigned int Asn1Count, IN NOCOPYANY *pAsn1Value, IN DWORD dwFlags, OUT DWORD *pcValue, OUT PCRYPT_DER_BLOB *ppValue, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra ) { LONG lAlignExtra; PCRYPT_ATTR_BLOB pValue;
lAlignExtra = INFO_LEN_ALIGN(Asn1Count * sizeof(CRYPT_DER_BLOB)); *plRemainExtra -= lAlignExtra; if (*plRemainExtra >= 0) { *pcValue = Asn1Count; pValue = (PCRYPT_DER_BLOB) *ppbExtra; *ppValue = pValue; *ppbExtra += lAlignExtra; } else pValue = NULL;
for (; Asn1Count > 0; Asn1Count--, pAsn1Value++, pValue++) Asn1X509GetAny(pAsn1Value, dwFlags, pValue, ppbExtra, plRemainExtra); }
//+-------------------------------------------------------------------------
// Set/Free/Get Extensions
//--------------------------------------------------------------------------
BOOL Asn1X509SetExtensions( IN DWORD cExtension, IN PCERT_EXTENSION pExtension, OUT Extensions *pAsn1 ) { Extension *pAsn1Ext;
pAsn1->value = NULL; pAsn1->count = 0; if (cExtension == 0) return TRUE;
pAsn1Ext = (Extension *) PkiZeroAlloc(cExtension * sizeof(Extension)); if (pAsn1Ext == NULL) return FALSE; pAsn1->value = pAsn1Ext; pAsn1->count = cExtension;
for ( ; cExtension > 0; cExtension--, pExtension++, pAsn1Ext++) { if (!Asn1X509SetObjId(pExtension->pszObjId, &pAsn1Ext->extnId)) return FALSE; if (pExtension->fCritical) { pAsn1Ext->critical = TRUE; pAsn1Ext->bit_mask |= critical_present; } Asn1X509SetOctetString(&pExtension->Value, &pAsn1Ext->extnValue); } return TRUE; }
void Asn1X509FreeExtensions( IN Extensions *pAsn1) { if (pAsn1->value) { PkiFree(pAsn1->value); pAsn1->value = NULL; } pAsn1->count = 0; }
void Asn1X509GetExtensions( IN Extensions *pAsn1, IN DWORD dwFlags, OUT DWORD *pcExtension, OUT PCERT_EXTENSION *ppExtension, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra ) { LONG lRemainExtra = *plRemainExtra; BYTE *pbExtra = *ppbExtra; LONG lAlignExtra;
DWORD cExt; Extension *pAsn1Ext; PCERT_EXTENSION pGetExt;
cExt = pAsn1->count; lAlignExtra = INFO_LEN_ALIGN(cExt * sizeof(CERT_EXTENSION)); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { *pcExtension = cExt; pGetExt = (PCERT_EXTENSION) pbExtra; *ppExtension = pGetExt; pbExtra += lAlignExtra; } else pGetExt = NULL;
pAsn1Ext = pAsn1->value; for ( ; cExt > 0; cExt--, pAsn1Ext++, pGetExt++) { Asn1X509GetObjId(&pAsn1Ext->extnId, dwFlags, &pGetExt->pszObjId, &pbExtra, &lRemainExtra); if (lRemainExtra >= 0) { pGetExt->fCritical = FALSE; if (pAsn1Ext->bit_mask & critical_present) pGetExt->fCritical = (BOOLEAN) pAsn1Ext->critical; }
Asn1X509GetOctetString(&pAsn1Ext->extnValue, dwFlags, &pGetExt->Value, &pbExtra, &lRemainExtra); }
*plRemainExtra = lRemainExtra; *ppbExtra = pbExtra; }
//+-------------------------------------------------------------------------
// Set/Free/Get CRYPT_ATTRIBUTE
//--------------------------------------------------------------------------
BOOL WINAPI Asn1X509SetAttribute( IN PCRYPT_ATTRIBUTE pInfo, OUT Attribute *pAsn1 ) { memset(pAsn1, 0, sizeof(*pAsn1)); if (!Asn1X509SetObjId(pInfo->pszObjId, &pAsn1->type)) return FALSE;
return Asn1X509SetSeqOfAny( pInfo->cValue, pInfo->rgValue, &pAsn1->values.count, &pAsn1->values.value); }
void Asn1X509FreeAttribute( IN OUT Attribute *pAsn1 ) { Asn1X509FreeSeqOfAny(pAsn1->values.value); }
void Asn1X509GetAttribute( IN Attribute *pAsn1, IN DWORD dwFlags, OUT PCRYPT_ATTRIBUTE pInfo, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra ) { Asn1X509GetObjId(&pAsn1->type, dwFlags, &pInfo->pszObjId, ppbExtra, plRemainExtra); Asn1X509GetSeqOfAny(pAsn1->values.count, pAsn1->values.value, dwFlags, &pInfo->cValue, &pInfo->rgValue, ppbExtra, plRemainExtra); }
//+-------------------------------------------------------------------------
// Set/Free/Get Attributes
//--------------------------------------------------------------------------
BOOL Asn1X509SetAttributes( IN DWORD cAttribute, IN PCRYPT_ATTRIBUTE pAttribute, OUT Attributes *pAsn1 ) { Attribute *pAsn1Attr;
pAsn1->value = NULL; pAsn1->count = 0; if (cAttribute == 0) return TRUE;
pAsn1Attr = (Attribute *) PkiZeroAlloc(cAttribute * sizeof(Attribute)); if (pAsn1Attr == NULL) return FALSE; pAsn1->value = pAsn1Attr; pAsn1->count = cAttribute;
for ( ; cAttribute > 0; cAttribute--, pAttribute++, pAsn1Attr++) { if (!Asn1X509SetAttribute(pAttribute, pAsn1Attr)) return FALSE; } return TRUE; }
void Asn1X509FreeAttributes( IN Attributes *pAsn1 ) { if (pAsn1->value) { DWORD cAttr = pAsn1->count; Attribute *pAsn1Attr = pAsn1->value;
for ( ; cAttr > 0; cAttr--, pAsn1Attr++) Asn1X509FreeAttribute(pAsn1Attr);
PkiFree(pAsn1->value); pAsn1->value = NULL; } pAsn1->count = 0; }
void Asn1X509GetAttributes( IN Attributes *pAsn1, IN DWORD dwFlags, OUT DWORD *pcAttribute, OUT PCRYPT_ATTRIBUTE *ppAttribute, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra ) { LONG lRemainExtra = *plRemainExtra; BYTE *pbExtra = *ppbExtra; LONG lAlignExtra;
DWORD cAttr; Attribute *pAsn1Attr; PCRYPT_ATTRIBUTE pGetAttr;
cAttr = pAsn1->count; lAlignExtra = INFO_LEN_ALIGN(cAttr * sizeof(CRYPT_ATTRIBUTE)); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { *pcAttribute = cAttr; pGetAttr = (PCRYPT_ATTRIBUTE) pbExtra; *ppAttribute = pGetAttr; pbExtra += lAlignExtra; } else pGetAttr = NULL;
pAsn1Attr = pAsn1->value; for ( ; cAttr > 0; cAttr--, pAsn1Attr++, pGetAttr++) { Asn1X509GetAttribute(pAsn1Attr, dwFlags, pGetAttr, &pbExtra, &lRemainExtra); }
*plRemainExtra = lRemainExtra; *ppbExtra = pbExtra; }
//+-------------------------------------------------------------------------
// Set/Free/Get CMC Tagged Attributes
//--------------------------------------------------------------------------
BOOL Asn1CmcSetTaggedAttributes( IN DWORD cTaggedAttr, IN PCMC_TAGGED_ATTRIBUTE pTaggedAttr, OUT ControlSequence *pAsn1 ) { TaggedAttribute *pAsn1Attr;
pAsn1->value = NULL; pAsn1->count = 0; if (cTaggedAttr == 0) return TRUE;
pAsn1Attr = (TaggedAttribute *) PkiZeroAlloc( cTaggedAttr * sizeof(TaggedAttribute)); if (pAsn1Attr == NULL) return FALSE; pAsn1->value = pAsn1Attr; pAsn1->count = cTaggedAttr;
for ( ; cTaggedAttr > 0; cTaggedAttr--, pTaggedAttr++, pAsn1Attr++) { pAsn1Attr->bodyPartID = pTaggedAttr->dwBodyPartID; if (!Asn1X509SetObjId(pTaggedAttr->Attribute.pszObjId, &pAsn1Attr->type)) return FALSE;
if (!Asn1X509SetSeqOfAny( pTaggedAttr->Attribute.cValue, pTaggedAttr->Attribute.rgValue, &pAsn1Attr->values.count, &pAsn1Attr->values.value)) return FALSE; } return TRUE; }
void Asn1CmcFreeTaggedAttributes( IN OUT ControlSequence *pAsn1 ) { if (pAsn1->value) { TaggedAttribute *pAsn1Attr = pAsn1->value; DWORD cTaggedAttr = pAsn1->count;
for ( ; cTaggedAttr > 0; cTaggedAttr--, pAsn1Attr++) { Asn1X509FreeSeqOfAny(pAsn1Attr->values.value); } PkiFree(pAsn1->value); pAsn1->value = NULL; } pAsn1->count = 0; }
void Asn1CmcGetTaggedAttributes( IN ControlSequence *pAsn1, IN DWORD dwFlags, OUT DWORD *pcTaggedAttr, OUT PCMC_TAGGED_ATTRIBUTE *ppTaggedAttr, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra ) { LONG lRemainExtra = *plRemainExtra; BYTE *pbExtra = *ppbExtra; LONG lAlignExtra;
DWORD cTaggedAttr; TaggedAttribute *pAsn1Attr; PCMC_TAGGED_ATTRIBUTE pTaggedAttr;
cTaggedAttr = pAsn1->count; lAlignExtra = INFO_LEN_ALIGN(cTaggedAttr * sizeof(CMC_TAGGED_ATTRIBUTE)); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { *pcTaggedAttr = cTaggedAttr; pTaggedAttr = (PCMC_TAGGED_ATTRIBUTE) pbExtra; *ppTaggedAttr = pTaggedAttr; pbExtra += lAlignExtra; } else pTaggedAttr = NULL;
pAsn1Attr = pAsn1->value; for ( ; cTaggedAttr > 0; cTaggedAttr--, pAsn1Attr++, pTaggedAttr++) { if (lRemainExtra >= 0) { pTaggedAttr->dwBodyPartID = pAsn1Attr->bodyPartID; } Asn1X509GetObjId(&pAsn1Attr->type, dwFlags, &pTaggedAttr->Attribute.pszObjId, &pbExtra, &lRemainExtra); Asn1X509GetSeqOfAny( pAsn1Attr->values.count, pAsn1Attr->values.value, dwFlags, &pTaggedAttr->Attribute.cValue, &pTaggedAttr->Attribute.rgValue, &pbExtra, &lRemainExtra); }
*plRemainExtra = lRemainExtra; *ppbExtra = pbExtra; }
//+-------------------------------------------------------------------------
// Set/Free/Get CMC Tagged Requests
//--------------------------------------------------------------------------
BOOL Asn1CmcSetTaggedRequests( IN DWORD cTaggedReq, IN PCMC_TAGGED_REQUEST pTaggedReq, OUT ReqSequence *pAsn1 ) { TaggedRequest *pAsn1Req;
pAsn1->value = NULL; pAsn1->count = 0; if (cTaggedReq == 0) return TRUE;
pAsn1Req = (TaggedRequest *) PkiZeroAlloc( cTaggedReq * sizeof(TaggedRequest)); if (pAsn1Req == NULL) return FALSE; pAsn1->value = pAsn1Req; pAsn1->count = cTaggedReq;
for ( ; cTaggedReq > 0; cTaggedReq--, pTaggedReq++, pAsn1Req++) { PCMC_TAGGED_CERT_REQUEST pTaggedCertReq; TaggedCertificationRequest *ptcr;
if (CMC_TAGGED_CERT_REQUEST_CHOICE != pTaggedReq->dwTaggedRequestChoice) { SetLastError((DWORD) E_INVALIDARG); return FALSE; }
pAsn1Req->choice = tcr_chosen; ptcr = &pAsn1Req->u.tcr; pTaggedCertReq = pTaggedReq->pTaggedCertRequest;
ptcr->bodyPartID = pTaggedCertReq->dwBodyPartID; Asn1X509SetAny(&pTaggedCertReq->SignedCertRequest, &ptcr->certificationRequest); } return TRUE; }
void Asn1CmcFreeTaggedRequests( IN OUT ReqSequence *pAsn1 ) { if (pAsn1->value) { PkiFree(pAsn1->value); pAsn1->value = NULL; } pAsn1->count = 0; }
BOOL Asn1CmcGetTaggedRequests( IN ReqSequence *pAsn1, IN DWORD dwFlags, OUT DWORD *pcTaggedReq, OUT PCMC_TAGGED_REQUEST *ppTaggedReq, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra ) { BOOL fResult; LONG lRemainExtra = *plRemainExtra; BYTE *pbExtra = *ppbExtra; LONG lAlignExtra;
DWORD cTaggedReq; TaggedRequest *pAsn1Req; PCMC_TAGGED_REQUEST pTaggedReq;
cTaggedReq = pAsn1->count; lAlignExtra = INFO_LEN_ALIGN(cTaggedReq * sizeof(CMC_TAGGED_REQUEST)); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { *pcTaggedReq = cTaggedReq; pTaggedReq = (PCMC_TAGGED_REQUEST) pbExtra; *ppTaggedReq = pTaggedReq; pbExtra += lAlignExtra; } else pTaggedReq = NULL;
pAsn1Req = pAsn1->value; for ( ; cTaggedReq > 0; cTaggedReq--, pAsn1Req++, pTaggedReq++) { PCMC_TAGGED_CERT_REQUEST pTaggedCertReq; TaggedCertificationRequest *ptcr;
if (tcr_chosen != pAsn1Req->choice) { SetLastError((DWORD) CRYPT_E_BAD_ENCODE); goto ErrorReturn; }
ptcr = &pAsn1Req->u.tcr;
lAlignExtra = INFO_LEN_ALIGN(sizeof(CMC_TAGGED_CERT_REQUEST)); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { pTaggedReq->dwTaggedRequestChoice = CMC_TAGGED_CERT_REQUEST_CHOICE;
pTaggedCertReq = (PCMC_TAGGED_CERT_REQUEST) pbExtra; pbExtra += lAlignExtra;
pTaggedReq->pTaggedCertRequest = pTaggedCertReq; pTaggedCertReq->dwBodyPartID = ptcr->bodyPartID; } else pTaggedCertReq = NULL;
Asn1X509GetAny(&ptcr->certificationRequest, dwFlags, &pTaggedCertReq->SignedCertRequest, &pbExtra, &lRemainExtra); }
*plRemainExtra = lRemainExtra; *ppbExtra = pbExtra;
fResult = TRUE; CommonReturn: return fResult;
ErrorReturn: fResult = FALSE; goto CommonReturn; }
//+-------------------------------------------------------------------------
// Set/Free/Get CMC Tagged ContentInfo
//--------------------------------------------------------------------------
BOOL Asn1CmcSetTaggedContentInfos( IN DWORD cTaggedCI, IN PCMC_TAGGED_CONTENT_INFO pTaggedCI, OUT CmsSequence *pAsn1 ) { TaggedContentInfo *pAsn1CI;
pAsn1->value = NULL; pAsn1->count = 0; if (cTaggedCI == 0) return TRUE;
pAsn1CI = (TaggedContentInfo *) PkiZeroAlloc( cTaggedCI * sizeof(TaggedContentInfo)); if (pAsn1CI == NULL) return FALSE; pAsn1->value = pAsn1CI; pAsn1->count = cTaggedCI;
for ( ; cTaggedCI > 0; cTaggedCI--, pTaggedCI++, pAsn1CI++) { pAsn1CI->bodyPartID = pTaggedCI->dwBodyPartID; Asn1X509SetAny(&pTaggedCI->EncodedContentInfo, &pAsn1CI->contentInfo); }
return TRUE; }
void Asn1CmcFreeTaggedContentInfos( IN OUT CmsSequence *pAsn1 ) { if (pAsn1->value) { PkiFree(pAsn1->value); pAsn1->value = NULL; } pAsn1->count = 0; }
void Asn1CmcGetTaggedContentInfos( IN CmsSequence *pAsn1, IN DWORD dwFlags, OUT DWORD *pcTaggedCI, OUT PCMC_TAGGED_CONTENT_INFO *ppTaggedCI, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra ) { LONG lRemainExtra = *plRemainExtra; BYTE *pbExtra = *ppbExtra; LONG lAlignExtra;
DWORD cTaggedCI; TaggedContentInfo *pAsn1CI; PCMC_TAGGED_CONTENT_INFO pTaggedCI;
cTaggedCI = pAsn1->count; lAlignExtra = INFO_LEN_ALIGN(cTaggedCI * sizeof(CMC_TAGGED_CONTENT_INFO)); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { *pcTaggedCI = cTaggedCI; pTaggedCI = (PCMC_TAGGED_CONTENT_INFO) pbExtra; *ppTaggedCI = pTaggedCI; pbExtra += lAlignExtra; } else pTaggedCI = NULL;
pAsn1CI = pAsn1->value; for ( ; cTaggedCI > 0; cTaggedCI--, pAsn1CI++, pTaggedCI++) { if (lRemainExtra >= 0) { pTaggedCI->dwBodyPartID = pAsn1CI->bodyPartID; }
Asn1X509GetAny(&pAsn1CI->contentInfo, dwFlags, &pTaggedCI->EncodedContentInfo, &pbExtra, &lRemainExtra); }
*plRemainExtra = lRemainExtra; *ppbExtra = pbExtra; }
//+-------------------------------------------------------------------------
// Set/Free/Get CMC Tagged OtherMsg
//--------------------------------------------------------------------------
BOOL Asn1CmcSetTaggedOtherMsgs( IN DWORD cTaggedOM, IN PCMC_TAGGED_OTHER_MSG pTaggedOM, OUT OtherMsgSequence *pAsn1 ) { TaggedOtherMsg *pAsn1OM;
pAsn1->value = NULL; pAsn1->count = 0; if (cTaggedOM == 0) return TRUE;
pAsn1OM = (TaggedOtherMsg *) PkiZeroAlloc( cTaggedOM * sizeof(TaggedOtherMsg)); if (pAsn1OM == NULL) return FALSE; pAsn1->value = pAsn1OM; pAsn1->count = cTaggedOM;
for ( ; cTaggedOM > 0; cTaggedOM--, pTaggedOM++, pAsn1OM++) { pAsn1OM->bodyPartID = pTaggedOM->dwBodyPartID;
if (!Asn1X509SetObjId(pTaggedOM->pszObjId, &pAsn1OM->otherMsgType)) return FALSE;
Asn1X509SetAny(&pTaggedOM->Value, &pAsn1OM->otherMsgValue); }
return TRUE; }
void Asn1CmcFreeTaggedOtherMsgs( IN OUT OtherMsgSequence *pAsn1 ) { if (pAsn1->value) { PkiFree(pAsn1->value); pAsn1->value = NULL; } pAsn1->count = 0; }
void Asn1CmcGetTaggedOtherMsgs( IN OtherMsgSequence *pAsn1, IN DWORD dwFlags, OUT DWORD *pcTaggedOM, OUT PCMC_TAGGED_OTHER_MSG *ppTaggedOM, IN OUT BYTE **ppbExtra, IN OUT LONG *plRemainExtra ) { LONG lRemainExtra = *plRemainExtra; BYTE *pbExtra = *ppbExtra; LONG lAlignExtra;
DWORD cTaggedOM; TaggedOtherMsg *pAsn1OM; PCMC_TAGGED_OTHER_MSG pTaggedOM;
cTaggedOM = pAsn1->count; lAlignExtra = INFO_LEN_ALIGN(cTaggedOM * sizeof(CMC_TAGGED_OTHER_MSG)); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { *pcTaggedOM = cTaggedOM; pTaggedOM = (PCMC_TAGGED_OTHER_MSG) pbExtra; *ppTaggedOM = pTaggedOM; pbExtra += lAlignExtra; } else pTaggedOM = NULL;
pAsn1OM = pAsn1->value; for ( ; cTaggedOM > 0; cTaggedOM--, pAsn1OM++, pTaggedOM++) { if (lRemainExtra >= 0) { pTaggedOM->dwBodyPartID = pAsn1OM->bodyPartID; }
Asn1X509GetObjId(&pAsn1OM->otherMsgType, dwFlags, &pTaggedOM->pszObjId, &pbExtra, &lRemainExtra);
Asn1X509GetAny(&pAsn1OM->otherMsgValue, dwFlags, &pTaggedOM->Value, &pbExtra, &lRemainExtra); }
*plRemainExtra = lRemainExtra; *ppbExtra = pbExtra; }
//+-------------------------------------------------------------------------
// CMC Data Encode (ASN1)
//--------------------------------------------------------------------------
BOOL WINAPI Asn1CmcDataEncodeEx( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN PCMC_DATA_INFO pInfo, IN DWORD dwFlags, IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara, OUT OPTIONAL void *pvEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; CmcData Asn1Info;
memset(&Asn1Info, 0, sizeof(Asn1Info)); if (!Asn1CmcSetTaggedAttributes(pInfo->cTaggedAttribute, pInfo->rgTaggedAttribute, &Asn1Info.controlSequence)) goto ErrorReturn; if (!Asn1CmcSetTaggedRequests(pInfo->cTaggedRequest, pInfo->rgTaggedRequest, &Asn1Info.reqSequence)) goto ErrorReturn; if (!Asn1CmcSetTaggedContentInfos(pInfo->cTaggedContentInfo, pInfo->rgTaggedContentInfo, &Asn1Info.cmsSequence)) goto ErrorReturn; if (!Asn1CmcSetTaggedOtherMsgs(pInfo->cTaggedOtherMsg, pInfo->rgTaggedOtherMsg, &Asn1Info.otherMsgSequence)) goto ErrorReturn;
fResult = Asn1InfoEncodeEx( CmcData_PDU, &Asn1Info, dwFlags, pEncodePara, pvEncoded, pcbEncoded );
CommonReturn: Asn1CmcFreeTaggedAttributes(&Asn1Info.controlSequence); Asn1CmcFreeTaggedRequests(&Asn1Info.reqSequence); Asn1CmcFreeTaggedContentInfos(&Asn1Info.cmsSequence); Asn1CmcFreeTaggedOtherMsgs(&Asn1Info.otherMsgSequence); return fResult;
ErrorReturn: if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) *((void **) pvEncoded) = NULL; *pcbEncoded = 0; fResult = FALSE; goto CommonReturn; }
//+-------------------------------------------------------------------------
// CMC Data Decode (ASN1)
//--------------------------------------------------------------------------
BOOL WINAPI Asn1CmcDataDecodeExCallback( IN void *pvAsn1Info, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA /*pDecodePara*/, OUT OPTIONAL void *pvStructInfo, IN OUT LONG *plRemainExtra ) { BOOL fResult; CmcData *pAsn1 = (CmcData *) pvAsn1Info; PCMC_DATA_INFO pInfo = (PCMC_DATA_INFO) pvStructInfo; LONG lRemainExtra = *plRemainExtra; BYTE *pbExtra;
lRemainExtra -= sizeof(CMC_DATA_INFO); if (lRemainExtra < 0) { pbExtra = NULL; } else { memset(pInfo, 0, sizeof(CMC_DATA_INFO)); pbExtra = (BYTE *) pInfo + sizeof(CMC_DATA_INFO); }
Asn1CmcGetTaggedAttributes(&pAsn1->controlSequence, dwFlags, &pInfo->cTaggedAttribute, &pInfo->rgTaggedAttribute, &pbExtra, &lRemainExtra );
if (!Asn1CmcGetTaggedRequests(&pAsn1->reqSequence, dwFlags, &pInfo->cTaggedRequest, &pInfo->rgTaggedRequest, &pbExtra, &lRemainExtra )) goto ErrorReturn;
Asn1CmcGetTaggedContentInfos(&pAsn1->cmsSequence, dwFlags, &pInfo->cTaggedContentInfo, &pInfo->rgTaggedContentInfo, &pbExtra, &lRemainExtra );
Asn1CmcGetTaggedOtherMsgs(&pAsn1->otherMsgSequence, dwFlags, &pInfo->cTaggedOtherMsg, &pInfo->rgTaggedOtherMsg, &pbExtra, &lRemainExtra );
fResult = TRUE; CommonReturn: *plRemainExtra = lRemainExtra; return fResult;
ErrorReturn: fResult = FALSE; goto CommonReturn; }
BOOL WINAPI Asn1CmcDataDecodeEx( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara, OUT OPTIONAL void *pvStructInfo, IN OUT DWORD *pcbStructInfo ) { return Asn1InfoDecodeAndAllocEx( CmcData_PDU, pbEncoded, cbEncoded, dwFlags, pDecodePara, Asn1CmcDataDecodeExCallback, pvStructInfo, pcbStructInfo ); }
//+-------------------------------------------------------------------------
// CMC Response Encode (ASN1)
//--------------------------------------------------------------------------
BOOL WINAPI Asn1CmcResponseEncodeEx( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN PCMC_RESPONSE_INFO pInfo, IN DWORD dwFlags, IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara, OUT OPTIONAL void *pvEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; CmcResponseBody Asn1Info;
memset(&Asn1Info, 0, sizeof(Asn1Info)); if (!Asn1CmcSetTaggedAttributes(pInfo->cTaggedAttribute, pInfo->rgTaggedAttribute, &Asn1Info.controlSequence)) goto ErrorReturn; if (!Asn1CmcSetTaggedContentInfos(pInfo->cTaggedContentInfo, pInfo->rgTaggedContentInfo, &Asn1Info.cmsSequence)) goto ErrorReturn; if (!Asn1CmcSetTaggedOtherMsgs(pInfo->cTaggedOtherMsg, pInfo->rgTaggedOtherMsg, &Asn1Info.otherMsgSequence)) goto ErrorReturn;
fResult = Asn1InfoEncodeEx( CmcResponseBody_PDU, &Asn1Info, dwFlags, pEncodePara, pvEncoded, pcbEncoded ); CommonReturn: Asn1CmcFreeTaggedAttributes(&Asn1Info.controlSequence); Asn1CmcFreeTaggedContentInfos(&Asn1Info.cmsSequence); Asn1CmcFreeTaggedOtherMsgs(&Asn1Info.otherMsgSequence); return fResult;
ErrorReturn: if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) *((void **) pvEncoded) = NULL; *pcbEncoded = 0; fResult = FALSE; goto CommonReturn; }
//+-------------------------------------------------------------------------
// CMC Response Decode (ASN1)
//--------------------------------------------------------------------------
BOOL WINAPI Asn1CmcResponseDecodeExCallback( IN void *pvAsn1Info, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA /*pDecodePara*/, OUT OPTIONAL void *pvStructInfo, IN OUT LONG *plRemainExtra ) { BOOL fResult; CmcResponseBody *pAsn1 = (CmcResponseBody *) pvAsn1Info; PCMC_RESPONSE_INFO pInfo = (PCMC_RESPONSE_INFO) pvStructInfo; LONG lRemainExtra = *plRemainExtra; BYTE *pbExtra;
lRemainExtra -= sizeof(CMC_RESPONSE_INFO); if (lRemainExtra < 0) { pbExtra = NULL; } else { memset(pInfo, 0, sizeof(CMC_RESPONSE_INFO)); pbExtra = (BYTE *) pInfo + sizeof(CMC_RESPONSE_INFO); }
Asn1CmcGetTaggedAttributes(&pAsn1->controlSequence, dwFlags, &pInfo->cTaggedAttribute, &pInfo->rgTaggedAttribute, &pbExtra, &lRemainExtra );
Asn1CmcGetTaggedContentInfos(&pAsn1->cmsSequence, dwFlags, &pInfo->cTaggedContentInfo, &pInfo->rgTaggedContentInfo, &pbExtra, &lRemainExtra );
Asn1CmcGetTaggedOtherMsgs(&pAsn1->otherMsgSequence, dwFlags, &pInfo->cTaggedOtherMsg, &pInfo->rgTaggedOtherMsg, &pbExtra, &lRemainExtra );
fResult = TRUE; *plRemainExtra = lRemainExtra; return fResult; }
BOOL WINAPI Asn1CmcResponseDecodeEx( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara, OUT OPTIONAL void *pvStructInfo, IN OUT DWORD *pcbStructInfo ) { return Asn1InfoDecodeAndAllocEx( CmcResponseBody_PDU, pbEncoded, cbEncoded, dwFlags, pDecodePara, Asn1CmcResponseDecodeExCallback, pvStructInfo, pcbStructInfo ); }
//+-------------------------------------------------------------------------
// CMC Status Encode (ASN1)
//--------------------------------------------------------------------------
BOOL WINAPI Asn1CmcStatusEncodeEx( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN PCMC_STATUS_INFO pInfo, IN DWORD dwFlags, IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara, OUT OPTIONAL void *pvEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; CmcStatusInfo Asn1Info;
memset(&Asn1Info, 0, sizeof(Asn1Info)); Asn1Info.cmcStatus = pInfo->dwStatus; if (pInfo->cBodyList) { Asn1Info.bodyList.count = pInfo->cBodyList; Asn1Info.bodyList.value = pInfo->rgdwBodyList; }
if (pInfo->pwszStatusString && L'\0' != *pInfo->pwszStatusString) { Asn1Info.bit_mask |= statusString_present; Asn1Info.statusString.length = (DWORD)wcslen(pInfo->pwszStatusString); Asn1Info.statusString.value = pInfo->pwszStatusString; }
if (CMC_OTHER_INFO_NO_CHOICE != pInfo->dwOtherInfoChoice) { Asn1Info.bit_mask |= otherInfo_present;
switch (pInfo->dwOtherInfoChoice) { case CMC_OTHER_INFO_FAIL_CHOICE: Asn1Info.otherInfo.choice = failInfo_chosen; Asn1Info.otherInfo.u.failInfo = pInfo->dwFailInfo; break; case CMC_OTHER_INFO_PEND_CHOICE: Asn1Info.otherInfo.choice = pendInfo_chosen; Asn1X509SetOctetString(&pInfo->pPendInfo->PendToken, &Asn1Info.otherInfo.u.pendInfo.pendToken); if (!PkiAsn1ToGeneralizedTime( &pInfo->pPendInfo->PendTime, &Asn1Info.otherInfo.u.pendInfo.pendTime)) goto GeneralizedTimeError; break; default: goto InvalidOtherInfoChoiceError; } }
fResult = Asn1InfoEncodeEx( CmcStatusInfo_PDU, &Asn1Info, dwFlags, pEncodePara, pvEncoded, pcbEncoded );
CommonReturn: return fResult;
ErrorReturn: if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) *((void **) pvEncoded) = NULL; *pcbEncoded = 0; fResult = FALSE; goto CommonReturn;
SET_ERROR(InvalidOtherInfoChoiceError, E_INVALIDARG) SET_ERROR(GeneralizedTimeError, CRYPT_E_BAD_ENCODE) }
//+-------------------------------------------------------------------------
// CMC Status Decode (ASN1)
//--------------------------------------------------------------------------
BOOL WINAPI Asn1CmcStatusDecodeExCallback( IN void *pvAsn1Info, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA /*pDecodePara*/, OUT OPTIONAL void *pvStructInfo, IN OUT LONG *plRemainExtra ) { BOOL fResult; CmcStatusInfo *pAsn1 = (CmcStatusInfo *) pvAsn1Info; PCMC_STATUS_INFO pInfo = (PCMC_STATUS_INFO) pvStructInfo; LONG lRemainExtra = *plRemainExtra; LONG lAlignExtra; BYTE *pbExtra;
lRemainExtra -= sizeof(CMC_STATUS_INFO); if (lRemainExtra < 0) { pbExtra = NULL; } else { memset(pInfo, 0, sizeof(CMC_STATUS_INFO)); pbExtra = (BYTE *) pInfo + sizeof(CMC_STATUS_INFO);
pInfo->dwStatus = pAsn1->cmcStatus; }
if (pAsn1->bodyList.count > 0) { ASN1uint32_t count = pAsn1->bodyList.count;
lAlignExtra = INFO_LEN_ALIGN(count * sizeof(DWORD)); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { BodyPartID *value; DWORD *pdwBodyList;
value = pAsn1->bodyList.value; pdwBodyList = (DWORD *) pbExtra; pbExtra += lAlignExtra;
pInfo->cBodyList = count; pInfo->rgdwBodyList = pdwBodyList;
for ( ; count > 0; count--, value++, pdwBodyList++) *pdwBodyList = *value; } }
if (pAsn1->bit_mask & statusString_present) { ASN1uint32_t length = pAsn1->statusString.length;
lAlignExtra = INFO_LEN_ALIGN((length + 1) * sizeof(WCHAR)); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { memcpy(pbExtra, pAsn1->statusString.value, length * sizeof(WCHAR)); memset(pbExtra + (length * sizeof(WCHAR)), 0, sizeof(WCHAR));
pInfo->pwszStatusString = (LPWSTR) pbExtra; pbExtra += lAlignExtra; } }
if (pAsn1->bit_mask & otherInfo_present) { switch (pAsn1->otherInfo.choice) { case failInfo_chosen: if (lRemainExtra >= 0) { pInfo->dwOtherInfoChoice = CMC_OTHER_INFO_FAIL_CHOICE; pInfo->dwFailInfo = pAsn1->otherInfo.u.failInfo; } break; case pendInfo_chosen: { PCMC_PEND_INFO pPendInfo;
lAlignExtra = INFO_LEN_ALIGN(sizeof(CMC_PEND_INFO)); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { pInfo->dwOtherInfoChoice = CMC_OTHER_INFO_PEND_CHOICE; pPendInfo = (PCMC_PEND_INFO) pbExtra; pInfo->pPendInfo = pPendInfo; pbExtra += lAlignExtra;
if (!PkiAsn1FromGeneralizedTime( &pAsn1->otherInfo.u.pendInfo.pendTime, &pPendInfo->PendTime)) goto GeneralizedTimeDecodeError; } else pPendInfo = NULL;
Asn1X509GetOctetString( &pAsn1->otherInfo.u.pendInfo.pendToken, dwFlags, &pPendInfo->PendToken, &pbExtra, &lRemainExtra); } break; default: goto InvalidOtherInfoChoiceError; } }
fResult = TRUE; CommonReturn: *plRemainExtra = lRemainExtra; return fResult; ErrorReturn: fResult = FALSE; goto CommonReturn; SET_ERROR(InvalidOtherInfoChoiceError, CRYPT_E_BAD_ENCODE) SET_ERROR(GeneralizedTimeDecodeError, CRYPT_E_BAD_ENCODE) }
BOOL WINAPI Asn1CmcStatusDecodeEx( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara, OUT OPTIONAL void *pvStructInfo, IN OUT DWORD *pcbStructInfo ) { return Asn1InfoDecodeAndAllocEx( CmcStatusInfo_PDU, pbEncoded, cbEncoded, dwFlags, pDecodePara, Asn1CmcStatusDecodeExCallback, pvStructInfo, pcbStructInfo ); }
//+-------------------------------------------------------------------------
// CMC Add Extensions Encode (ASN1)
//--------------------------------------------------------------------------
BOOL WINAPI Asn1CmcAddExtensionsEncodeEx( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN PCMC_ADD_EXTENSIONS_INFO pInfo, IN DWORD dwFlags, IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara, OUT OPTIONAL void *pvEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; CmcAddExtensions Asn1Info;
memset(&Asn1Info, 0, sizeof(Asn1Info)); Asn1Info.pkiDataReference = pInfo->dwCmcDataReference; if (pInfo->cCertReference) { Asn1Info.certReferences.count = pInfo->cCertReference; Asn1Info.certReferences.value = pInfo->rgdwCertReference; }
if (!Asn1X509SetExtensions(pInfo->cExtension, pInfo->rgExtension, &Asn1Info.extensions)) goto ErrorReturn;
fResult = Asn1InfoEncodeEx( CmcAddExtensions_PDU, &Asn1Info, dwFlags, pEncodePara, pvEncoded, pcbEncoded );
CommonReturn: Asn1X509FreeExtensions(&Asn1Info.extensions); return fResult;
ErrorReturn: if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) *((void **) pvEncoded) = NULL; *pcbEncoded = 0; fResult = FALSE; goto CommonReturn; }
//+-------------------------------------------------------------------------
// CMC Add Extensions Decode (ASN1)
//--------------------------------------------------------------------------
BOOL WINAPI Asn1CmcAddExtensionsDecodeExCallback( IN void *pvAsn1Info, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA /*pDecodePara*/, OUT OPTIONAL void *pvStructInfo, IN OUT LONG *plRemainExtra ) { BOOL fResult; CmcAddExtensions *pAsn1 = (CmcAddExtensions *) pvAsn1Info; PCMC_ADD_EXTENSIONS_INFO pInfo = (PCMC_ADD_EXTENSIONS_INFO) pvStructInfo; LONG lRemainExtra = *plRemainExtra; LONG lAlignExtra; BYTE *pbExtra;
lRemainExtra -= sizeof(CMC_ADD_EXTENSIONS_INFO); if (lRemainExtra < 0) { pbExtra = NULL; } else { memset(pInfo, 0, sizeof(CMC_ADD_EXTENSIONS_INFO)); pbExtra = (BYTE *) pInfo + sizeof(CMC_ADD_EXTENSIONS_INFO);
pInfo->dwCmcDataReference = pAsn1->pkiDataReference; }
if (pAsn1->certReferences.count > 0) { ASN1uint32_t count = pAsn1->certReferences.count;
lAlignExtra = INFO_LEN_ALIGN(count * sizeof(DWORD)); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { BodyPartID *value; DWORD *pdwCertReference;
value = pAsn1->certReferences.value; pdwCertReference = (DWORD *) pbExtra; pbExtra += lAlignExtra;
pInfo->cCertReference = count; pInfo->rgdwCertReference = pdwCertReference;
for ( ; count > 0; count--, value++, pdwCertReference++) *pdwCertReference = *value; } }
Asn1X509GetExtensions(&pAsn1->extensions, dwFlags, &pInfo->cExtension, &pInfo->rgExtension, &pbExtra, &lRemainExtra);
fResult = TRUE; *plRemainExtra = lRemainExtra; return fResult; }
BOOL WINAPI Asn1CmcAddExtensionsDecodeEx( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara, OUT OPTIONAL void *pvStructInfo, IN OUT DWORD *pcbStructInfo ) { return Asn1InfoDecodeAndAllocEx( CmcAddExtensions_PDU, pbEncoded, cbEncoded, dwFlags, pDecodePara, Asn1CmcAddExtensionsDecodeExCallback, pvStructInfo, pcbStructInfo ); }
//+-------------------------------------------------------------------------
// CMC Add Attributes Encode (ASN1)
//--------------------------------------------------------------------------
BOOL WINAPI Asn1CmcAddAttributesEncodeEx( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN PCMC_ADD_ATTRIBUTES_INFO pInfo, IN DWORD dwFlags, IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara, OUT OPTIONAL void *pvEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; CmcAddAttributes Asn1Info;
memset(&Asn1Info, 0, sizeof(Asn1Info)); Asn1Info.pkiDataReference = pInfo->dwCmcDataReference; if (pInfo->cCertReference) { Asn1Info.certReferences.count = pInfo->cCertReference; Asn1Info.certReferences.value = pInfo->rgdwCertReference; }
if (!Asn1X509SetAttributes(pInfo->cAttribute, pInfo->rgAttribute, &Asn1Info.attributes)) goto ErrorReturn;
fResult = Asn1InfoEncodeEx( CmcAddAttributes_PDU, &Asn1Info, dwFlags, pEncodePara, pvEncoded, pcbEncoded );
CommonReturn: Asn1X509FreeAttributes(&Asn1Info.attributes); return fResult;
ErrorReturn: if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) *((void **) pvEncoded) = NULL; *pcbEncoded = 0; fResult = FALSE; goto CommonReturn; }
//+-------------------------------------------------------------------------
// CMC Add Attributes Decode (ASN1)
//--------------------------------------------------------------------------
BOOL WINAPI Asn1CmcAddAttributesDecodeExCallback( IN void *pvAsn1Info, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA /*pDecodePara*/, OUT OPTIONAL void *pvStructInfo, IN OUT LONG *plRemainExtra ) { BOOL fResult; CmcAddAttributes *pAsn1 = (CmcAddAttributes *) pvAsn1Info; PCMC_ADD_ATTRIBUTES_INFO pInfo = (PCMC_ADD_ATTRIBUTES_INFO) pvStructInfo; LONG lRemainExtra = *plRemainExtra; LONG lAlignExtra; BYTE *pbExtra;
lRemainExtra -= sizeof(CMC_ADD_ATTRIBUTES_INFO); if (lRemainExtra < 0) { pbExtra = NULL; } else { memset(pInfo, 0, sizeof(CMC_ADD_ATTRIBUTES_INFO)); pbExtra = (BYTE *) pInfo + sizeof(CMC_ADD_ATTRIBUTES_INFO);
pInfo->dwCmcDataReference = pAsn1->pkiDataReference; }
if (pAsn1->certReferences.count > 0) { ASN1uint32_t count = pAsn1->certReferences.count;
lAlignExtra = INFO_LEN_ALIGN(count * sizeof(DWORD)); lRemainExtra -= lAlignExtra; if (lRemainExtra >= 0) { BodyPartID *value; DWORD *pdwCertReference;
value = pAsn1->certReferences.value; pdwCertReference = (DWORD *) pbExtra; pbExtra += lAlignExtra;
pInfo->cCertReference = count; pInfo->rgdwCertReference = pdwCertReference;
for ( ; count > 0; count--, value++, pdwCertReference++) *pdwCertReference = *value; } }
Asn1X509GetAttributes(&pAsn1->attributes, dwFlags, &pInfo->cAttribute, &pInfo->rgAttribute, &pbExtra, &lRemainExtra);
fResult = TRUE; *plRemainExtra = lRemainExtra; return fResult; }
BOOL WINAPI Asn1CmcAddAttributesDecodeEx( IN DWORD /*dwCertEncodingType*/, IN LPCSTR /*lpszStructType*/, IN const BYTE *pbEncoded, IN DWORD cbEncoded, IN DWORD dwFlags, IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara, OUT OPTIONAL void *pvStructInfo, IN OUT DWORD *pcbStructInfo ) { return Asn1InfoDecodeAndAllocEx( CmcAddAttributes_PDU, pbEncoded, cbEncoded, dwFlags, pDecodePara, Asn1CmcAddAttributesDecodeExCallback, pvStructInfo, pcbStructInfo ); }
|