|
|
/* Key.cpp : defines the key object.
This file contains the routines that allow a key to store and restore itself */ #include "stdafx.h"
#include "resource.h"
#include "KeyObjs.h"
#include "cmnkey.h"
#include "W3Key.h"
#define KEY_VERSION 0x102
/*========
The scheme here is to create a handle that contains all the data necessary to restore the key object. The data contained in that handle is then stored as a secret on the target machine. This does require that the size of the handle be less than 65000 bytes, which should be no problem. */
//------------------------------------------------------------------------------
// generate a handle containing data that gets stored and then is used to restore
// the key object at a later date. Restore this key by passing this dereferenced
// handle back into the FInitKey routine above.
HANDLE CW3Key::HGenerateDataHandle( BOOL fIncludePassword ) { DWORD cbSize; DWORD cbChar = sizeof(TCHAR); PUCHAR p; HANDLE h;
CString szReserved; // save an empty string so that one can be added later
szReserved.Empty();
// calculate the size of the handle
cbSize = 2*sizeof(DWORD) + sizeof(BOOL); cbSize += sizeof(DWORD); // reserved dword
cbSize += sizeof(DWORD) + szReserved.GetLength() * cbChar + cbChar;
cbSize += sizeof(DWORD) + m_szName.GetLength() * cbChar + cbChar; cbSize += sizeof(DWORD) + m_szPassword.GetLength() * cbChar + cbChar;
// no longer need to store all the distinguishing info now that crack certificate works
cbSize += (sizeof(DWORD) + szReserved.GetLength() * cbChar + cbChar) * 6; /*
cbSize += sizeof(DWORD) + m_szOrganization.GetLength() * cbChar + cbChar; cbSize += sizeof(DWORD) + m_szUnit.GetLength() * cbChar + cbChar; cbSize += sizeof(DWORD) + m_szNetAddress.GetLength() * cbChar + cbChar; cbSize += sizeof(DWORD) + m_szCountry.GetLength() * cbChar + cbChar; cbSize += sizeof(DWORD) + m_szStateProvince.GetLength() * cbChar + cbChar; cbSize += sizeof(DWORD) + m_szLocality.GetLength() * cbChar + cbChar; */
cbSize += sizeof(DWORD) + m_szIPAddress.GetLength() * cbChar + cbChar; cbSize += sizeof(BOOL); //m_fDefault
cbSize += sizeof(DWORD) + m_cbPrivateKey; cbSize += sizeof(DWORD) + m_cbCertificate; cbSize += sizeof(DWORD) + m_cbCertificateRequest; cbSize += sizeof(FILETIME); // no longer used
// create the new handle and lock it
h = GlobalAlloc( GHND, cbSize ); if ( !h ) { AfxThrowMemoryException(); return NULL; } p = (PUCHAR)GlobalLock( h );
// put in the version, fComplete, and nBits
*((UNALIGNED DWORD*)p) = KEY_VERSION; p += sizeof(DWORD); *((UNALIGNED DWORD*)p) = 0; // no longer used
p += sizeof(DWORD); *((UNALIGNED BOOL*)p) = (m_pCertificate != NULL); // no longer used
p += sizeof(BOOL);
// add in a reserved dword for future use.
*((UNALIGNED DWORD*)p) = 0L; p += sizeof(DWORD);
// now the strings......
// for each string, first write out the size of the string, then the string data.
// save the reserved string. If you need to add one later and don't want to
// invalidate the older keys on a machine, replace this string.
cbSize = szReserved.GetLength() * cbChar + cbChar; *((UNALIGNED DWORD*)p) = cbSize; p += sizeof(DWORD); CopyMemory( p, LPCTSTR(szReserved), cbSize ); p += cbSize;
// save the name
cbSize = m_szName.GetLength() * cbChar + cbChar; *((UNALIGNED DWORD*)p) = cbSize; p += sizeof(DWORD); CopyMemory( p, LPCTSTR(m_szName), cbSize ); p += cbSize;
// save the password
if ( fIncludePassword ) { cbSize = m_szPassword.GetLength() * cbChar + cbChar; *((UNALIGNED DWORD*)p) = cbSize; p += sizeof(DWORD); CopyMemory( p, LPCTSTR(m_szPassword), cbSize ); p += cbSize; } else // do not include the password - just put in an empty field
{ *((UNALIGNED DWORD*)p) = 0; p += sizeof(DWORD); }
// no longer need to store all the distinguishing info now that crack certificate works
for ( WORD i = 0; i < 6; i++ ) { cbSize = szReserved.GetLength() * cbChar + cbChar; *((UNALIGNED DWORD*)p) = cbSize; p += sizeof(DWORD); CopyMemory( p, LPCTSTR(szReserved), cbSize ); p += cbSize; }
// save the ip address it is attached to
cbSize = m_szIPAddress.GetLength() * cbChar + cbChar; *((UNALIGNED DWORD*)p) = cbSize; p += sizeof(DWORD); CopyMemory( p, LPCTSTR(m_szIPAddress), cbSize ); p += cbSize;
// put in the m_fDefault flag
*((UNALIGNED BOOL*)p) = m_fDefault; p += sizeof(BOOL);
// now put in the number of bytes in the private key
*((UNALIGNED DWORD*)p) = m_cbPrivateKey; p += sizeof(DWORD);
// put in the private key
CopyMemory( p, m_pPrivateKey, m_cbPrivateKey ); p += m_cbPrivateKey;
// now put in the number of bytes in the certificate
*((UNALIGNED DWORD*)p) = m_cbCertificate; p += sizeof(DWORD);
// put in the certificate key
CopyMemory( p, m_pCertificate, m_cbCertificate ); p += m_cbCertificate;
// now put in the number of bytes in the certificate request
*((UNALIGNED DWORD*)p) = m_cbCertificateRequest; p += sizeof(DWORD);
// put in the certificate request
CopyMemory( p, m_pCertificateRequest, m_cbCertificateRequest ); p += m_cbCertificateRequest;
// and finally, add the timestamp
FILETIME ft; memset( &ft, 0, sizeof(ft) ); *((UNALIGNED FILETIME*)p) = ft; p += sizeof(FILETIME);
// unlock the handle
GlobalUnlock( h );
// all done
return h; }
//------------------------------------------------------------------------------
// Given a pointer to a block of data originally created by the above routine, fill
// in the key object
BOOL CW3Key::InitializeFromPointer( PUCHAR pSrc, DWORD cbSrc ) { DWORD dword, version; DWORD cbChar = sizeof(TCHAR); PUCHAR p = pSrc;
ASSERT(pSrc && cbSrc);
// get the version of the data - just put it into dword for now
version = *((UNALIGNED DWORD*)p); // check the version for validity
if ( version > KEY_VERSION ) { return FALSE; } p += sizeof(DWORD);
// anything below version 0x101 is BAD. Do not accept it
if ( version < 0x101 ) { AfxMessageBox( IDS_INVALID_KEY, MB_OK|MB_ICONINFORMATION ); return FALSE; } // get the bits and the complete flag
// no longer used
p += sizeof(DWORD); p += sizeof(BOOL); ASSERT( p < (pSrc + cbSrc) );
// get the reserved dword - (acutally, just skip over it)
p += sizeof(DWORD);
// now the strings......
// for each string, first get the size of the string, then the data from the string
// get the reserved string - (actually, just skip over it)
dword = *((UNALIGNED DWORD*)p); p += sizeof(DWORD); p += dword;
// get the name
dword = *((UNALIGNED DWORD*)p); p += sizeof(DWORD); m_szName= p; p += dword; ASSERT( p < (pSrc + cbSrc) );
// get the password
dword = *((UNALIGNED DWORD*)p); p += sizeof(DWORD); // if there is no password, don't worry, just skip it
if ( dword ) { m_szPassword = p; p += dword; ASSERT( p < (pSrc + cbSrc) ); }
// get the organization
// no longer used - skip the DN info
for ( WORD i = 0; i < 6; i++ ) { dword = *((UNALIGNED DWORD*)p); p += sizeof(DWORD); p += dword; ASSERT( p < (pSrc + cbSrc) ); }
// get the ip addres it is attached to
dword = *((UNALIGNED DWORD*)p); p += sizeof(DWORD); m_szIPAddress = p; p += dword; ASSERT( p < (pSrc + cbSrc) );
// get the default flag
m_fDefault = *((UNALIGNED BOOL*)p); p += sizeof(BOOL);
// now put get the number of bytes in the private key
m_cbPrivateKey = *((UNALIGNED DWORD*)p); p += sizeof(DWORD); ASSERT( p < (pSrc + cbSrc) );
// if the private key already exists, kill it. Then make a new pointer for it
if ( m_pPrivateKey ) GlobalFree( (HANDLE)m_pPrivateKey ); m_pPrivateKey = (PVOID)GlobalAlloc( GPTR, m_cbPrivateKey ); if ( !m_pPrivateKey ) return FALSE;
// put in the private key
CopyMemory( m_pPrivateKey, p, m_cbPrivateKey ); p += m_cbPrivateKey; ASSERT( p < (pSrc + cbSrc) );
// now put get the number of bytes in the certificate
m_cbCertificate = *((UNALIGNED DWORD*)p); p += sizeof(DWORD); ASSERT( p < (pSrc + cbSrc) );
// if the private key already exists, kill it. Then make a new pointer for it
if ( m_pCertificate ) GlobalFree( (HANDLE)m_pCertificate ); m_pCertificate = NULL;
// only make a certificate pointer if m_cbCertificate is greater than zero
if ( m_cbCertificate ) { m_pCertificate = (PVOID)GlobalAlloc( GPTR, m_cbCertificate ); if ( !m_pCertificate ) return FALSE;
// put in the private key
CopyMemory( m_pCertificate, p, m_cbCertificate ); p += m_cbCertificate; if ( version >= KEY_VERSION ) ASSERT( p < (pSrc + cbSrc) ); else ASSERT( p == (pSrc + cbSrc) ); }
// added near the end
if ( version >= KEY_VERSION ) { // now put get the number of bytes in the certificte request
m_cbCertificateRequest = *((UNALIGNED DWORD*)p); p += sizeof(DWORD); ASSERT( p < (pSrc + cbSrc) );
// if the private key already exists, kill it. Then make a new pointer for it
if ( m_pCertificateRequest ) GlobalFree( (HANDLE)m_pCertificateRequest ); m_pCertificateRequest = NULL;
// only make a certificate pointer if m_cbCertificate is greater than zero
if ( m_cbCertificateRequest ) { m_pCertificateRequest = (PVOID)GlobalAlloc( GPTR, m_cbCertificateRequest ); if ( !m_pCertificateRequest ) return FALSE;
// put in the private key
CopyMemory( m_pCertificateRequest, p, m_cbCertificateRequest ); p += m_cbCertificateRequest; ASSERT( p < (pSrc + cbSrc) ); }
// finally read in the expiration timestamp
// m_tsExpires = *((UNALIGNED FILETIME*)p);
p += sizeof(FILETIME); } else { m_cbCertificateRequest = 0; if ( m_pCertificateRequest ) GlobalFree( (HANDLE)m_pCertificateRequest ); m_pCertificateRequest = NULL; // m_tsExpires.dwLowDateTime = 0;
// m_tsExpires.dwHighDateTime = 0;
}
// all done
return TRUE; }
|