//+-------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1996 - 1999 // // File: along.cpp // // Contents: Cert Server Extension Encoding/Decoding implementation // //--------------------------------------------------------------------------- #include "pch.cpp" #pragma hdrstop #include #include "resource.h" #include "along.h" #include "celib.h" //+-------------------------------------------------------------------------- // CCertEncodeLongArray::~CCertEncodeLongArray -- destructor // // free memory associated with this instance //+-------------------------------------------------------------------------- CCertEncodeLongArray::~CCertEncodeLongArray() { _Cleanup(); } //+-------------------------------------------------------------------------- // CCertEncodeLongArray::_Cleanup -- release all resources // // free memory associated with this instance //+-------------------------------------------------------------------------- VOID CCertEncodeLongArray::_Cleanup() { if (NULL != m_aValue) { LocalFree(m_aValue); m_aValue = NULL; } m_cValue = 0; m_cValuesSet = 0; m_fConstructing = FALSE; } //+-------------------------------------------------------------------------- // CCertEncodeLongArray::Decode -- Decode LongArray // // Returns S_OK on success. //+-------------------------------------------------------------------------- STDMETHODIMP CCertEncodeLongArray::Decode( /* [in] */ BSTR const strBinary) { HRESULT hr = S_OK; CRYPT_SEQUENCE_OF_ANY *pSequence = NULL; DWORD cbSequence; LONG i; _Cleanup(); if (NULL == strBinary) { hr = E_POINTER; ceERRORPRINTLINE("NULL parm", hr); goto error; } // Decode to an array of ASN blobs: if (!ceDecodeObject( X509_ASN_ENCODING, X509_SEQUENCE_OF_ANY, (BYTE *) strBinary, SysStringByteLen(strBinary), FALSE, (VOID **) &pSequence, &cbSequence)) { hr = ceHLastError(); ceERRORPRINTLINE("ceDecodeObject", hr); goto error; } m_cValue = pSequence->cValue; m_aValue = (LONG *) LocalAlloc(LMEM_FIXED, m_cValue * sizeof(m_aValue[0])); if (NULL == m_aValue) { hr = E_OUTOFMEMORY; ceERRORPRINTLINE("LocalAlloc", hr); goto error; } for (i = 0; i < m_cValue; i++) { DWORD cb; // Decode each ASN blob to an integer: cb = sizeof(m_aValue[i]); if (!CryptDecodeObject( X509_ASN_ENCODING, X509_INTEGER, pSequence->rgValue[i].pbData, pSequence->rgValue[i].cbData, 0, // dwFlags (VOID *) &m_aValue[i], &cb)) { hr = ceHLastError(); ceERRORPRINTLINE("CryptDecodeObject", hr); goto error; } assert(sizeof(m_aValue[i]) == cb); } error: if (NULL != pSequence) { LocalFree(pSequence); } if (S_OK != hr) { _Cleanup(); } return(_SetErrorInfo(hr, L"CCertEncodeLongArray::Decode")); } //+-------------------------------------------------------------------------- // CCertEncodeLongArray::GetCount -- Get Array count // // Returns S_OK on success. //+-------------------------------------------------------------------------- STDMETHODIMP CCertEncodeLongArray::GetCount( /* [out, retval] */ LONG __RPC_FAR *pCount) { HRESULT hr = S_OK; if (NULL == pCount) { hr = E_POINTER; ceERRORPRINTLINE("NULL parm", hr); goto error; } if (NULL == m_aValue) { hr = E_INVALIDARG; ceERRORPRINTLINE("bad parameter", hr); goto error; } *pCount = m_cValue; error: return(_SetErrorInfo(hr, L"CCertEncodeLongArray::GetCount")); } //+-------------------------------------------------------------------------- // CCertEncodeLongArray::GetValue -- Fetch the indexed long // // Returns S_OK on success. //+-------------------------------------------------------------------------- STDMETHODIMP CCertEncodeLongArray::GetValue( /* [in] */ LONG Index, /* [out, retval] */ LONG __RPC_FAR *pValue) { HRESULT hr = S_OK; BYTE *pb; if (NULL == pValue) { hr = E_POINTER; ceERRORPRINTLINE("NULL parm", hr); goto error; } if (NULL == m_aValue || Index >= m_cValue) { hr = E_INVALIDARG; ceERRORPRINTLINE("bad parameter", hr); goto error; } // Bitmap only exists when constrcuting! if (m_fConstructing) { pb = (BYTE *) &m_aValue[m_cValue]; if (!GETBIT(pb, Index)) { hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); ceERRORPRINTLINE("uninitialized", hr); goto error; } } *pValue = m_aValue[Index]; error: return(_SetErrorInfo(hr, L"CCertEncodeLongArray::GetValue")); } //+-------------------------------------------------------------------------- // CCertEncodeLongArray::Reset -- clear out data, and set up to encode new data // // Returns S_OK on success. //+-------------------------------------------------------------------------- STDMETHODIMP CCertEncodeLongArray::Reset( /* [in] */ LONG Count) { HRESULT hr = S_OK; DWORD cbAlloc; _Cleanup(); m_fConstructing = TRUE; if (CENCODEMAX < Count || 0 > Count) { hr = E_INVALIDARG; ceERRORPRINTLINE("bad count parameter", hr); goto error; } cbAlloc = Count * sizeof(m_aValue[0]) + BITSTOBYTES(Count); m_aValue = (LONG *) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, cbAlloc); if (NULL == m_aValue) { hr = E_OUTOFMEMORY; ceERRORPRINTLINE("LocalAlloc", hr); goto error; } m_cValue = Count; error: return(_SetErrorInfo(hr, L"CCertEncodeLongArray::Reset")); } //+-------------------------------------------------------------------------- // CCertEncodeLongArray::SetValue -- Set an array long // // Returns S_OK on success. //+-------------------------------------------------------------------------- STDMETHODIMP CCertEncodeLongArray::SetValue( /* [in] */ LONG Index, /* [in] */ LONG Value) { HRESULT hr = S_OK; BYTE *pb; if (!m_fConstructing || NULL == m_aValue || Index >= m_cValue || m_cValuesSet >= m_cValue) { hr = E_INVALIDARG; ceERRORPRINTLINE("bad parameter", hr); goto error; } pb = (BYTE *) &m_aValue[m_cValue]; if (GETBIT(pb, Index)) { hr = E_INVALIDARG; ceERRORPRINTLINE("already set", hr); goto error; } SETBIT(pb, Index); m_aValue[Index] = Value; m_cValuesSet++; error: return(_SetErrorInfo(hr, L"CCertEncodeLongArray::SetValue")); } //+-------------------------------------------------------------------------- // CCertEncodeLongArray::Encode -- Encode LongArray // // Returns S_OK on success. //+-------------------------------------------------------------------------- STDMETHODIMP CCertEncodeLongArray::Encode( /* [out, retval] */ BSTR __RPC_FAR *pstrBinary) { HRESULT hr = S_OK; LONG i; CRYPT_SEQUENCE_OF_ANY Sequence; BYTE *pbEncoded = NULL; DWORD cbEncoded; Sequence.cValue = 0; Sequence.rgValue = NULL; if (NULL == pstrBinary) { hr = E_POINTER; ceERRORPRINTLINE("NULL parm", hr); goto error; } ceFreeBstr(pstrBinary); if (!m_fConstructing || NULL == m_aValue) { hr = E_INVALIDARG; ceERRORPRINTLINE("bad parameter", hr); goto error; } if (m_cValuesSet != m_cValue) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); ceERRORPRINTLINE("m_cValuesSet", hr); goto error; } Sequence.rgValue = (CRYPT_DER_BLOB *) LocalAlloc( LMEM_FIXED, m_cValue * sizeof(Sequence.rgValue[0])); if (NULL == Sequence.rgValue) { hr = E_OUTOFMEMORY; ceERRORPRINTLINE("LocalAlloc", hr); goto error; } for (i = 0; i < m_cValue; i++) { // Encode each integer into an ASN blob: if (!ceEncodeObject( X509_ASN_ENCODING, X509_INTEGER, &m_aValue[i], 0, FALSE, &Sequence.rgValue[i].pbData, &Sequence.rgValue[i].cbData)) { hr = ceHLastError(); ceERRORPRINTLINE("ceEncodeObject", hr); goto error; } Sequence.cValue++; } assert((LONG) Sequence.cValue == m_cValue); // Encode each integer into an ASN blob: if (!ceEncodeObject( X509_ASN_ENCODING, X509_SEQUENCE_OF_ANY, &Sequence, 0, FALSE, &pbEncoded, &cbEncoded)) { hr = ceHLastError(); ceERRORPRINTLINE("ceEncodeObject", hr); goto error; } if (!ceConvertWszToBstr( pstrBinary, (WCHAR const *) pbEncoded, cbEncoded)) { hr = E_OUTOFMEMORY; ceERRORPRINTLINE("ceConvertWszToBstr", hr); goto error; } error: if (NULL != pbEncoded) { LocalFree(pbEncoded); } if (NULL != Sequence.rgValue) { assert((LONG) Sequence.cValue <= m_cValue); for (i = 0; i < (LONG) Sequence.cValue; i++) { assert(NULL != Sequence.rgValue[i].pbData); LocalFree(Sequence.rgValue[i].pbData); } LocalFree(Sequence.rgValue); } return(_SetErrorInfo(hr, L"CCertEncodeLongArray::Encode")); } //+-------------------------------------------------------------------------- // CCertEncodeLongArray::_SetErrorInfo -- set error object information // // Returns passed HRESULT //+-------------------------------------------------------------------------- HRESULT CCertEncodeLongArray::_SetErrorInfo( IN HRESULT hrError, IN WCHAR const *pwszDescription) { assert(FAILED(hrError) || S_OK == hrError || S_FALSE == hrError); if (FAILED(hrError)) { HRESULT hr; hr = ceDispatchSetErrorInfo( hrError, pwszDescription, wszCLASS_CERTENCODELONGARRAY, &IID_ICertEncodeLongArray); assert(hr == hrError); } return(hrError); }