windows-nt/Source/XPSP1/NT/ds/security/cryptoapi/pkitrust/initpki/tcrack.cpp
2020-09-26 16:20:57 +08:00

381 lines
9.9 KiB
C++

//-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1999
//
// File: tcrack.cpp
//
// Contents: API testing of CryptEncodeObject/CryptDecodeObject.
//
// History: 29-January-97 xiaohs created
//
//--------------------------------------------------------------------------
#include "global.hxx"
//--------------------------------------------------------------------------
// See if the sequence "81 7f" is in the BLOB. If it is, we need to fix it
//--------------------------------------------------------------------------
BOOL BadCert(DWORD cbEncoded, BYTE *pbEncoded)
{
DWORD iIndex=0;
DWORD iLimit=cbEncoded-2;
BYTE rgByte[2];
assert(pbEncoded);
memset(rgByte, 0, 2);
//set the rgByte to be the patter of 0x81 0x7F, which is 10000001 and 01111111,
//whic his 129 and 127 in decimal
rgByte[0]=rgByte[0]|129;
rgByte[1]=rgByte[1]|127;
for(iIndex=0;iIndex<=iLimit;iIndex++)
{
if(memcmp(rgByte,&(pbEncoded[iIndex]),2)==0)
return TRUE;
}
return FALSE;
}
//--------------------------------------------------------------------------
// Copy the BLOBs
//--------------------------------------------------------------------------
void SetData(DWORD cbNewData, BYTE *pbNewData,
DWORD *pcbOldData, BYTE **ppbOldData)
{
assert(pcbOldData);
assert(ppbOldData);
*pcbOldData=cbNewData;
*ppbOldData=pbNewData;
}
///////////////////////////////////////////////////////////////////////////
//Certificate Manipulation Functions
//--------------------------------------------------------------------------
// This is the functions
//--------------------------------------------------------------------------
BOOL Fix7FCert(DWORD cbEncoded, BYTE *pbEncoded, DWORD *pcbEncoded,
BYTE **ppbEncoded)
{
//init
*pcbEncoded=0;
*ppbEncoded=NULL;
if(!BadCert(cbEncoded, pbEncoded))
return TRUE;
if(DecodeX509_CERT(cbEncoded, pbEncoded,pcbEncoded,
ppbEncoded))
return TRUE;
else
{
//release the memory
SAFE_FREE(*ppbEncoded)
*ppbEncoded=NULL;
*pcbEncoded=0;
return FALSE;
}
}
//--------------------------------------------------------------------------
// A general routine to encode a struct based on lpszStructType
//--------------------------------------------------------------------------
BOOL EncodeStruct(LPCSTR lpszStructType, void *pStructInfo,DWORD *pcbEncoded,
BYTE **ppbEncoded)
{
BOOL fSucceeded=FALSE;
DWORD cbEncoded=NULL;
//init
*pcbEncoded=0;
*ppbEncoded=NULL;
assert(lpszStructType);
assert(pStructInfo);
//length only calculation
TESTC(CryptEncodeObject(CRYPT_ENCODE_TYPE,lpszStructType, pStructInfo,NULL,
&cbEncoded),TRUE)
//the struct has to be more than 0 byte
assert(cbEncoded);
//allocate the correct amount of memory
*ppbEncoded=(BYTE *)SAFE_ALLOC(cbEncoded);
CHECK_POINTER(*ppbEncoded);
//Encode the strcut with *pcbEncoded == the correct length
*pcbEncoded=cbEncoded;
//Encode the struct
TESTC(CryptEncodeObject(CRYPT_ENCODE_TYPE,lpszStructType,pStructInfo,*ppbEncoded,
pcbEncoded),TRUE)
fSucceeded=TRUE;
TCLEANUP:
return fSucceeded;
}
//--------------------------------------------------------------------------
// A general routine to decode a BLOB based on lpszStructType
//
//--------------------------------------------------------------------------
BOOL DecodeBLOB(LPCSTR lpszStructType,DWORD cbEncoded, BYTE *pbEncoded,
DWORD *pcbStructInfo, void **ppvStructInfo)
{
BOOL fSucceeded=FALSE;
DWORD cbStructInfo=0;
//init
*pcbStructInfo=0;
*ppvStructInfo=NULL;
assert(lpszStructType);
assert(pbEncoded);
assert(cbEncoded);
//Decode. Length Only Calculation
TESTC(CryptDecodeObject(CRYPT_ENCODE_TYPE,lpszStructType,pbEncoded,cbEncoded,
CRYPT_DECODE_FLAG,NULL,&cbStructInfo),TRUE)
//the struct has to be more than 0 byte
assert(cbStructInfo);
*ppvStructInfo=(BYTE *)SAFE_ALLOC(cbStructInfo);
CHECK_POINTER(*ppvStructInfo);
//Decode the BLOB with *pcbStructInfo==correct length
*pcbStructInfo=cbStructInfo;
TESTC(CryptDecodeObject(CRYPT_ENCODE_TYPE,lpszStructType,pbEncoded,cbEncoded,
CRYPT_DECODE_FLAG,*ppvStructInfo,pcbStructInfo),TRUE)
fSucceeded=TRUE;
TCLEANUP:
return fSucceeded;
}
//--------------------------------------------------------------------------
// Decode X509_CERT BLOBs
//
//--------------------------------------------------------------------------
BOOL DecodeX509_CERT(DWORD cbEncoded, BYTE *pbEncoded,DWORD *pcbEncoded,
BYTE **ppbEncoded)
{
BOOL fSucceeded=FALSE;
DWORD cbStructInfo=0;
void *pStructInfo=NULL;
LPCSTR lpszStructType=NULL;
DWORD cbToBeSigned=0;
BYTE *pbToBeSigned=NULL;
DWORD cbOldSigned=0;
BYTE *pbOldSigned=NULL;
//init
lpszStructType=X509_CERT;
//Decode the encoded BLOB
TESTC(DecodeBLOB(lpszStructType,cbEncoded, pbEncoded,&cbStructInfo,
&pStructInfo),TRUE)
//Further Decode the X509_CERT_TO_BE_SIGNED
//Notice we should use the original cbData and pbData passed in for Decode
//but use ToBeSigned in CERT_SIGNED_CONTENT_INFO for encode purpose
TESTC(DecodeX509_CERT_TO_BE_SIGNED(cbEncoded,
pbEncoded,&cbToBeSigned,&pbToBeSigned),TRUE);
//copy the new encoded BLOB
SetData((((PCERT_SIGNED_CONTENT_INFO)pStructInfo)->ToBeSigned).cbData,
(((PCERT_SIGNED_CONTENT_INFO)pStructInfo)->ToBeSigned).pbData,
&cbOldSigned, &pbOldSigned);
SetData(cbToBeSigned, pbToBeSigned,
&((((PCERT_SIGNED_CONTENT_INFO)pStructInfo)->ToBeSigned).cbData),
&((((PCERT_SIGNED_CONTENT_INFO)pStructInfo)->ToBeSigned).pbData));
//if requested, encode the BLOB back to what it was. Make sure no data is lost
//by checking the size of the encoded blob and do a memcmp.
TESTC(EncodeStruct(lpszStructType, pStructInfo,pcbEncoded, ppbEncoded),TRUE);
fSucceeded=TRUE;
TCLEANUP:
SetData(cbOldSigned, pbOldSigned,
&((((PCERT_SIGNED_CONTENT_INFO)pStructInfo)->ToBeSigned).cbData),
&((((PCERT_SIGNED_CONTENT_INFO)pStructInfo)->ToBeSigned).pbData));
SAFE_FREE(pStructInfo)
SAFE_FREE(pbToBeSigned)
return fSucceeded;
}
//--------------------------------------------------------------------------
// Decode X509_CERT_TO_BE_SIGNED BLOBs
//
//--------------------------------------------------------------------------
BOOL DecodeX509_CERT_TO_BE_SIGNED(DWORD cbEncoded, BYTE *pbEncoded, DWORD *pcbEncoded,
BYTE **ppbEncoded)
{
BOOL fSucceeded=FALSE;
DWORD cbStructInfo=0;
void *pStructInfo=NULL;
LPCSTR lpszStructType=NULL;
DWORD cbOldIssuer=0;
BYTE *pbOldIssuer=NULL;
DWORD cbIssuer=0;
BYTE *pbIssuer=NULL;
DWORD cbOldSubject=0;
BYTE *pbOldSubject=NULL;
DWORD cbSubject=0;
BYTE *pbSubject=NULL;
//init
lpszStructType=X509_CERT_TO_BE_SIGNED;
//Decode the encoded BLOB
TESTC(DecodeBLOB(lpszStructType,cbEncoded, pbEncoded,&cbStructInfo,
&pStructInfo),TRUE)
//Decode Issuer in CERT_INFO struct
TESTC(DecodeX509_NAME((((PCERT_INFO)pStructInfo)->Issuer).cbData,
(((PCERT_INFO)pStructInfo)->Issuer).pbData,&cbIssuer,&pbIssuer),TRUE)
SetData((((PCERT_INFO)pStructInfo)->Issuer).cbData,
(((PCERT_INFO)pStructInfo)->Issuer).pbData,&cbOldIssuer,&pbOldIssuer);
SetData(cbIssuer, pbIssuer,
&((((PCERT_INFO)pStructInfo)->Issuer).cbData),
&((((PCERT_INFO)pStructInfo)->Issuer).pbData));
//Decode Subject in CERT_INFO struct
TESTC(DecodeX509_NAME((((PCERT_INFO)pStructInfo)->Subject).cbData,
(((PCERT_INFO)pStructInfo)->Subject).pbData,&cbSubject,&pbSubject),TRUE)
SetData((((PCERT_INFO)pStructInfo)->Subject).cbData,
(((PCERT_INFO)pStructInfo)->Subject).pbData,
&cbOldSubject, &pbOldSubject);
SetData(cbSubject, pbSubject,
&((((PCERT_INFO)pStructInfo)->Subject).cbData),
&((((PCERT_INFO)pStructInfo)->Subject).pbData));
//if requested, encode the BLOB back to what it was. Make sure no data is lost
//by checking the size of the encoded blob and do a memcmp.
TESTC(EncodeStruct(lpszStructType, pStructInfo,pcbEncoded,
ppbEncoded),TRUE);
fSucceeded=TRUE;
TCLEANUP:
//copy back the old values
SetData(cbOldSubject, pbOldSubject,
&((((PCERT_INFO)pStructInfo)->Subject).cbData),
&((((PCERT_INFO)pStructInfo)->Subject).pbData));
SetData(cbOldIssuer, pbOldIssuer,
&((((PCERT_INFO)pStructInfo)->Issuer).cbData),
&((((PCERT_INFO)pStructInfo)->Issuer).pbData));
SAFE_FREE(pStructInfo)
SAFE_FREE(pbSubject)
SAFE_FREE(pbIssuer)
return fSucceeded;
}
//--------------------------------------------------------------------------
// Decode X509_NAME BLOBs
//
//--------------------------------------------------------------------------
BOOL DecodeX509_NAME(DWORD cbEncoded, BYTE *pbEncoded, DWORD *pcbEncoded,
BYTE **ppbEncoded)
{
BOOL fSucceeded=FALSE;
DWORD cbStructInfo=0;
void *pStructInfo=NULL;
LPCSTR lpszStructType=NULL;
//init
lpszStructType=X509_NAME;
//Decode the encoded BLOB
TESTC(DecodeBLOB(lpszStructType,cbEncoded, pbEncoded,&cbStructInfo,
&pStructInfo),TRUE)
//if requested, encode the BLOB back to what it was. Make sure no data is lost
//by checking the size of the encoded blob and do a memcmp.
TESTC(EncodeStruct(lpszStructType, pStructInfo,pcbEncoded, ppbEncoded),TRUE);
fSucceeded=TRUE;
TCLEANUP:
SAFE_FREE(pStructInfo)
return fSucceeded;
}