|
|
//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: astring.cpp
//
// Contents: Cert Server Extension Encoding/Decoding implementation
//
//---------------------------------------------------------------------------
#include "pch.cpp"
#pragma hdrstop
#include <assert.h>
#include "resource.h"
#include "astring.h"
#include "celib.h"
//+--------------------------------------------------------------------------
// CCertEncodeStringArray::~CCertEncodeStringArray -- destructor
//
// free memory associated with this instance
//+--------------------------------------------------------------------------
CCertEncodeStringArray::~CCertEncodeStringArray() { _Cleanup(); }
//+--------------------------------------------------------------------------
// CCertEncodeStringArray::_Cleanup -- release all resources
//
// free memory associated with this instance
//+--------------------------------------------------------------------------
VOID CCertEncodeStringArray::_Cleanup() { LONG i;
if (NULL != m_aValue) { for (i = 0; i < m_cValue; i++) { CERT_NAME_VALUE *pNameValue;
pNameValue = m_aValue[i]; assert(NULL != pNameValue); if (m_fConstructing) { if (NULL != pNameValue->Value.pbData) { LocalFree(pNameValue->Value.pbData); } } else { LocalFree(pNameValue); } } if (m_fConstructing && NULL != m_aValue[0]) { LocalFree(m_aValue[0]); } LocalFree(m_aValue); m_aValue = NULL; } m_cValue = 0; m_cValuesSet = 0; m_fConstructing = FALSE; m_StringType = CERT_RDN_IA5_STRING; }
//+--------------------------------------------------------------------------
// CCertEncodeStringArray::Decode -- Decode StringArray
//
// Returns S_OK on success.
//+--------------------------------------------------------------------------
STDMETHODIMP CCertEncodeStringArray::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_aValue = (CERT_NAME_VALUE **) LocalAlloc( LMEM_FIXED, pSequence->cValue * sizeof(m_aValue[0])); if (NULL == m_aValue) { hr = E_OUTOFMEMORY; ceERRORPRINTLINE("LocalAlloc", hr); goto error; } for (i = 0; i < (LONG) pSequence->cValue; i++) { DWORD cb;
// Decode each ASN blob to a name value (string blob + encoding type):
if (!ceDecodeObject( X509_ASN_ENCODING, X509_UNICODE_ANY_STRING, pSequence->rgValue[i].pbData, pSequence->rgValue[i].cbData, FALSE, (VOID **) &m_aValue[i], &cb)) { hr = ceHLastError(); ceERRORPRINTLINE("ceDecodeObject", hr); goto error; } if (0 == i) { m_StringType = m_aValue[i]->dwValueType; } else { if (m_StringType != (LONG) m_aValue[i]->dwValueType) { ceERRORPRINTLINE("dwValueType mismatch", hr); } } m_cValue++; } assert((LONG) pSequence->cValue == m_cValue);
error: if (NULL != pSequence) { LocalFree(pSequence); } if (S_OK != hr) { _Cleanup(); } return(_SetErrorInfo(hr, L"CCertEncodeStringArray::Decode")); }
//+--------------------------------------------------------------------------
// CCertEncodeStringArray::GetStringType -- Get string type
//
// Returns S_OK on success.
//+--------------------------------------------------------------------------
STDMETHODIMP CCertEncodeStringArray::GetStringType( /* [out, retval] */ LONG __RPC_FAR *pStringType) { HRESULT hr = S_OK;
if (NULL == pStringType) { hr = E_POINTER; ceERRORPRINTLINE("NULL parm", hr); goto error; } if (NULL == m_aValue) { hr = E_INVALIDARG; ceERRORPRINTLINE("bad parameter", hr); goto error; } *pStringType = m_StringType; error: return(_SetErrorInfo(hr, L"CCertEncodeStringArray::GetStringType")); }
//+--------------------------------------------------------------------------
// CCertEncodeStringArray::GetCount -- Get Array count
//
// Returns S_OK on success.
//+--------------------------------------------------------------------------
STDMETHODIMP CCertEncodeStringArray::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"CCertEncodeStringArray::GetCount")); }
//+--------------------------------------------------------------------------
// CCertEncodeStringArray::GetValue -- Fetch the indexed string
//
// Returns S_OK on success.
//+--------------------------------------------------------------------------
STDMETHODIMP CCertEncodeStringArray::GetValue( /* [in] */ LONG Index, /* [out, retval] */ BSTR __RPC_FAR *pstr) { HRESULT hr = S_OK;
if (NULL == pstr) { hr = E_POINTER; ceERRORPRINTLINE("NULL parm", hr); goto error; } ceFreeBstr(pstr); if (NULL == m_aValue || Index >= m_cValue) { hr = E_INVALIDARG; ceERRORPRINTLINE("bad parameter", hr); goto error; } if (NULL == m_aValue[Index]->Value.pbData) { hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); ceERRORPRINTLINE("uninitialized", hr); goto error; } if (!ceConvertWszToBstr( pstr, (WCHAR const *) m_aValue[Index]->Value.pbData, -1)) { hr = E_OUTOFMEMORY; ceERRORPRINTLINE("ceConvertWszToBstr", hr); goto error; } error: return(_SetErrorInfo(hr, L"CCertEncodeStringArray::GetValue")); }
//+--------------------------------------------------------------------------
// CCertEncodeStringArray::Reset -- clear out data
//
// Returns S_OK on success.
//+--------------------------------------------------------------------------
STDMETHODIMP CCertEncodeStringArray::Reset( /* [in] */ LONG Count, /* [in] */ LONG StringType) { HRESULT hr = S_OK; CERT_NAME_VALUE *aNameValue = NULL; LONG i;
_Cleanup(); m_fConstructing = TRUE; if (CENCODEMAX < Count || 0 > Count) { hr = E_INVALIDARG; ceERRORPRINTLINE("bad count parameter", hr); goto error; }
switch (StringType) { case CERT_RDN_ANY_TYPE: //case CERT_RDN_ENCODED_BLOB:
//case CERT_RDN_OCTET_STRING:
case CERT_RDN_NUMERIC_STRING: case CERT_RDN_PRINTABLE_STRING: //case CERT_RDN_TELETEX_STRING: same as CERT_RDN_T61_STRING:
case CERT_RDN_T61_STRING: case CERT_RDN_VIDEOTEX_STRING: case CERT_RDN_IA5_STRING: case CERT_RDN_GRAPHIC_STRING: //case CERT_RDN_VISIBLE_STRING: same as CERT_RDN_ISO646_STRING:
case CERT_RDN_ISO646_STRING: case CERT_RDN_GENERAL_STRING: //case CERT_RDN_UNIVERSAL_STRING: same as CERT_RDN_INT4_STRING:
case CERT_RDN_INT4_STRING: //case CERT_RDN_BMP_STRING: same as case CERT_RDN_UNICODE_STRING:
case CERT_RDN_UNICODE_STRING: break;
default: hr = E_INVALIDARG; ceERRORPRINTLINE("bad parameter", hr); goto error; } m_StringType = StringType;
aNameValue = (CERT_NAME_VALUE *) LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, Count * sizeof(*m_aValue[0])); if (NULL == aNameValue) { hr = E_OUTOFMEMORY; ceERRORPRINTLINE("LocalAlloc", hr); goto error; }
m_aValue = (CERT_NAME_VALUE **) LocalAlloc( LMEM_FIXED, Count * sizeof(m_aValue[0])); if (NULL == m_aValue) { hr = E_OUTOFMEMORY; ceERRORPRINTLINE("LocalAlloc", hr); goto error; }
m_cValue = Count; for (i = 0; i < Count; i++) { m_aValue[i] = &aNameValue[i]; } aNameValue = NULL;
error: if (NULL != aNameValue) { LocalFree(aNameValue); } if (S_OK != hr) { _Cleanup(); } return(_SetErrorInfo(hr, L"CCertEncodeStringArray::Reset")); }
//+--------------------------------------------------------------------------
// CCertEncodeStringArray::SetValue -- Set an array string
//
// Returns S_OK on success.
//+--------------------------------------------------------------------------
STDMETHODIMP CCertEncodeStringArray::SetValue( /* [in] */ LONG Index, /* [in] */ BSTR const str) { HRESULT hr = S_OK; WCHAR *pwsz;
if (NULL == str) { hr = E_POINTER; ceERRORPRINTLINE("NULL parm", hr); goto error; } if (!m_fConstructing || NULL == m_aValue || Index >= m_cValue || m_cValuesSet >= m_cValue || NULL != m_aValue[Index]->Value.pbData) { hr = E_INVALIDARG; ceERRORPRINTLINE("bad parameter", hr); goto error; } pwsz = ceDuplicateString(str); if (NULL == pwsz) { hr = E_OUTOFMEMORY; ceERRORPRINTLINE("ceDuplicateString", hr); goto error; } m_aValue[Index]->dwValueType = m_StringType; m_aValue[Index]->Value.pbData = (BYTE *) pwsz; m_aValue[Index]->Value.cbData = 0; m_cValuesSet++;
error: return(_SetErrorInfo(hr, L"CCertEncodeStringArray::SetValue")); }
//+--------------------------------------------------------------------------
// CCertEncodeStringArray::Encode -- Encode StringArray
//
// Returns S_OK on success.
//+--------------------------------------------------------------------------
STDMETHODIMP CCertEncodeStringArray::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("uninitialized values", 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 name blob into an ASN blob:
if (!ceEncodeObject( X509_ASN_ENCODING, X509_UNICODE_ANY_STRING, 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 the array of 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"CCertEncodeStringArray::Encode")); }
//+--------------------------------------------------------------------------
// CCertEncodeStringArray::_SetErrorInfo -- set error object information
//
// Returns passed HRESULT
//+--------------------------------------------------------------------------
HRESULT CCertEncodeStringArray::_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_CERTENCODESTRINGARRAY, &IID_ICertEncodeStringArray); assert(hr == hrError); } return(hrError); }
|