You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
964 lines
18 KiB
964 lines
18 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
blob.c
|
|
|
|
Abstract:
|
|
|
|
Generic blob manipulators for the IIS cryptographic package.
|
|
|
|
The following routines are exported by this module:
|
|
|
|
IISCryptoReadBlobFromRegistry
|
|
IISCryptoWriteBlobToRegistry
|
|
IISCryptoIsValidBlob
|
|
IISCryptoFreeBlob
|
|
IISCryptoCompareBlobs
|
|
IISCryptoCloneBlobFromRawData
|
|
IISCryptoCreateCleartextBlob
|
|
IcpCreateBlob
|
|
|
|
Author:
|
|
|
|
Keith Moore (keithmo) 02-Dec-1996
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
//
|
|
// Private constants.
|
|
//
|
|
|
|
|
|
//
|
|
// Private types.
|
|
//
|
|
|
|
|
|
//
|
|
// Private globals.
|
|
//
|
|
|
|
|
|
//
|
|
// Private prototypes.
|
|
//
|
|
|
|
|
|
//
|
|
// Public functions.
|
|
//
|
|
|
|
|
|
HRESULT
|
|
WINAPI
|
|
IISCryptoReadBlobFromRegistry(
|
|
OUT PIIS_CRYPTO_BLOB * ppBlob,
|
|
IN HKEY hRegistryKey,
|
|
IN LPCTSTR pszRegistryValueName
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine creates a new blob, reading the blob out of the
|
|
registry.
|
|
|
|
Arguments:
|
|
|
|
ppBlob - Receives a pointer to the newly created blob if successful.
|
|
|
|
hRegistryKey - An open handle to a registry key.
|
|
|
|
pszRegistryValueName - The name of the REG_BINARY registry value
|
|
containing the blob.
|
|
|
|
Return Value:
|
|
|
|
HRESULT - Completion status, 0 if successful, !0 otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
HRESULT result;
|
|
PIIS_CRYPTO_BLOB blob;
|
|
long status;
|
|
DWORD type;
|
|
long length;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
DBG_ASSERT( IcpGlobals.Initialized );
|
|
DBG_ASSERT( ppBlob != NULL );
|
|
DBG_ASSERT( hRegistryKey != NULL );
|
|
DBG_ASSERT( pszRegistryValueName != NULL );
|
|
|
|
//
|
|
// Setup our locals so we know how to cleanup on exit.
|
|
//
|
|
|
|
blob = NULL;
|
|
|
|
//
|
|
// Determine the size of the blob.
|
|
//
|
|
|
|
length = 0;
|
|
|
|
status = RegQueryValueEx(
|
|
hRegistryKey,
|
|
pszRegistryValueName,
|
|
NULL,
|
|
&type,
|
|
NULL,
|
|
( LPDWORD )&length
|
|
);
|
|
|
|
if( status != NO_ERROR ) {
|
|
result = RETURNCODETOHRESULT(status);
|
|
goto fatal;
|
|
}
|
|
|
|
//
|
|
// Allocate a new blob.
|
|
//
|
|
|
|
blob = IcpAllocMemory( length );
|
|
|
|
if( blob == NULL ) {
|
|
result = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
|
|
goto fatal;
|
|
}
|
|
|
|
//
|
|
// Read the blob.
|
|
//
|
|
|
|
status = RegQueryValueEx(
|
|
hRegistryKey,
|
|
pszRegistryValueName,
|
|
NULL,
|
|
&type,
|
|
(LPBYTE)blob,
|
|
( LPDWORD )&length
|
|
);
|
|
|
|
if( status != NO_ERROR ) {
|
|
result = RETURNCODETOHRESULT(status);
|
|
goto fatal;
|
|
}
|
|
|
|
//
|
|
// Validate the blob.
|
|
//
|
|
|
|
if( !IISCryptoIsValidBlob( blob ) ) {
|
|
result = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
|
|
goto fatal;
|
|
}
|
|
|
|
//
|
|
// Success!
|
|
//
|
|
|
|
*ppBlob = blob;
|
|
|
|
UpdateBlobsCreated();
|
|
return NO_ERROR;
|
|
|
|
fatal:
|
|
|
|
if( blob != NULL ) {
|
|
IcpFreeMemory( blob );
|
|
}
|
|
|
|
DBG_ASSERT( FAILED(result) );
|
|
return result;
|
|
|
|
} // IISCryptoReadBlobFromRegistry
|
|
|
|
|
|
HRESULT
|
|
WINAPI
|
|
IISCryptoWriteBlobToRegistry(
|
|
IN PIIS_CRYPTO_BLOB pBlob,
|
|
IN HKEY hRegistryKey,
|
|
IN LPCTSTR pszRegistryValueName
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine writes the given blob to the given registry location.
|
|
|
|
Arguments:
|
|
|
|
pBlob - A pointer to the blob to write.
|
|
|
|
hRegistryKey - An open handle to a registry key.
|
|
|
|
pszRegistryValueName - The name of the REG_BINARY registry value
|
|
that will receive the blob.
|
|
|
|
Return Value:
|
|
|
|
HRESULT - Completion status, 0 if successful, !0 otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
long status;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
DBG_ASSERT( IcpGlobals.Initialized );
|
|
DBG_ASSERT( pBlob != NULL );
|
|
DBG_ASSERT( IISCryptoIsValidBlob( pBlob ) );
|
|
DBG_ASSERT( hRegistryKey != NULL );
|
|
DBG_ASSERT( pszRegistryValueName != NULL );
|
|
|
|
//
|
|
// Write the blob.
|
|
//
|
|
|
|
status = RegSetValueEx(
|
|
hRegistryKey,
|
|
pszRegistryValueName,
|
|
0,
|
|
REG_BINARY,
|
|
(LPBYTE)pBlob,
|
|
IISCryptoGetBlobLength( pBlob )
|
|
);
|
|
|
|
return RETURNCODETOHRESULT(status);
|
|
|
|
} // IISCryptoWriteBlobToRegistry
|
|
|
|
|
|
BOOL
|
|
WINAPI
|
|
IISCryptoIsValidBlob(
|
|
IN PIIS_CRYPTO_BLOB pBlob
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine determines if the specified blob is indeed a valid
|
|
blob.
|
|
|
|
Arguments:
|
|
|
|
pBlob - The blob to validate.
|
|
|
|
Return Value:
|
|
|
|
BOOL - TRUE if the blob is valid, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PIC_BLOB blob;
|
|
BOOL result;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
DBG_ASSERT( IcpGlobals.Initialized );
|
|
DBG_ASSERT( pBlob != NULL );
|
|
|
|
//
|
|
// Validate the signature.
|
|
//
|
|
|
|
blob = (PIC_BLOB)pBlob;
|
|
|
|
switch( blob->Header.BlobSignature ) {
|
|
|
|
case KEY_BLOB_SIGNATURE :
|
|
case PUBLIC_KEY_BLOB_SIGNATURE :
|
|
case DATA_BLOB_SIGNATURE :
|
|
case HASH_BLOB_SIGNATURE :
|
|
case CLEARTEXT_BLOB_SIGNATURE :
|
|
result = TRUE;
|
|
break;
|
|
|
|
default :
|
|
result = FALSE;
|
|
break;
|
|
|
|
}
|
|
|
|
if( result &&
|
|
blob->Header.BlobSignature != CLEARTEXT_BLOB_SIGNATURE ) {
|
|
|
|
//
|
|
// Validate some of the blob internal structure. Note that we
|
|
// don't validate the internal structure of the cleartext blobs,
|
|
// as they do not conform to the normal IC_BLOB structure.
|
|
//
|
|
|
|
if( blob->DataLength == 0 ||
|
|
blob->Header.BlobDataLength !=
|
|
CALC_BLOB_DATA_LENGTH( blob->DataLength, blob->SignatureLength ) ) {
|
|
|
|
result = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
} // IISCryptoIsValidBlob
|
|
|
|
BOOL
|
|
WINAPI
|
|
IISCryptoIsValidBlob2(
|
|
IN PIIS_CRYPTO_BLOB pBlob
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine determines if the specified blob is indeed a valid
|
|
blob.
|
|
|
|
Arguments:
|
|
|
|
pBlob - The blob to validate.
|
|
|
|
Return Value:
|
|
|
|
BOOL - TRUE if the blob is valid, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PIC_BLOB2 blob;
|
|
BOOL result;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
DBG_ASSERT( IcpGlobals.Initialized );
|
|
DBG_ASSERT( pBlob != NULL );
|
|
|
|
//
|
|
// Validate the signature.
|
|
//
|
|
|
|
blob = (PIC_BLOB2)pBlob;
|
|
|
|
switch( blob->Header.BlobSignature ) {
|
|
|
|
case SALT_BLOB_SIGNATURE :
|
|
result = TRUE;
|
|
break;
|
|
|
|
default :
|
|
result = FALSE;
|
|
break;
|
|
|
|
}
|
|
|
|
if( result ) {
|
|
|
|
//
|
|
// Validate some of the blob internal structure. Note that we
|
|
// don't validate the internal structure of the cleartext blobs,
|
|
// as they do not conform to the normal IC_BLOB structure.
|
|
//
|
|
|
|
if( blob->DataLength == 0 ||
|
|
blob->Header.BlobDataLength !=
|
|
CALC_BLOB_DATA_LENGTH2( blob->DataLength, blob->SaltLength ) ) {
|
|
|
|
result = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
} // IISCryptoIsValidBlob2
|
|
|
|
|
|
HRESULT
|
|
WINAPI
|
|
IISCryptoFreeBlob(
|
|
IN PIIS_CRYPTO_BLOB pBlob
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine frees all resources associated with the given blob.
|
|
After this routine completes, the blob is unusable.
|
|
|
|
Arguments:
|
|
|
|
pBlob - The blob to free.
|
|
|
|
Return Value:
|
|
|
|
HRESULT - Completion status, 0 if successful, !0 otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
DBG_ASSERT( IcpGlobals.Initialized );
|
|
DBG_ASSERT( pBlob != NULL );
|
|
DBG_ASSERT( IISCryptoIsValidBlob( pBlob ) );
|
|
|
|
//
|
|
// Corrupt the structure signature before freeing the blob.
|
|
//
|
|
|
|
*(PCHAR)(&pBlob->BlobSignature) = 'X';
|
|
|
|
//
|
|
// Free the resources.
|
|
//
|
|
|
|
IcpFreeMemory( pBlob );
|
|
|
|
//
|
|
// Success!
|
|
//
|
|
|
|
UpdateBlobsFreed();
|
|
return NO_ERROR;
|
|
|
|
} // IISCryptoFreeBlob
|
|
|
|
HRESULT
|
|
WINAPI
|
|
IISCryptoFreeBlob2(
|
|
IN PIIS_CRYPTO_BLOB pBlob
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine frees all resources associated with the given blob.
|
|
After this routine completes, the blob is unusable.
|
|
|
|
Arguments:
|
|
|
|
pBlob - The blob to free.
|
|
|
|
Return Value:
|
|
|
|
HRESULT - Completion status, 0 if successful, !0 otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
DBG_ASSERT( IcpGlobals.Initialized );
|
|
DBG_ASSERT( pBlob != NULL );
|
|
DBG_ASSERT( IISCryptoIsValidBlob2( pBlob ) );
|
|
|
|
//
|
|
// Corrupt the structure signature before freeing the blob.
|
|
//
|
|
|
|
*(PCHAR)(&pBlob->BlobSignature) = 'X';
|
|
|
|
//
|
|
// Free the resources.
|
|
//
|
|
|
|
IcpFreeMemory( pBlob );
|
|
|
|
//
|
|
// Success!
|
|
//
|
|
|
|
UpdateBlobsFreed();
|
|
return NO_ERROR;
|
|
|
|
} // IISCryptoFreeBlob2
|
|
|
|
|
|
BOOL
|
|
WINAPI
|
|
IISCryptoCompareBlobs(
|
|
IN PIIS_CRYPTO_BLOB pBlob1,
|
|
IN PIIS_CRYPTO_BLOB pBlob2
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine compares two blobs to determine if they are identical.
|
|
|
|
Arguments:
|
|
|
|
pBlob1 - Pointer to a blob.
|
|
|
|
pBlob2 - Pointer to another blob.
|
|
|
|
Return Value:
|
|
|
|
BOOL - TRUE if the blobs match, FALSE otherwise, or if the blobs
|
|
are invalid.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
DBG_ASSERT( IcpGlobals.Initialized );
|
|
DBG_ASSERT( pBlob1 != NULL );
|
|
DBG_ASSERT( pBlob2 != NULL );
|
|
DBG_ASSERT( IISCryptoIsValidBlob( pBlob1 ) );
|
|
DBG_ASSERT( IISCryptoIsValidBlob( pBlob2 ) );
|
|
|
|
//
|
|
// Just do a straight memory compare of the two blobs.
|
|
//
|
|
|
|
if( memcmp( pBlob1, pBlob2, sizeof(*pBlob1) ) == 0 ) {
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// No match.
|
|
//
|
|
|
|
return FALSE;
|
|
|
|
} // IISCryptoCompareBlobs
|
|
|
|
|
|
HRESULT
|
|
WINAPI
|
|
IISCryptoCloneBlobFromRawData(
|
|
OUT PIIS_CRYPTO_BLOB * ppBlob,
|
|
IN PBYTE pRawBlob,
|
|
IN DWORD dwRawBlobLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine makes a copy of a blob from raw data. The raw data
|
|
buffer may be unaligned.
|
|
|
|
Arguments:
|
|
|
|
ppBlob - Receives a pointer to the newly created blob if successful.
|
|
|
|
pRawBlob - Pointer to the raw blob data.
|
|
|
|
dwRawBlobLength - Length of the raw blob data.
|
|
|
|
Return Value:
|
|
|
|
HRESULT - Completion status, 0 if successful, !0 otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PIIS_CRYPTO_BLOB newBlob;
|
|
IIS_CRYPTO_BLOB UNALIGNED *unalignedBlob;
|
|
DWORD blobLength;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
DBG_ASSERT( ppBlob != NULL );
|
|
DBG_ASSERT( pRawBlob != NULL );
|
|
|
|
//
|
|
// Allocate space for the new blob.
|
|
//
|
|
|
|
unalignedBlob = (IIS_CRYPTO_BLOB UNALIGNED *)pRawBlob;
|
|
blobLength = IISCryptoGetBlobLength( unalignedBlob );
|
|
|
|
if( blobLength != dwRawBlobLength ) {
|
|
return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
|
|
}
|
|
|
|
newBlob = IcpAllocMemory( blobLength );
|
|
if( newBlob != NULL ) {
|
|
|
|
//
|
|
// Clone it. The (PCHAR) casts are necessary to force the compiler
|
|
// to copy BYTE-wise.
|
|
//
|
|
|
|
RtlCopyMemory(
|
|
(PCHAR)newBlob,
|
|
(PCHAR)unalignedBlob,
|
|
blobLength
|
|
);
|
|
|
|
//
|
|
// Validate its contents.
|
|
//
|
|
|
|
if( IISCryptoIsValidBlob( newBlob ) ) {
|
|
|
|
*ppBlob = newBlob;
|
|
|
|
UpdateBlobsCreated();
|
|
return NO_ERROR;
|
|
|
|
}
|
|
|
|
IcpFreeMemory( newBlob );
|
|
return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
|
|
|
|
}
|
|
|
|
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
|
|
|
|
} // IISCryptoCloneBlobFromRawData
|
|
|
|
HRESULT
|
|
WINAPI
|
|
IISCryptoCloneBlobFromRawData2(
|
|
OUT PIIS_CRYPTO_BLOB * ppBlob,
|
|
IN PBYTE pRawBlob,
|
|
IN DWORD dwRawBlobLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine makes a copy of a blob from raw data. The raw data
|
|
buffer may be unaligned.
|
|
|
|
Arguments:
|
|
|
|
ppBlob - Receives a pointer to the newly created blob if successful.
|
|
|
|
pRawBlob - Pointer to the raw blob data.
|
|
|
|
dwRawBlobLength - Length of the raw blob data.
|
|
|
|
Return Value:
|
|
|
|
HRESULT - Completion status, 0 if successful, !0 otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PIIS_CRYPTO_BLOB newBlob;
|
|
IIS_CRYPTO_BLOB UNALIGNED *unalignedBlob;
|
|
DWORD blobLength;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
DBG_ASSERT( ppBlob != NULL );
|
|
DBG_ASSERT( pRawBlob != NULL );
|
|
|
|
//
|
|
// Allocate space for the new blob.
|
|
//
|
|
|
|
unalignedBlob = (IIS_CRYPTO_BLOB UNALIGNED *)pRawBlob;
|
|
blobLength = IISCryptoGetBlobLength( unalignedBlob );
|
|
|
|
if( blobLength != dwRawBlobLength ) {
|
|
return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
|
|
}
|
|
|
|
newBlob = IcpAllocMemory( blobLength );
|
|
if( newBlob != NULL ) {
|
|
|
|
//
|
|
// Clone it. The (PCHAR) casts are necessary to force the compiler
|
|
// to copy BYTE-wise.
|
|
//
|
|
|
|
RtlCopyMemory(
|
|
(PCHAR)newBlob,
|
|
(PCHAR)unalignedBlob,
|
|
blobLength
|
|
);
|
|
|
|
//
|
|
// Validate its contents.
|
|
//
|
|
|
|
if( IISCryptoIsValidBlob2( newBlob ) ) {
|
|
|
|
*ppBlob = newBlob;
|
|
|
|
UpdateBlobsCreated();
|
|
return NO_ERROR;
|
|
|
|
}
|
|
|
|
IcpFreeMemory( newBlob );
|
|
return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
|
|
|
|
}
|
|
|
|
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
|
|
|
|
} // IISCryptoCloneBlobFromRawData2
|
|
|
|
|
|
HRESULT
|
|
WINAPI
|
|
IISCryptoCreateCleartextBlob(
|
|
OUT PIIS_CRYPTO_BLOB * ppBlob,
|
|
IN PBYTE pBlobData,
|
|
IN DWORD dwBlobDataLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine creates a cleartext blob containing the specified
|
|
data.
|
|
|
|
Arguments:
|
|
|
|
ppBlob - Receives a pointer to the newly created blob if successful.
|
|
|
|
pBlobData - Pointer to the blob data.
|
|
|
|
dwBlobDataLength - Length of the blob data.
|
|
|
|
Return Value:
|
|
|
|
HRESULT - Completion status, 0 if successful, !0 otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PIIS_CRYPTO_BLOB blob;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
DBG_ASSERT( ppBlob != NULL );
|
|
DBG_ASSERT( pBlobData != NULL );
|
|
|
|
//
|
|
// Allocate space for the new blob.
|
|
//
|
|
|
|
blob = IcpAllocMemory( dwBlobDataLength + sizeof(*blob) );
|
|
|
|
if( blob != NULL ) {
|
|
|
|
//
|
|
// Initialize the blob.
|
|
//
|
|
|
|
blob->BlobSignature = CLEARTEXT_BLOB_SIGNATURE;
|
|
blob->BlobDataLength = dwBlobDataLength;
|
|
|
|
RtlCopyMemory(
|
|
blob + 1,
|
|
pBlobData,
|
|
dwBlobDataLength
|
|
);
|
|
|
|
*ppBlob = blob;
|
|
|
|
UpdateBlobsCreated();
|
|
return NO_ERROR;
|
|
|
|
}
|
|
|
|
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
|
|
|
|
} // IISCryptoCreateCleartextBlob
|
|
|
|
|
|
PIC_BLOB
|
|
IcpCreateBlob(
|
|
IN DWORD dwBlobSignature,
|
|
IN DWORD dwDataLength,
|
|
IN DWORD dwSignatureLength OPTIONAL
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine creates a new blob.
|
|
|
|
Arguments:
|
|
|
|
dwBlobSignature - The structure signature for the new blob.
|
|
|
|
dwDataLength - The data length for the blob.
|
|
|
|
dwSignatureLength - The length of the digital signature, 0 if
|
|
there is no signature for this blob. This value cannot be
|
|
CLEARTEXT_BLOB_SIGNATURE; cleartext blobs are "special".
|
|
|
|
Return Value:
|
|
|
|
PIC_BLOB - Pointer to the newly created blob if successful,
|
|
NULL otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PIC_BLOB blob;
|
|
DWORD blobDataLength;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
DBG_ASSERT( dwBlobSignature == KEY_BLOB_SIGNATURE ||
|
|
dwBlobSignature == PUBLIC_KEY_BLOB_SIGNATURE ||
|
|
dwBlobSignature == DATA_BLOB_SIGNATURE ||
|
|
dwBlobSignature == HASH_BLOB_SIGNATURE );
|
|
|
|
//
|
|
// Allocate storage for the blob.
|
|
//
|
|
|
|
blobDataLength = CALC_BLOB_DATA_LENGTH( dwDataLength, dwSignatureLength );
|
|
blob = IcpAllocMemory( blobDataLength + sizeof(IIS_CRYPTO_BLOB) );
|
|
|
|
if( blob != NULL ) {
|
|
|
|
//
|
|
// Initialize the blob.
|
|
//
|
|
|
|
blob->Header.BlobSignature = dwBlobSignature;
|
|
blob->Header.BlobDataLength = blobDataLength;
|
|
|
|
blob->DataLength = dwDataLength;
|
|
blob->SignatureLength = dwSignatureLength;
|
|
|
|
}
|
|
|
|
return blob;
|
|
|
|
} // IcpCreateBlob
|
|
|
|
PIC_BLOB2
|
|
IcpCreateBlob2(
|
|
IN DWORD dwBlobSignature,
|
|
IN DWORD dwDataLength,
|
|
IN DWORD dwSaltLength OPTIONAL
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine creates a new blob.
|
|
|
|
Arguments:
|
|
|
|
dwBlobSignature - The structure signature for the new blob.
|
|
|
|
dwDataLength - The data length for the blob.
|
|
|
|
dwSaltLength - The length of the random salt
|
|
|
|
Return Value:
|
|
|
|
PIC_BLOB2 - Pointer to the newly created blob if successful,
|
|
NULL otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PIC_BLOB2 blob;
|
|
DWORD blobDataLength;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
DBG_ASSERT( dwBlobSignature == SALT_BLOB_SIGNATURE );
|
|
|
|
//
|
|
// Allocate storage for the blob.
|
|
//
|
|
|
|
blobDataLength = CALC_BLOB_DATA_LENGTH( dwDataLength, dwSaltLength );
|
|
blob = IcpAllocMemory( blobDataLength + sizeof(IIS_CRYPTO_BLOB) );
|
|
|
|
if( blob != NULL ) {
|
|
|
|
//
|
|
// Initialize the blob.
|
|
//
|
|
|
|
blob->Header.BlobSignature = dwBlobSignature;
|
|
blob->Header.BlobDataLength = blobDataLength;
|
|
|
|
blob->DataLength = dwDataLength;
|
|
blob->SaltLength = dwSaltLength;
|
|
|
|
}
|
|
|
|
return blob;
|
|
|
|
} // IcpCreateBlob2
|
|
|
|
|
|
//
|
|
// Private functions.
|
|
//
|
|
|