765 lines
16 KiB
C++
765 lines
16 KiB
C++
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
||
|
//
|
||
|
// File: crldist.cpp
|
||
|
//
|
||
|
// Contents: Cert Server Extension Encoding/Decoding implementation
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
#include "pch.cpp"
|
||
|
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include <assert.h>
|
||
|
#include "resource.h"
|
||
|
#include "altname.h"
|
||
|
#include "celib.h"
|
||
|
|
||
|
#ifndef EAN_NAMEOBJECTID
|
||
|
#define EAN_NAMEOBJECTID ( 0x80000000 )
|
||
|
#endif EAN_NAMEOBJECTID
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::CCertEncodeAltName -- constructor
|
||
|
//
|
||
|
// initialize class
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
CCertEncodeAltName::CCertEncodeAltName()
|
||
|
{
|
||
|
m_aValue = NULL;
|
||
|
m_DecodeInfo = NULL;
|
||
|
m_fConstructing = FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::~CCertEncodeAltName -- destructor
|
||
|
//
|
||
|
// free memory associated with this instance
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
CCertEncodeAltName::~CCertEncodeAltName()
|
||
|
{
|
||
|
_Cleanup();
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::_NameType -- determine name type tag
|
||
|
//
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
CCertEncodeAltName::enumNameType
|
||
|
CCertEncodeAltName::_NameType(
|
||
|
IN DWORD NameChoice)
|
||
|
{
|
||
|
enumNameType Type = enumUnknown;
|
||
|
|
||
|
switch (NameChoice)
|
||
|
{
|
||
|
case CERT_ALT_NAME_RFC822_NAME:
|
||
|
case CERT_ALT_NAME_DNS_NAME:
|
||
|
case CERT_ALT_NAME_URL:
|
||
|
Type = enumUnicode;
|
||
|
break;
|
||
|
|
||
|
case CERT_ALT_NAME_REGISTERED_ID:
|
||
|
Type = enumAnsi;
|
||
|
break;
|
||
|
|
||
|
case CERT_ALT_NAME_DIRECTORY_NAME:
|
||
|
case CERT_ALT_NAME_IP_ADDRESS:
|
||
|
Type = enumBlob;
|
||
|
break;
|
||
|
|
||
|
case CERT_ALT_NAME_OTHER_NAME:
|
||
|
Type = enumOther;
|
||
|
break;
|
||
|
|
||
|
//case CERT_ALT_NAME_X400_ADDRESS:
|
||
|
//case CERT_ALT_NAME_EDI_PARTY_NAME:
|
||
|
}
|
||
|
return(Type);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::_Cleanup -- release all resources
|
||
|
//
|
||
|
// free memory associated with this instance
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
VOID
|
||
|
CCertEncodeAltName::_Cleanup()
|
||
|
{
|
||
|
if (NULL != m_aValue)
|
||
|
{
|
||
|
if (!m_fConstructing)
|
||
|
{
|
||
|
if (NULL != m_DecodeInfo)
|
||
|
{
|
||
|
LocalFree(m_DecodeInfo);
|
||
|
m_DecodeInfo = NULL;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CERT_ALT_NAME_ENTRY *pName;
|
||
|
CERT_ALT_NAME_ENTRY *pNameEnd;
|
||
|
|
||
|
for (pName = m_aValue, pNameEnd = &m_aValue[m_cValue];
|
||
|
pName < pNameEnd;
|
||
|
pName++)
|
||
|
{
|
||
|
BYTE **ppb;
|
||
|
|
||
|
ppb = NULL;
|
||
|
|
||
|
switch (_NameType(pName->dwAltNameChoice))
|
||
|
{
|
||
|
case enumUnicode:
|
||
|
case enumAnsi:
|
||
|
ppb = (BYTE **) &pName->pwszURL;
|
||
|
break;
|
||
|
|
||
|
case enumBlob:
|
||
|
ppb = (BYTE **) &pName->DirectoryName.pbData;
|
||
|
break;
|
||
|
|
||
|
case enumOther:
|
||
|
{
|
||
|
CERT_OTHER_NAME *pOther = pName->pOtherName;
|
||
|
if (NULL != pOther)
|
||
|
{
|
||
|
if (NULL != pOther->pszObjId)
|
||
|
{
|
||
|
LocalFree(pOther->pszObjId);
|
||
|
}
|
||
|
if (NULL != pOther->Value.pbData)
|
||
|
{
|
||
|
LocalFree(pOther->Value.pbData);
|
||
|
}
|
||
|
}
|
||
|
ppb = (BYTE **) &pName->pOtherName;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (NULL != ppb && NULL != *ppb)
|
||
|
{
|
||
|
LocalFree(*ppb);
|
||
|
}
|
||
|
}
|
||
|
LocalFree(m_aValue);
|
||
|
}
|
||
|
m_aValue = NULL;
|
||
|
}
|
||
|
assert(NULL == m_DecodeInfo);
|
||
|
m_fConstructing = FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::_MapName -- map a distribution point
|
||
|
//
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
HRESULT
|
||
|
CCertEncodeAltName::_MapName(
|
||
|
IN BOOL fEncode,
|
||
|
IN LONG NameIndex, // NameIndex | EAN_*
|
||
|
OUT CERT_ALT_NAME_ENTRY **ppName)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
CERT_ALT_NAME_ENTRY *pName;
|
||
|
|
||
|
if (fEncode)
|
||
|
{
|
||
|
pName = m_fConstructing? m_aValue : NULL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pName = m_aValue;
|
||
|
}
|
||
|
|
||
|
if (NULL == pName)
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
ceERRORPRINTLINE("bad parameter", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
NameIndex &= ~EAN_NAMEOBJECTID;
|
||
|
if (m_cValue <= NameIndex)
|
||
|
{
|
||
|
ceERRORPRINTLINE("bad NameIndex parameter", hr);
|
||
|
hr = E_INVALIDARG;
|
||
|
goto error;
|
||
|
}
|
||
|
*ppName = &pName[NameIndex];
|
||
|
|
||
|
error:
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::Decode -- Decode AltName
|
||
|
//
|
||
|
// Returns S_OK on success.
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CCertEncodeAltName::Decode(
|
||
|
/* [in] */ BSTR const strBinary)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
_Cleanup();
|
||
|
|
||
|
if (NULL == strBinary)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
ceERRORPRINTLINE("NULL parm", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
// Decode CERT_ALT_NAME_INFO:
|
||
|
|
||
|
if (!ceDecodeObject(
|
||
|
X509_ASN_ENCODING,
|
||
|
X509_ALTERNATE_NAME,
|
||
|
(BYTE *) strBinary,
|
||
|
SysStringByteLen(strBinary),
|
||
|
FALSE,
|
||
|
(VOID **) &m_DecodeInfo,
|
||
|
&m_DecodeLength))
|
||
|
{
|
||
|
hr = ceHLastError();
|
||
|
ceERRORPRINTLINE("ceDecodeObject", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
m_aValue = m_DecodeInfo->rgAltEntry;
|
||
|
m_cValue = m_DecodeInfo->cAltEntry;
|
||
|
|
||
|
error:
|
||
|
if (S_OK != hr)
|
||
|
{
|
||
|
_Cleanup();
|
||
|
}
|
||
|
return(_SetErrorInfo(hr, L"CCertEncodeAltName::Decode"));
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::GetNameCount -- Get the Distribution Name Count
|
||
|
//
|
||
|
// Returns S_OK on success.
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CCertEncodeAltName::GetNameCount(
|
||
|
/* [out, retval] */ LONG __RPC_FAR *pNameCount)
|
||
|
{
|
||
|
HRESULT hr = E_INVALIDARG;
|
||
|
|
||
|
if (NULL == pNameCount)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
ceERRORPRINTLINE("NULL parm", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
if (NULL == m_aValue)
|
||
|
{
|
||
|
ceERRORPRINTLINE("bad parameter", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
*pNameCount = m_cValue;
|
||
|
hr = S_OK;
|
||
|
|
||
|
error:
|
||
|
return(_SetErrorInfo(hr, L"CCertEncodeAltName::GetNameCount"));
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::GetNameChoice -- Get a Name Choice
|
||
|
//
|
||
|
// Returns S_OK on success.
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CCertEncodeAltName::GetNameChoice(
|
||
|
/* [in] */ LONG NameIndex,
|
||
|
/* [out, retval] */ LONG __RPC_FAR *pNameChoice)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
CERT_ALT_NAME_ENTRY *pName;
|
||
|
|
||
|
if (NULL == pNameChoice)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
ceERRORPRINTLINE("NULL parm", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
hr = _MapName(FALSE, NameIndex, &pName);
|
||
|
if (S_OK != hr)
|
||
|
{
|
||
|
ceERRORPRINTLINE("_MapName", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
if (enumUnknown == _NameType(pName->dwAltNameChoice))
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||
|
ceERRORPRINTLINE("uninitialized", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
*pNameChoice = pName->dwAltNameChoice;
|
||
|
|
||
|
error:
|
||
|
return(_SetErrorInfo(hr, L"CCertEncodeAltName::GetNameChoice"));
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::GetName -- Get a Name
|
||
|
//
|
||
|
// Returns S_OK on success.
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CCertEncodeAltName::GetName(
|
||
|
/* [in] */ LONG NameIndex, // NameIndex | EAN_*
|
||
|
/* [out, retval] */ BSTR __RPC_FAR *pstrName)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
CERT_ALT_NAME_ENTRY *pName;
|
||
|
|
||
|
if (NULL == pstrName)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
ceERRORPRINTLINE("NULL parm", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
ceFreeBstr(pstrName);
|
||
|
hr = _MapName(FALSE, NameIndex, &pName);
|
||
|
if (S_OK != hr)
|
||
|
{
|
||
|
ceERRORPRINTLINE("_MapName", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
switch (_NameType(pName->dwAltNameChoice))
|
||
|
{
|
||
|
case enumUnicode:
|
||
|
if (!ceConvertWszToBstr(pstrName, pName->pwszURL, -1))
|
||
|
{
|
||
|
ceERRORPRINTLINE("no memory", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case enumAnsi:
|
||
|
if (!ceConvertSzToBstr(pstrName, pName->pszRegisteredID, -1))
|
||
|
{
|
||
|
ceERRORPRINTLINE("no memory", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case enumBlob:
|
||
|
if (!ceConvertWszToBstr(
|
||
|
pstrName,
|
||
|
(WCHAR const *) pName->DirectoryName.pbData,
|
||
|
pName->DirectoryName.cbData))
|
||
|
{
|
||
|
ceERRORPRINTLINE("no memory", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case enumOther:
|
||
|
if (EAN_NAMEOBJECTID & NameIndex)
|
||
|
{
|
||
|
if (!ceConvertSzToBstr(
|
||
|
pstrName,
|
||
|
pName->pOtherName->pszObjId,
|
||
|
-1))
|
||
|
{
|
||
|
ceERRORPRINTLINE("no memory", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (!ceConvertWszToBstr(
|
||
|
pstrName,
|
||
|
(WCHAR const *) pName->pOtherName->Value.pbData,
|
||
|
pName->pOtherName->Value.cbData))
|
||
|
{
|
||
|
ceERRORPRINTLINE("no memory", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
assert(enumUnknown == _NameType(pName->dwAltNameChoice));
|
||
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||
|
ceERRORPRINTLINE("uninitialized", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
hr = S_OK;
|
||
|
|
||
|
error:
|
||
|
return(_SetErrorInfo(hr, L"CCertEncodeAltName::GetName"));
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::Reset -- clear out data
|
||
|
//
|
||
|
// Returns S_OK on success.
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CCertEncodeAltName::Reset(
|
||
|
/* [in] */ LONG NameCount)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
CERT_NAME_VALUE *aNameValue = NULL;
|
||
|
|
||
|
_Cleanup();
|
||
|
m_fConstructing = TRUE;
|
||
|
if (CENCODEMAX < NameCount || 0 > NameCount)
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
ceERRORPRINTLINE("bad count parameter", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
m_aValue = (CERT_ALT_NAME_ENTRY *) LocalAlloc(
|
||
|
LMEM_FIXED | LMEM_ZEROINIT,
|
||
|
NameCount * sizeof(m_aValue[0]));
|
||
|
if (NULL == m_aValue)
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
ceERRORPRINTLINE("LocalAlloc", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
m_cValue = NameCount;
|
||
|
|
||
|
error:
|
||
|
if (S_OK != hr)
|
||
|
{
|
||
|
_Cleanup();
|
||
|
}
|
||
|
return(_SetErrorInfo(hr, L"CCertEncodeAltName::Reset"));
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::SetNameEntry -- Set a Name Netry
|
||
|
//
|
||
|
// Returns S_OK on success.
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CCertEncodeAltName::SetNameEntry(
|
||
|
/* [in] */ LONG NameIndex, // NameIndex | EAN_*
|
||
|
/* [in] */ LONG NameChoice,
|
||
|
/* [in] */ BSTR const strName)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
CERT_ALT_NAME_ENTRY *pName;
|
||
|
DATA_BLOB *pBlob = NULL;
|
||
|
|
||
|
if (NULL == strName)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
ceERRORPRINTLINE("NULL parm", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
if (!m_fConstructing)
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
ceERRORPRINTLINE("bad parameter", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
hr = _MapName(TRUE, NameIndex, &pName);
|
||
|
if (S_OK != hr)
|
||
|
{
|
||
|
ceERRORPRINTLINE("_MapName", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
if (enumUnknown != _NameType(pName->dwAltNameChoice))
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
ceERRORPRINTLINE("bad parameter", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
hr = ceVerifyAltNameString(NameChoice, strName);
|
||
|
if (S_OK != hr)
|
||
|
{
|
||
|
ceERRORPRINTLINE("ceVerifyAltNameString", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
switch (_NameType(NameChoice))
|
||
|
{
|
||
|
case enumUnicode:
|
||
|
pName->pwszURL = ceDuplicateString(strName);
|
||
|
if (NULL == pName->pwszURL)
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
ceERRORPRINTLINE("ceDuplicateString", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case enumAnsi:
|
||
|
if (CERT_ALT_NAME_REGISTERED_ID == NameChoice)
|
||
|
{
|
||
|
hr = ceVerifyObjId(strName);
|
||
|
if (S_OK != hr)
|
||
|
{
|
||
|
ceERRORPRINTLINE("ceVerifyObjId", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
}
|
||
|
if (!ceConvertWszToSz(&pName->pszRegisteredID, strName, -1))
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
ceERRORPRINTLINE("ceConvertWszToSz", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case enumBlob:
|
||
|
pBlob = &pName->DirectoryName;
|
||
|
break;
|
||
|
|
||
|
case enumOther:
|
||
|
if (NULL == pName->pOtherName)
|
||
|
{
|
||
|
pName->pOtherName = (CERT_OTHER_NAME *) LocalAlloc(
|
||
|
LMEM_FIXED | LMEM_ZEROINIT,
|
||
|
sizeof(*pName->pOtherName));
|
||
|
if (NULL == pName->pOtherName)
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
_JumpError(hr, error, "LocalAlloc");
|
||
|
}
|
||
|
}
|
||
|
else if (CERT_ALT_NAME_OTHER_NAME != pName->dwAltNameChoice)
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
_JumpError(hr, error, "NameChoice conflict");
|
||
|
}
|
||
|
if (EAN_NAMEOBJECTID & NameIndex)
|
||
|
{
|
||
|
if (NULL != pName->pOtherName->pszObjId)
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
_JumpError(hr, error, "pszObjId already set");
|
||
|
}
|
||
|
if (!ceConvertWszToSz(&pName->pOtherName->pszObjId, strName, -1))
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
_JumpError(hr, error, "ceConvertWszToSz");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pBlob = &pName->pOtherName->Value;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
hr = E_INVALIDARG;
|
||
|
ceERRORPRINTLINE("bad NameChoice parameter", hr);
|
||
|
goto error;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (NULL != pBlob)
|
||
|
{
|
||
|
if (NULL != pBlob->pbData)
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
_JumpError(hr, error, "pbData already set");
|
||
|
}
|
||
|
pBlob->cbData = SysStringByteLen(strName);
|
||
|
pBlob->pbData = (BYTE *) LocalAlloc(LMEM_FIXED, pBlob->cbData);
|
||
|
if (NULL == pBlob->pbData)
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
_JumpError(hr, error, "LocalAlloc");
|
||
|
}
|
||
|
CopyMemory(pBlob->pbData, strName, pBlob->cbData);
|
||
|
}
|
||
|
pName->dwAltNameChoice = NameChoice;
|
||
|
|
||
|
error:
|
||
|
return(_SetErrorInfo(hr, L"CCertEncodeAltName::SetNameEntry"));
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::_VerifyName -- Verify name
|
||
|
//
|
||
|
// Returns S_OK on success.
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
BOOL
|
||
|
CCertEncodeAltName::_VerifyName(
|
||
|
IN LONG NameIndex)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
BOOL fOk = FALSE;
|
||
|
CERT_ALT_NAME_ENTRY *pName;
|
||
|
|
||
|
assert(m_fConstructing);
|
||
|
|
||
|
hr = _MapName(TRUE, NameIndex, &pName);
|
||
|
if (S_OK != hr)
|
||
|
{
|
||
|
ceERRORPRINTLINE("_MapName", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
assert(NULL != pName);
|
||
|
switch (_NameType(pName->dwAltNameChoice))
|
||
|
{
|
||
|
case enumOther:
|
||
|
if (NULL != pName->pOtherName &&
|
||
|
NULL != pName->pOtherName->pszObjId &&
|
||
|
NULL != pName->pOtherName->Value.pbData)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
// FALLTHROUGH
|
||
|
|
||
|
case enumUnknown:
|
||
|
hr = E_INVALIDARG;
|
||
|
ceERRORPRINTLINE("uninitialized name", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
fOk = TRUE;
|
||
|
|
||
|
error:
|
||
|
return(fOk);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::Encode -- Encode AltName
|
||
|
//
|
||
|
// Returns S_OK on success.
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CCertEncodeAltName::Encode(
|
||
|
/* [out, retval] */ BSTR __RPC_FAR *pstrBinary)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
CERT_ALT_NAME_INFO AltName;
|
||
|
BYTE *pbEncoded = NULL;
|
||
|
DWORD cbEncoded;
|
||
|
LONG i;
|
||
|
|
||
|
if (NULL == pstrBinary)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
ceERRORPRINTLINE("NULL parm", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
AltName.cAltEntry = m_cValue;
|
||
|
AltName.rgAltEntry = m_aValue;
|
||
|
|
||
|
ceFreeBstr(pstrBinary);
|
||
|
if (!m_fConstructing || NULL == m_aValue)
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
ceERRORPRINTLINE("bad parameter", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < m_cValue; i++)
|
||
|
{
|
||
|
// Verify all entries are initialized:
|
||
|
|
||
|
if (!_VerifyName(i))
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||
|
ceERRORPRINTLINE("uninitialized name", hr);
|
||
|
goto error;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Encode CERT_ALT_NAME_INFO:
|
||
|
|
||
|
if (!ceEncodeObject(
|
||
|
X509_ASN_ENCODING,
|
||
|
X509_ALTERNATE_NAME,
|
||
|
&AltName,
|
||
|
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);
|
||
|
}
|
||
|
return(_SetErrorInfo(hr, L"CCertEncodeAltName::Encode"));
|
||
|
}
|
||
|
|
||
|
|
||
|
//+--------------------------------------------------------------------------
|
||
|
// CCertEncodeAltName::_SetErrorInfo -- set error object information
|
||
|
//
|
||
|
// Returns passed HRESULT
|
||
|
//+--------------------------------------------------------------------------
|
||
|
|
||
|
HRESULT
|
||
|
CCertEncodeAltName::_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_CERTENCODEALTNAME,
|
||
|
&IID_ICertEncodeAltName);
|
||
|
assert(hr == hrError);
|
||
|
}
|
||
|
return(hrError);
|
||
|
}
|