Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

389 lines
8.5 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995.
//
// File: cert509.c
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 8-10-95 RichardW Created
//
//----------------------------------------------------------------------------
#include "sslsspi.h"
#include "encode.h"
#include "md5.h"
#include "md2.h"
BOOL
DoVerifySignature(
PUCHAR pbCertificate,
DWORD cbCertificate,
PUCHAR pbSignature,
DWORD cbSignature,
ALG_ID AlgId,
PSTR Authority)
{
MD5_CTX Md5;
MD2_CTX Md2;
BSAFE_PUB_KEY * pKey;
UCHAR Buffer[ENCRYPTED_KEY_SIZE];
UCHAR SigBuffer[ENCRYPTED_KEY_SIZE];
UCHAR Signature[16];
PUCHAR pDigest;
if (AlgId == MD2_WITH_RSA)
{
ZeroMemory( &Md2, sizeof(Md2) );
MD2Update( &Md2, pbCertificate, cbCertificate );
MD2Final( &Md2 );
pDigest = Md2.state;
}
else
{
MD5Init( &Md5 );
MD5Update( &Md5, pbCertificate, cbCertificate );
MD5Final( &Md5 );
pDigest = Md5.digest;
}
pKey = FindIssuerKey(Authority);
if (!pKey)
{
DebugLog((DEB_WARN, "Unknown Issuing Authority: %s\n", Authority));
return( FALSE );
}
ZeroMemory( SigBuffer, ENCRYPTED_KEY_SIZE );
ZeroMemory( Buffer, ENCRYPTED_KEY_SIZE );
ReverseMemCopy( SigBuffer, pbSignature, cbSignature );
BSafeEncPublic( pKey, SigBuffer, Buffer );
ReverseMemCopy( Signature, Buffer, 16 );
if (memcmp( Signature, pDigest, 16 ))
{
DebugLog((DEB_WARN, "Signatures did not compare?\n"));
return( FALSE );
}
else
{
DebugLog((DEB_TRACE, "Signatures matched !!! \n"));
}
return( TRUE );
}
BOOL
CrackCertificate(
PUCHAR pbCertificate,
DWORD cbCertificate,
BOOL VerifySignature,
PX509Certificate * ppCertificate)
{
DWORD cbCertInfo;
PUCHAR pCertInfo;
PUCHAR pbCert;
int Result;
PUCHAR SignedPortion;
DWORD dwLength;
PX509Certificate pCertificate;
ALG_ID PubKeyAlg;
PUCHAR PubKeyBuffer;
DWORD CertSize;
ALG_ID SigAlg;
PUCHAR pSig;
pbCert = pbCertificate;
Result = DecodeHeader(&cbCertInfo, pbCert);
if (Result < 0)
{
DebugLog((DEB_WARN, "Initial header wrong\n"));
return(FALSE);
}
pCertInfo = pbCert + Result;
SignedPortion = pCertInfo;
//
// Break Out certificate info
//
Result = DecodeHeader(&dwLength, pCertInfo);
if (Result < 0)
{
DebugLog((DEB_WARN, "Cert Data header wrong\n"));
return(FALSE);
}
pCertificate = SslAlloc('karC', LMEM_FIXED | LMEM_ZEROINIT, sizeof(X509Certificate) );
if (!pCertificate)
{
return(FALSE);
}
pCertInfo += Result;
Result = DecodeInteger( (BYTE *) pCertificate->SerialNumber,
&dwLength,
pCertInfo,
TRUE );
if (Result < 0)
{
DebugLog((DEB_WARN, "No Serial Number in certificate\n"));
goto Crack_CleanUp;
}
pCertInfo += Result;
Result = DecodeAlgorithm( &pCertificate->SignatureAlgorithm,
pCertInfo,
TRUE);
if (Result < 0)
{
DebugLog((DEB_WARN, "Algorithm has non-null parameters!\n"));
goto Crack_CleanUp;
}
pCertInfo += Result;
Result = DecodeDN( NULL, &dwLength, pCertInfo, FALSE);
if (Result < 0)
{
DebugLog((DEB_WARN, "No issuer name in certificate\n"));
goto Crack_CleanUp;
}
pCertificate->pszIssuer = SslAlloc('karC', LMEM_FIXED, dwLength + 1);
if (!pCertificate->pszIssuer)
{
goto Crack_CleanUp;
}
Result = DecodeDN(pCertificate->pszIssuer,
&dwLength,
pCertInfo,
TRUE);
pCertificate->pszIssuer[dwLength] = '\0'; // Null terminate the string...
pCertInfo += Result;
Result = DecodeHeader(&dwLength, pCertInfo);
if (Result < 0)
{
DebugLog((DEB_WARN, "Header for Validity times not found\n"));
goto Crack_CleanUp;
}
pCertInfo += Result;
Result = DecodeFileTime(&pCertificate->ValidFrom,
pCertInfo,
TRUE);
if (Result < 0)
{
DebugLog((DEB_WARN, "Valid from not found\n"));
goto Crack_CleanUp;
}
pCertInfo += Result;
Result = DecodeFileTime(&pCertificate->ValidUntil,
pCertInfo,
TRUE);
if (Result < 0)
{
DebugLog((DEB_WARN, "Valid until not found\n"));
goto Crack_CleanUp;
}
pCertInfo += Result;
Result = DecodeDN(NULL, &dwLength, pCertInfo, FALSE);
if (Result < 0)
{
DebugLog((DEB_WARN, "Subject name not found\n"));
goto Crack_CleanUp;
}
pCertificate->pszSubject = SslAlloc('karC', LMEM_FIXED, dwLength);
if (!pCertificate->pszSubject)
{
goto Crack_CleanUp;
}
Result = DecodeDN( pCertificate->pszSubject,
&dwLength,
pCertInfo,
TRUE);
if (Result < 0)
{
DebugLog((DEB_WARN, "Could not decode DN of subject\n"));
goto Crack_CleanUp;
}
pCertInfo += Result;
//
// Now, get subjectPublicKeyInfo
//
Result = DecodeHeader(&dwLength, pCertInfo);
if (Result < 0)
{
DebugLog((DEB_WARN, "No header for pubkey\n"));
goto Crack_CleanUp;
}
pCertInfo += Result;
Result = DecodeAlgorithm(&PubKeyAlg,
pCertInfo,
TRUE);
if (Result < 0)
{
DebugLog((DEB_WARN, "No algorithm\n"));
goto Crack_CleanUp;
}
pCertInfo += Result;
Result = DecodeBitString(NULL, &dwLength, pCertInfo, FALSE);
if (Result < 0)
{
DebugLog((DEB_WARN, "No pubkey bitstring\n"));
goto Crack_CleanUp;
}
PubKeyBuffer = SslAlloc('karC', LMEM_FIXED, dwLength);
if (!PubKeyBuffer)
{
goto Crack_CleanUp;
}
Result = DecodeBitString(PubKeyBuffer, &dwLength, pCertInfo, TRUE);
pCertInfo += Result;
Result = DecodeBsafePubKey( &pCertificate->pPublicKey,
&pCertificate->cbPublicKey,
PubKeyBuffer);
*ppCertificate = pCertificate;
CertSize = pCertInfo - SignedPortion;
Result = DecodeAlgorithm( &SigAlg, pCertInfo, TRUE );
if (Result < 0)
{
DebugLog((DEB_WARN, "No signature algorithm...\n"));
goto Crack_CleanUp;
}
pCertInfo += Result;
Result = DecodeBitString(NULL, &dwLength, pCertInfo, FALSE );
if (Result < 0)
{
DebugLog((DEB_WARN, "No signature bitstring?\n"));
goto Crack_CleanUp;
}
pSig = SslAlloc('karC', LMEM_FIXED, dwLength);
if (!pSig)
{
DebugLog((DEB_WARN, "Out of memory\n"));
goto Crack_CleanUp;
}
Result = DecodeBitString(pSig, &dwLength, pCertInfo, TRUE );
if (VerifySignature)
{
if ( DoVerifySignature( SignedPortion,
CertSize,
pSig,
dwLength,
SigAlg,
pCertificate->pszIssuer ) )
{
SslFree(pSig);
return( TRUE );
}
}
else
{
SslFree( pSig );
return( TRUE );
}
Crack_CleanUp:
DebugLog((DEB_WARN, "Error return from CrackCertificate, Cert at %x, current pointer at %x\n",
pbCertificate, pCertInfo));
if (pCertificate->pszSubject)
{
SslFree(pCertificate->pszSubject);
}
if (pCertificate->pszIssuer)
{
SslFree(pCertificate->pszIssuer);
}
SslFree(pCertificate);
return(FALSE);
}
VOID
FreeCertificate(
PX509Certificate pCertificate )
{
if ( pCertificate->pszSubject )
{
SslFree( pCertificate->pszSubject );
}
if ( pCertificate->pszIssuer )
{
SslFree( pCertificate->pszIssuer );
}
if ( pCertificate->pPublicKey )
{
SslFree( pCertificate->pPublicKey );
}
SslFree( pCertificate );
}