|
|
//-------------------------------------------------------------------------
//
// 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;
}
|