251 lines
7.3 KiB
C++
251 lines
7.3 KiB
C++
|
#include "stdafx.h"
|
||
|
|
||
|
#ifndef _CHICAGO_
|
||
|
|
||
|
// this file is always compile UNICODE in the library - so the conversions work out right
|
||
|
|
||
|
//
|
||
|
//Local includes
|
||
|
//
|
||
|
#include "certupgr.h"
|
||
|
|
||
|
#define BACKUP_ID 'KRBK'
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
void ReadWriteDWORD( HANDLE hFile, DWORD *pDword, BOOL fRead );
|
||
|
void ReadWriteString( HANDLE hFile, LPTSTR* ppsz, BOOL fRead );
|
||
|
void ReadWriteBlob( HANDLE hFile, PVOID pBlob, DWORD cbBlob, BOOL fRead );
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
PCCERT_CONTEXT ImportKRBackupToCAPIStore_A(
|
||
|
PCHAR pszFileName, // path of the file
|
||
|
PCHAR pszPassword, // ANSI password
|
||
|
PCHAR pszCAPIStore ) // name of the capi store
|
||
|
{
|
||
|
PCCERT_CONTEXT pCert = NULL;
|
||
|
|
||
|
// prep the wide strings
|
||
|
PWCHAR pszwFileName = NULL;
|
||
|
PWCHAR pszwCAPIStore = NULL;
|
||
|
DWORD lenFile = (strlen(pszFileName)+1) * sizeof(TCHAR);
|
||
|
DWORD lenStore = (strlen(pszCAPIStore)+1) * sizeof(TCHAR);
|
||
|
pszwFileName = (PWCHAR)GlobalAlloc( GPTR, lenFile );
|
||
|
pszwCAPIStore = (PWCHAR)GlobalAlloc( GPTR, lenStore );
|
||
|
if ( !pszwFileName || !pszwCAPIStore )
|
||
|
goto cleanup;
|
||
|
|
||
|
// convert the strings
|
||
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pszFileName, -1, pszwFileName, lenFile );
|
||
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pszCAPIStore, -1, pszwCAPIStore, lenStore );
|
||
|
|
||
|
// do the real call
|
||
|
pCert = ImportKRBackupToCAPIStore_W( pszwFileName, pszPassword, pszwCAPIStore );
|
||
|
|
||
|
cleanup:
|
||
|
// preserve the last error state
|
||
|
DWORD err = GetLastError();
|
||
|
|
||
|
// clean up the strings
|
||
|
if ( pszwFileName )
|
||
|
GlobalFree( pszwFileName );
|
||
|
if ( pszwCAPIStore )
|
||
|
GlobalFree( pszwCAPIStore );
|
||
|
|
||
|
// reset the last error state
|
||
|
SetLastError( err );
|
||
|
|
||
|
// return the cert
|
||
|
return pCert;
|
||
|
}
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
// Import old-style keyring backup file
|
||
|
PCCERT_CONTEXT ImportKRBackupToCAPIStore_W(
|
||
|
PWCHAR ptszFileName, // path of the file
|
||
|
PCHAR pszPassword, // ANSI password
|
||
|
PWCHAR pszCAPIStore ) // name of the capi store
|
||
|
{
|
||
|
PCCERT_CONTEXT pCertContext = NULL;
|
||
|
DWORD dword;
|
||
|
LPTSTR psz = NULL;
|
||
|
|
||
|
// prep the file name
|
||
|
HANDLE hFile = NULL;
|
||
|
|
||
|
// This code is originally from KeyRing. The fImport controlled whether it was reading
|
||
|
// or writing the file. In this case, we are always and only reading it. so....
|
||
|
const BOOL fImport = TRUE;
|
||
|
|
||
|
// also, this was a method on a class. The appropriate member variables are now here
|
||
|
PVOID pPrivateKey = NULL;
|
||
|
DWORD cbPrivateKey;
|
||
|
PVOID pCertificate = NULL;
|
||
|
DWORD cbCertificate;
|
||
|
PVOID pRequest = NULL;
|
||
|
DWORD cbRequest = 0;
|
||
|
CString szName;
|
||
|
|
||
|
// open the file
|
||
|
hFile = CreateFile(
|
||
|
ptszFileName, // pointer to name of the file
|
||
|
GENERIC_READ, // access (read-write) mode
|
||
|
FILE_SHARE_READ, // share mode
|
||
|
NULL, // pointer to security attributes
|
||
|
OPEN_EXISTING, // how to create
|
||
|
FILE_ATTRIBUTE_NORMAL, // file attributes
|
||
|
NULL // handle to file with attributes to copy
|
||
|
);
|
||
|
if ( hFile == INVALID_HANDLE_VALUE )
|
||
|
return NULL;
|
||
|
|
||
|
// do the backup id
|
||
|
dword = BACKUP_ID;
|
||
|
ReadWriteDWORD( hFile, &dword, fImport );
|
||
|
|
||
|
// check the backup id
|
||
|
if ( dword != BACKUP_ID )
|
||
|
{
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
// start with the name of the key
|
||
|
ReadWriteString( hFile, &psz, fImport );
|
||
|
|
||
|
// we aren't using the name for now, so throw it away.....
|
||
|
if ( psz )
|
||
|
GlobalFree( psz );
|
||
|
psz = NULL;
|
||
|
|
||
|
// now the private key data size
|
||
|
ReadWriteDWORD( hFile, &cbPrivateKey, fImport );
|
||
|
|
||
|
// make a private key data pointer if necessary
|
||
|
if ( fImport && cbPrivateKey )
|
||
|
{
|
||
|
pPrivateKey = GlobalAlloc( GPTR, cbPrivateKey );
|
||
|
if ( !pPrivateKey )
|
||
|
{
|
||
|
goto cleanup;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// use the private key pointer
|
||
|
if ( cbPrivateKey )
|
||
|
ReadWriteBlob( hFile, pPrivateKey, cbPrivateKey, fImport );
|
||
|
|
||
|
|
||
|
// now the certificate
|
||
|
ReadWriteDWORD( hFile, &cbCertificate, fImport );
|
||
|
|
||
|
// make a data pointer if necessary
|
||
|
if ( fImport && cbCertificate )
|
||
|
{
|
||
|
pCertificate = GlobalAlloc( GPTR, cbCertificate );
|
||
|
if ( !pCertificate )
|
||
|
{
|
||
|
goto cleanup;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// use the public key pointer
|
||
|
if ( cbCertificate )
|
||
|
ReadWriteBlob( hFile, pCertificate, cbCertificate, fImport );
|
||
|
|
||
|
|
||
|
// now the request - if there is one
|
||
|
ReadWriteDWORD( hFile, &cbRequest, fImport );
|
||
|
|
||
|
// make a data pointer if necessary
|
||
|
if ( fImport && cbRequest )
|
||
|
{
|
||
|
pRequest = GlobalAlloc( GPTR, cbRequest );
|
||
|
if ( !pRequest )
|
||
|
{
|
||
|
goto cleanup;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// use the request pointer
|
||
|
if ( cbRequest )
|
||
|
ReadWriteBlob( hFile, pRequest, cbRequest, fImport );
|
||
|
|
||
|
|
||
|
// finally, do the CAPI conversion here
|
||
|
pCertContext = CopyKRCertToCAPIStore(
|
||
|
pPrivateKey, cbPrivateKey,
|
||
|
pCertificate, cbCertificate,
|
||
|
pRequest, cbRequest,
|
||
|
pszPassword,
|
||
|
pszCAPIStore);
|
||
|
|
||
|
// clean up
|
||
|
cleanup:
|
||
|
if ( hFile )
|
||
|
CloseHandle( hFile );
|
||
|
if ( pPrivateKey )
|
||
|
GlobalFree( pPrivateKey );
|
||
|
if ( pCertificate )
|
||
|
GlobalFree( pCertificate );
|
||
|
if ( pRequest )
|
||
|
GlobalFree( pRequest );
|
||
|
|
||
|
// return the context
|
||
|
return pCertContext;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// file utilities
|
||
|
//---------------------------------------------------------------------------
|
||
|
void ReadWriteDWORD( HANDLE hFile, DWORD *pDword, BOOL fRead )
|
||
|
{
|
||
|
// read it or write it
|
||
|
ReadWriteBlob( hFile, pDword, sizeof(DWORD), fRead );
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// remember - we are only and always reading - never writing.......
|
||
|
void ReadWriteString( HANDLE hFile, LPTSTR* ppsz, BOOL fRead )
|
||
|
{
|
||
|
// get the length of the string
|
||
|
DWORD cbLength = 0;
|
||
|
ReadWriteDWORD(hFile,&cbLength,fRead );
|
||
|
|
||
|
// allocate the buffer for the new string - it is the responsibility
|
||
|
// of the caller to ensure that ppsz is not pointing to something that
|
||
|
// needs to be freed.
|
||
|
if ( fRead )
|
||
|
{
|
||
|
*ppsz = (LPTSTR)GlobalAlloc( GPTR, cbLength+1 );
|
||
|
ASSERT( *ppsz );
|
||
|
if ( !*ppsz )
|
||
|
AfxThrowMemoryException();
|
||
|
}
|
||
|
|
||
|
// read or write the string
|
||
|
ReadWriteBlob(hFile, *ppsz, cbLength+1, fRead);
|
||
|
}
|
||
|
|
||
|
/* #pragma INTRINSA suppress=all */
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
void ReadWriteBlob( HANDLE hFile, PVOID pBlob, DWORD cbBlob, BOOL fRead )
|
||
|
{
|
||
|
// read it or write it
|
||
|
// - always read it here this isn't keyring anymore
|
||
|
ReadFile(
|
||
|
hFile, // handle of file to read
|
||
|
pBlob, // address of buffer that receives data
|
||
|
cbBlob, // number of bytes to read
|
||
|
&cbBlob, // address of number of bytes read
|
||
|
NULL // address of structure for data
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#endif //_CHICAGO_
|