Leaked source code of windows server 2003
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.
 
 
 
 
 
 

772 lines
24 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1997 - 1998
//
// File: tcrobu.cpp
//
// Contents: CryptRetrieveObjectByUrl tests
//
// History: 27-May-97 kirtd Created
//
//----------------------------------------------------------------------------
#include <windows.h>
#include <assert.h>
#include "wincrypt.h"
#include "certtest.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <time.h>
#include <wininet.h>
#include <md5.h>
#include <cryptnet.h>
typedef BYTE CRYPT_ORIGIN_IDENTIFIER[MD5DIGESTLEN];
BYTE Foo[300];
BYTE Bar[300];
DWORD g_dwCount = 0;
//+---------------------------------------------------------------------------
//
// Function: Usage
//
// Synopsis: prints the usage statement
//
//----------------------------------------------------------------------------
static void Usage(void)
{
printf("Usage: tcrobu URL [ObjectOid] [-m] [-c] [-s] [-w] [-l]\n");
printf(" URL, locator to retrieve from\n");
printf(" ObjectOid, a cert, crl, or ctl, if omitted, retrieve bits\n");
printf(" -m, retrieve multiple objects\n");
printf(" -c, cache only retrieval\n");
printf(" -d, do not cache the result\n");
printf(" -w, wire only retrieval\n");
printf(" -u, CryptGetObjectUrl on the result context\n");
printf(" -l, logon user credentials <user> <password>\n");
printf(" -t, timeout\n");
printf(" -f, install cancel function\n");
printf(" -n, install and uninstall cancel function\n");
printf(" -r, the # of times the cancel function should be called\n");
printf(" -v, verbose display\n");
printf(" -q, quiet display\n");
printf(" -s, save to serialized store file\n");
printf(" -7, save to PKCS7 store file\n");
printf(" -a, get AuxInfo\n");
printf(" -p, sticky persist\n");
printf(" -e, prepend LDAP entry and attribute\n");
printf(" -k, Kerberos Signing for LDAP\n");
printf(" -i, inhibit authentication\n");
printf(" -Error, expected error\n");
printf(" -Flags, retrieval flags to be OR'ed\n");
printf(" -Size, maximum retrieval byte count\n");
}
//+---------------------------------------------------------------------------
//
// Function: CertGetOriginIdentifier
//
// Synopsis: get the origin identifier for a certificate
//
//----------------------------------------------------------------------------
BOOL WINAPI CertGetOriginIdentifier (
IN PCCERT_CONTEXT pCertContext,
IN PCCERT_CONTEXT pIssuer,
IN DWORD dwFlags,
OUT CRYPT_ORIGIN_IDENTIFIER OriginIdentifier
)
{
MD5_CTX md5ctx;
PCERT_INFO pCertInfo = pCertContext->pCertInfo;
PCERT_INFO pIssuerCertInfo = pIssuer->pCertInfo;
MD5Init( &md5ctx );
MD5Update( &md5ctx, pCertInfo->Issuer.pbData, pCertInfo->Issuer.cbData );
MD5Update( &md5ctx, pCertInfo->Subject.pbData, pCertInfo->Subject.cbData );
MD5Update(
&md5ctx,
(LPBYTE)pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,
strlen( pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId )
);
MD5Update(
&md5ctx,
pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.pbData,
pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.cbData
);
// We assume that the unused public key bits are zero
MD5Update(
&md5ctx,
pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData
);
MD5Update(
&md5ctx,
pIssuerCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
pIssuerCertInfo->SubjectPublicKeyInfo.PublicKey.cbData
);
MD5Final( &md5ctx );
memcpy( OriginIdentifier, md5ctx.digest, MD5DIGESTLEN );
return( TRUE );
}
//+---------------------------------------------------------------------------
//
// Function: MyCancelFunction
//
// Synopsis: The call back function to cancel the object retrieval.
// The cancellation happens when it is called for the 3rd time.
//
//----------------------------------------------------------------------------
BOOL WINAPI MyCancelFunction(DWORD dwFlags, void *pvArg)
{
DWORD *pCount=NULL;
pCount=(DWORD *)pvArg;
if(*pCount == g_dwCount)
return TRUE;
(*pCount)++;
return FALSE;
}
//+---------------------------------------------------------------------------
//
// Function: main
//
// Synopsis: main program entry point
//
//----------------------------------------------------------------------------
int _cdecl main(int argc, char * argv[])
{
#if 0
BOOL fResult;
HINTERNET hInetSession;
hInetSession = InternetOpen(
"foo",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0
);
if ( hInetSession == NULL )
{
printf("Error opening internet session %lx\n", GetLastError());
return( 1 );
}
fResult = InternetSetOption(
hInetSession,
INTERNET_OPTION_USERNAME,
"foo",
strlen( "foo" ) + 1
);
if ( fResult == TRUE )
{
fResult = InternetSetOption(
hInetSession,
INTERNET_OPTION_PROXY_USERNAME,
"bar",
strlen( "bar" ) + 1
);
}
if ( fResult == TRUE )
{
fResult = InternetSetOption(
hInetSession,
INTERNET_OPTION_PASSWORD,
"gamma",
strlen( "gamma" ) + 1
);
if ( fResult == TRUE )
{
fResult = InternetSetOption(
hInetSession,
INTERNET_OPTION_PROXY_PASSWORD,
"beta",
strlen( "beta" ) + 1
);
}
}
InternetCloseHandle( hInetSession );
return( 0 );
#endif
#if 0
LPWSTR pwszUrl = NULL;
if ( I_CryptNetGetUserDsStoreUrl( L"X509Certificate", &pwszUrl ) == TRUE )
{
wprintf(L"User DS Store URL = <%s>\n", pwszUrl);
CryptMemFree( pwszUrl );
}
else
{
printf("I_CryptNetGetUserDsStoreUrl failed <%lx>\n", GetLastError());
}
return( 0 );
#endif
#if 1
ULONG cCount;
PCRYPT_BLOB_ARRAY pcba;
LPVOID pv;
LPSTR pszObjectOid = NULL;
LPSTR pszUrl = NULL;
LPSTR pszUsername = NULL;
LPSTR pszPassword = NULL;
DWORD dwRetrievalFlags = 0;
BOOL fGetObjectUrl = FALSE;
PCRYPT_CREDENTIALS pCredentials = NULL;
CRYPT_CREDENTIALS Credentials;
CRYPT_PASSWORD_CREDENTIALSA PasswordCredentials;
CRYPT_PASSWORD_CREDENTIALSW UnicodePasswordCredentials;
BOOL fUnicodeCredentials = FALSE;
LPWSTR pwszUsername = NULL;
LPWSTR pwszPassword = NULL;
DWORD dwTimeout = 0;
BOOL fCancel = FALSE;
BOOL fUninstall = FALSE;
DWORD dwCount = 0;
BOOL fQuiet = FALSE;
DWORD dwDisplayFlags = 0;
BOOL fSave = FALSE;
BOOL fPKCS7Save = FALSE;
LPSTR pszSaveFilename = NULL;
DWORD dwExpectedError = 0;
PCRYPT_RETRIEVE_AUX_INFO pAuxInfo = NULL;
FILETIME LastSyncTime = { 0, 0 };
CRYPT_RETRIEVE_AUX_INFO AuxInfo;
memset(&AuxInfo, 0, sizeof(AuxInfo));
AuxInfo.cbSize = sizeof(AuxInfo);
if ( argc < 2 )
{
Usage();
return( 1 );
}
argv++;
argc--;
printf( "command line: %s\n", GetCommandLineA() );
pszUrl = argv[0];
while ( --argc > 0 )
{
if (**++argv == '-')
{
if (0 == _stricmp(argv[0]+1, "Error")) {
if ( argc < 2 )
{
Usage();
return( 1 );
}
dwExpectedError = (DWORD) strtoul(argv[1], NULL, 0);
argc -= 1;
argv++;
} else if (0 == _stricmp(argv[0]+1, "Flags")) {
if ( argc < 2 )
{
Usage();
return( 1 );
}
dwRetrievalFlags |= (DWORD) strtoul(argv[1], NULL, 0);
argc -= 1;
argv++;
} else if (0 == _stricmp(argv[0]+1, "Size")) {
if ( argc < 2 )
{
Usage();
return( 1 );
}
pAuxInfo = &AuxInfo;
AuxInfo.dwMaxUrlRetrievalByteCount =
(DWORD) strtoul(argv[1], NULL, 0);
argc -= 1;
argv++;
} else {
switch(argv[0][1])
{
case 'm':
case 'M':
dwRetrievalFlags |= CRYPT_RETRIEVE_MULTIPLE_OBJECTS;
break;
case 'c':
case 'C':
dwRetrievalFlags |= CRYPT_CACHE_ONLY_RETRIEVAL;
break;
case 'w':
case 'W':
dwRetrievalFlags |= CRYPT_WIRE_ONLY_RETRIEVAL;
break;
case 'f':
case 'F':
fCancel = TRUE;
break;
case 'n':
case 'N':
fUninstall = TRUE;
break;
case 'd':
case 'D':
dwRetrievalFlags |= CRYPT_DONT_CACHE_RESULT;
break;
case 'u':
case 'U':
fGetObjectUrl = TRUE;
break;
case 't':
case 'T':
if ( argc < 2 )
{
Usage();
return( 1 );
}
dwTimeout = atol( argv[1] );
argc -= 1;
argv++;
break;
case 'r':
case 'R':
if ( argc < 2 )
{
Usage();
return( 1 );
}
g_dwCount = atol( argv[1] );
argc -= 1;
argv++;
break;
case 'L':
fUnicodeCredentials = TRUE;
case 'l':
if ( argc < 2 )
{
Usage();
return( 1 );
}
pszUsername = argv[1];
if ( argc > 2 )
{
pszPassword = argv[2];
argc--;
argv++;
}
argc -= 1;
argv++;
break;
case 'q':
case 'Q':
fQuiet = TRUE;
break;
case 'v':
case 'V':
dwDisplayFlags |= DISPLAY_VERBOSE_FLAG;
break;
case '7':
fPKCS7Save = TRUE;
case 's':
case 'S':
fSave = TRUE;
if ( argc < 2 )
{
Usage();
return( 1 );
}
pszSaveFilename = argv[1];
argc -= 1;
argv++;
break;
case 'a':
case 'A':
pAuxInfo = &AuxInfo;
AuxInfo.pLastSyncTime = &LastSyncTime;
break;
case 'p':
case 'P':
dwRetrievalFlags |= CRYPT_STICKY_CACHE_RETRIEVAL;
break;
case 'e':
case 'E':
dwRetrievalFlags |= CRYPT_LDAP_INSERT_ENTRY_ATTRIBUTE;
break;
case 'k':
case 'K':
dwRetrievalFlags |= CRYPT_LDAP_SIGN_RETRIEVAL;
break;
case 'i':
case 'I':
dwRetrievalFlags |= CRYPT_NO_AUTH_RETRIEVAL;
break;
default:
Usage();
return -1;
}
}
}
else
{
if ( _stricmp( argv[0], "cert" ) == 0 )
{
pszObjectOid = (LPSTR)CONTEXT_OID_CERTIFICATE;
}
else if ( _stricmp( argv[0], "ctl" ) == 0 )
{
pszObjectOid = (LPSTR)CONTEXT_OID_CTL;
}
else if ( _stricmp( argv[0], "crl" ) == 0 )
{
pszObjectOid = (LPSTR)CONTEXT_OID_CRL;
}
else if ( _stricmp( argv[0], "pkcs7" ) == 0 )
{
pszObjectOid = (LPSTR)CONTEXT_OID_PKCS7;
}
else if ( _stricmp( argv[0], "any" ) == 0 )
{
pszObjectOid = (LPSTR)CONTEXT_OID_CAPI2_ANY;
}
else
{
Usage();
return( -1 );
}
}
}
if ( pszUsername != NULL )
{
if (fUnicodeCredentials)
{
pwszUsername = AllocAndSzToWsz(pszUsername);
if ( pszPassword != NULL )
{
pwszPassword = AllocAndSzToWsz(pszPassword);
}
UnicodePasswordCredentials.cbSize =
sizeof( UnicodePasswordCredentials );
UnicodePasswordCredentials.pszUsername = pwszUsername;
UnicodePasswordCredentials.pszPassword = pwszPassword;
Credentials.cbSize = sizeof( Credentials );
Credentials.pszCredentialsOid =
CREDENTIAL_OID_PASSWORD_CREDENTIALS_W;
Credentials.pvCredentials = (LPVOID)&UnicodePasswordCredentials;
pCredentials = &Credentials;
printf("Using Unicode credentials %S <%S>\n",
pwszUsername, pwszPassword);
}
else
{
PasswordCredentials.cbSize = sizeof( PasswordCredentials );
PasswordCredentials.pszUsername = pszUsername;
PasswordCredentials.pszPassword = pszPassword;
Credentials.cbSize = sizeof( Credentials );
Credentials.pszCredentialsOid = CREDENTIAL_OID_PASSWORD_CREDENTIALS_A;
Credentials.pvCredentials = (LPVOID)&PasswordCredentials;
pCredentials = &Credentials;
printf("Using credentials %s <%s>\n", pszUsername, pszPassword);
}
}
if(fCancel)
{
if(!CryptInstallCancelRetrieval(
MyCancelFunction,
&dwCount,
0,
NULL))
printf("Install cancel function failed!\n");
if(fUninstall)
{
if(!CryptUninstallCancelRetrieval(
0,
NULL))
printf("Uninstall cancel function failed!\n");
}
}
if ( CryptRetrieveObjectByUrlA(
pszUrl,
pszObjectOid,
dwRetrievalFlags,
dwTimeout,
&pv,
NULL,
pCredentials,
NULL,
pAuxInfo
) == FALSE )
{
DWORD dwLastErr = GetLastError();
if (0 == dwExpectedError)
printf( "CryptRetrieveObjectByUrl FAILED! <0x%x %d>\n", dwLastErr, dwLastErr );
else if (dwLastErr != dwExpectedError)
printf( "CryptRetrieveObjectByUrl FAILED! Expected: 0x%x Actual: <0x%x %d>\n", dwExpectedError, dwLastErr, dwLastErr );
else
printf( "CryptRetrieveObjectByUrl SUCCEEDED! Got Expected: <0x%x %d>\n", dwLastErr, dwLastErr );
if(fCancel)
{
if(!fUninstall)
{
if(!CryptUninstallCancelRetrieval(
0,
NULL))
printf("Uninstall cancel function failed!\n");
}
}
if (pwszUsername)
TestFree(pwszUsername);
if (pwszPassword)
TestFree(pwszPassword);
return( -1 );
}
if (0 == dwExpectedError)
printf( "CryptRetrieveObjectByUrl SUCCEEDED!\n" );
else
printf( "CryptRetrieveObjectByUrl FAILED! Expected: 0x%x Actual: 0x0\n", dwExpectedError );
if (pAuxInfo)
{
printf(" LastSyncTime:: %s\n",
FileTimeText(&LastSyncTime));
}
if(fCancel)
{
if(!fUninstall)
{
if(!CryptUninstallCancelRetrieval(
0,
NULL))
printf("Uninstall cancel function failed!\n");
}
}
if ( pszObjectOid == NULL )
{
pcba = (PCRYPT_BLOB_ARRAY)pv;
for ( cCount = 0; cCount < pcba->cBlob; cCount++ )
{
PBYTE pb = pcba->rgBlob[cCount].pbData;
DWORD cb = pcba->rgBlob[cCount].cbData;
printf( "\nObject#%d ", cCount+1);
if (dwRetrievalFlags & CRYPT_LDAP_INSERT_ENTRY_ATTRIBUTE)
{
DWORD cbPrefix;
LPCSTR pszIndex;
LPCSTR pszAttr;
pszIndex = (LPCSTR) pb;
cbPrefix = strlen(pszIndex) + 1;
pb += cbPrefix;
cb -= cbPrefix;
pszAttr = (LPCSTR) pb;
cbPrefix = strlen(pszAttr) + 1;
pb += cbPrefix;
cb -= cbPrefix;
printf("[%s, %s] ", pszIndex, pszAttr);
}
printf( "- Length=0x%lx\n", cb );
PrintBytes(
"",
pb,
cb
);
}
CryptMemFree( pv );
}
else if ( pszObjectOid == CONTEXT_OID_CERTIFICATE )
{
if ( !( dwRetrievalFlags & CRYPT_RETRIEVE_MULTIPLE_OBJECTS ) )
{
DisplayCert( (PCCERT_CONTEXT)pv, dwDisplayFlags );
if ( fGetObjectUrl == TRUE )
{
#if 1
DWORD cbUrlArray;
if ( CryptGetObjectUrl(
URL_OID_CERTIFICATE_CRL_DIST_POINT,
pv,
0,
NULL,
&cbUrlArray,
NULL,
NULL,
NULL
) == FALSE )
{
printf("GetObjectUrl failed %lx\n", GetLastError());
}
else
{
printf("cbUrlArray = %ld\n", cbUrlArray);
}
#else
DWORD cCount;
LARGE_INTEGER TickCount1;
LARGE_INTEGER TickCount2;
LARGE_INTEGER TickCount;
CRYPT_ORIGIN_IDENTIFIER OriginIdentifier;
#define NUM_ITER 1000000
GetSystemTimeAsFileTime( (LPFILETIME)&TickCount1 );
for ( cCount = 0; cCount < NUM_ITER; cCount++ )
{
if ( memcmp( Foo, Bar, 100 ) != 0 )
{
Foo[0] = 1;
Bar[0] = 1;
}
if ( memcmp( Foo, Bar, 200 ) != 0 )
{
Foo[0] = 1;
Bar[0] = 1;
}
if ( memcmp( Foo, Bar, 64 ) != 0 )
{
Foo[0] = 1;
Bar[0] = 1;
}
if ( memcmp( Foo, Bar, 128 ) != 0 )
{
Foo[0] = 1;
Bar[0] = 1;
}
//CertGetOriginIdentifier(
// (PCCERT_CONTEXT)pv,
// (PCCERT_CONTEXT)pv,
// 0,
// OriginIdentifier
// );
}
GetSystemTimeAsFileTime( (LPFILETIME)&TickCount2 );
TickCount.QuadPart = ( TickCount2.QuadPart - TickCount1.QuadPart );
printf("PerIter = %ld ns. Total = %ld s.\n", (((LPFILETIME)&TickCount)->dwLowDateTime / NUM_ITER) * 100, ((LPFILETIME)&TickCount)->dwLowDateTime / 10000000);
#endif
}
CertFreeCertificateContext( (PCCERT_CONTEXT)pv );
}
else
{
if (!fQuiet)
DisplayStore( (HCERTSTORE)pv, dwDisplayFlags );
if (fSave && pszSaveFilename)
SaveStoreEx( (HCERTSTORE)pv, fPKCS7Save, pszSaveFilename);
CertCloseStore( (HCERTSTORE)pv, 0 );
}
}
else if ( pszObjectOid == CONTEXT_OID_CTL )
{
if ( !( dwRetrievalFlags & CRYPT_RETRIEVE_MULTIPLE_OBJECTS ) )
{
DisplayCtl( (PCCTL_CONTEXT)pv, dwDisplayFlags );
CertFreeCTLContext( (PCCTL_CONTEXT)pv );
}
else
{
if (!fQuiet)
DisplayStore( (HCERTSTORE)pv, dwDisplayFlags );
if (fSave && pszSaveFilename)
SaveStoreEx( (HCERTSTORE)pv, fPKCS7Save, pszSaveFilename);
CertCloseStore( (HCERTSTORE)pv, 0 );
}
}
else if ( pszObjectOid == CONTEXT_OID_CRL )
{
if ( !( dwRetrievalFlags & CRYPT_RETRIEVE_MULTIPLE_OBJECTS ) )
{
DisplayCrl( (PCCRL_CONTEXT)pv, dwDisplayFlags );
CertFreeCRLContext( (PCCRL_CONTEXT)pv );
}
else
{
if (!fQuiet)
DisplayStore( (HCERTSTORE)pv, dwDisplayFlags );
if (fSave && pszSaveFilename)
SaveStoreEx( (HCERTSTORE)pv, fPKCS7Save, pszSaveFilename);
CertCloseStore( (HCERTSTORE)pv, 0 );
}
}
else if ( ( pszObjectOid == CONTEXT_OID_CAPI2_ANY ) ||
( pszObjectOid == CONTEXT_OID_PKCS7 ) )
{
if (!fQuiet)
DisplayStore( (HCERTSTORE)pv, dwDisplayFlags );
if (fSave && pszSaveFilename)
SaveStoreEx( (HCERTSTORE)pv, fPKCS7Save, pszSaveFilename);
CertCloseStore( (HCERTSTORE)pv, 0 );
}
if (pwszUsername)
TestFree(pwszUsername);
if (pwszPassword)
TestFree(pwszPassword);
return( 0 );
#endif
}