windows-nt/Source/XPSP1/NT/ds/security/services/ca/certenc/adate.cpp

436 lines
9.4 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: adate.cpp
//
// Contents: Cert Server Extension Encoding/Decoding implementation
//
//---------------------------------------------------------------------------
#include "pch.cpp"
#pragma hdrstop
#include <assert.h>
#include "resource.h"
#include "adate.h"
#include "celib.h"
//+--------------------------------------------------------------------------
// CCertEncodeDateArray::~CCertEncodeDateArray -- destructor
//
// free memory associated with this instance
//+--------------------------------------------------------------------------
CCertEncodeDateArray::~CCertEncodeDateArray()
{
_Cleanup();
}
//+--------------------------------------------------------------------------
// CCertEncodeDateArray::_Cleanup -- release all resources
//
// free memory associated with this instance
//+--------------------------------------------------------------------------
VOID
CCertEncodeDateArray::_Cleanup()
{
if (NULL != m_aValue)
{
LocalFree(m_aValue);
m_aValue = NULL;
}
m_cValue = 0;
m_cValuesSet = 0;
m_fConstructing = FALSE;
}
//+--------------------------------------------------------------------------
// CCertEncodeDateArray::Decode -- Decode DateArray
//
// Returns S_OK on success.
//+--------------------------------------------------------------------------
STDMETHODIMP
CCertEncodeDateArray::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 = (DATE *) 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;
FILETIME ft;
// Decode each ASN blob to a FILETIME:
cb = sizeof(ft);
if (!CryptDecodeObject(
X509_ASN_ENCODING,
X509_CHOICE_OF_TIME,
pSequence->rgValue[i].pbData,
pSequence->rgValue[i].cbData,
0, // dwFlags
&ft,
&cb))
{
hr = ceHLastError();
ceERRORPRINTLINE("CryptDecodeObject", hr);
goto error;
}
assert(sizeof(ft) == cb);
// Convert each FILETIME into a DATE:
hr = ceFileTimeToDate(&ft, &m_aValue[i]);
if (S_OK != hr)
{
ceERRORPRINTLINE("ceFileTimeToDate", hr);
_Cleanup();
goto error;
}
}
error:
if (NULL != pSequence)
{
LocalFree(pSequence);
}
if (S_OK != hr)
{
_Cleanup();
}
return(_SetErrorInfo(hr, L"CCertEncodeDateArray::Decode"));
}
//+--------------------------------------------------------------------------
// CCertEncodeDateArray::GetCount -- Get Array count
//
// Returns S_OK on success.
//+--------------------------------------------------------------------------
STDMETHODIMP
CCertEncodeDateArray::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"CCertEncodeDateArray::GetCount"));
}
//+--------------------------------------------------------------------------
// CCertEncodeDateArray::GetValue -- Fetch the indexed date
//
// Returns S_OK on success.
//+--------------------------------------------------------------------------
STDMETHODIMP
CCertEncodeDateArray::GetValue(
/* [in] */ LONG Index,
/* [out, retval] */ DATE __RPC_FAR *pValue)
{
HRESULT hr = S_OK;
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;
}
if (0 == m_aValue[Index])
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
ceERRORPRINTLINE("uninitialized", hr);
goto error;
}
*pValue = m_aValue[Index];
error:
return(_SetErrorInfo(hr, L"CCertEncodeDateArray::GetValue"));
}
//+--------------------------------------------------------------------------
// CCertEncodeDateArray::Reset -- clear out data, and set up to encode new data
//
// Returns S_OK on success.
//+--------------------------------------------------------------------------
STDMETHODIMP
CCertEncodeDateArray::Reset(
/* [in] */ LONG Count)
{
HRESULT hr = S_OK;
_Cleanup();
m_fConstructing = TRUE;
if (CENCODEMAX < Count || 0 > Count)
{
hr = E_INVALIDARG;
ceERRORPRINTLINE("bad count parameter", hr);
goto error;
}
m_aValue = (DATE *) LocalAlloc(
LMEM_FIXED | LMEM_ZEROINIT,
Count * sizeof(m_aValue[0]));
if (NULL == m_aValue)
{
hr = E_OUTOFMEMORY;
ceERRORPRINTLINE("LocalAlloc", hr);
goto error;
}
m_cValue = Count;
error:
return(_SetErrorInfo(hr, L"CCertEncodeDateArray::Reset"));
}
//+--------------------------------------------------------------------------
// CCertEncodeDateArray::SetValue -- Set an array date
//
// Returns S_OK on success.
//+--------------------------------------------------------------------------
STDMETHODIMP
CCertEncodeDateArray::SetValue(
/* [in] */ LONG Index,
/* [in] */ DATE Value)
{
HRESULT hr = S_OK;
if (!m_fConstructing ||
NULL == m_aValue ||
Index >= m_cValue ||
m_cValuesSet >= m_cValue ||
0 != m_aValue[Index] ||
0 == Value)
{
hr = E_INVALIDARG;
ceERRORPRINTLINE("bad parameter", hr);
goto error;
}
m_aValue[Index] = Value;
m_cValuesSet++;
error:
return(_SetErrorInfo(hr, L"CCertEncodeDateArray::SetValue"));
}
//+--------------------------------------------------------------------------
// CCertEncodeDateArray::Encode -- Encode DateArray
//
// Returns S_OK on success.
//+--------------------------------------------------------------------------
STDMETHODIMP
CCertEncodeDateArray::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++)
{
FILETIME ft;
// Convert each DATE into a FILETIME:
assert(0 != m_aValue[i]);
hr = ceDateToFileTime(&m_aValue[i], &ft);
if (S_OK != hr)
{
ceERRORPRINTLINE("ceDateToFileTime", hr);
goto error;
}
// Encode each FILETIME into an ASN blob:
if (!ceEncodeObject(
X509_ASN_ENCODING,
X509_CHOICE_OF_TIME,
&ft,
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"CCertEncodeDateArray::Encode"));
}
//+--------------------------------------------------------------------------
// CCertEncodeDateArray::_SetErrorInfo -- set error object information
//
// Returns passed HRESULT
//+--------------------------------------------------------------------------
HRESULT
CCertEncodeDateArray::_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_CERTENCODEDATEARRAY,
&IID_ICertEncodeDateArray);
assert(hr == hrError);
}
return(hrError);
}