windows-nt/Source/XPSP1/NT/ds/security/common/cryptdll/utest/cryptest.cxx

410 lines
9.8 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation 1992 - 1992
//
// File: cryptest.cxx
//
// Contents: test program to test encryption functions
//
//
// History: 07-Oct-1996 MikeSw Created
//
//------------------------------------------------------------------------
extern "C"
{
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#define SECURITY_WIN32
#include <security.h>
#include <cryptdll.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <kerbcomm.h>
#include <align.h>
#include "md5.h"
}
typedef enum _CRYPT_ACTIONS {
HashPassword,
EncryptData,
ChecksumData,
EnumTypes,
NoAction
} CRYPT_ACTIONS;
VOID
DoMd5(
PUCHAR Buffer,
ULONG BufferLength
)
{
MD5_CTX Md5Context;
MD5Init(&Md5Context);
MD5Update(&Md5Context, Buffer, BufferLength);
MD5Final(&Md5Context);
}
void _cdecl
main(int argc, char *argv[])
{
NTSTATUS Status;
UNICODE_STRING Password;
UNICODE_STRING User;
UNICODE_STRING Domain;
UNICODE_STRING Salt;
ULONG CryptType = 0;
ULONG HashType = 0;
ULONG SumType = 0;
WCHAR PasswordBuffer[100];
WCHAR UserBuffer[100];
WCHAR DomainBuffer[100];
KERB_ACCOUNT_TYPE AccountType = UserAccount;
CRYPT_ACTIONS Command = NoAction;
int Index;
ULONG uI;
KERB_ENCRYPTION_KEY Key;
KERBERR KerbErr;
ULONG BlockSize;
ULONG Overhead;
ULONG BufferLength;
ULONG ReqBufferLength;
UCHAR OriginalBuffer[1000];
PUCHAR EncryptedBuffer = NULL;
PUCHAR DecryptedBuffer = NULL;
PCRYPTO_SYSTEM Crypto;
PCRYPT_STATE_BUFFER StateBuffer = NULL;
Index = 1;
while (Index < argc)
{
if (_stricmp(argv[Index],"-hash") == 0)
{
Command = HashPassword;
if (argc < Index+1)
{
goto Cleanup;
}
sscanf(argv[++Index],"%d",&HashType);
}
else if (_stricmp(argv[Index],"-pass") == 0)
{
if (argc < Index + 1)
{
goto Cleanup;
}
mbstowcs(PasswordBuffer,argv[++Index],100);
RtlInitUnicodeString(
&Password,
PasswordBuffer
);
}
else if (_stricmp(argv[Index],"-user") == 0)
{
if (argc < Index + 1)
{
goto Cleanup;
}
mbstowcs(UserBuffer,argv[++Index],100);
RtlInitUnicodeString(
&User,
UserBuffer
);
}
else if (_stricmp(argv[Index],"-domain") == 0)
{
if (argc < Index + 1)
{
goto Cleanup;
}
mbstowcs(DomainBuffer,argv[++Index],100);
RtlInitUnicodeString(
&Domain,
DomainBuffer
);
}
else if (_stricmp(argv[Index],"-type") == 0)
{
if (argc < Index + 1)
{
goto Cleanup;
}
if (_stricmp(argv[Index+1],"user") == 0)
{
AccountType = UserAccount;
}
else if (_stricmp(argv[Index+1],"machine") == 0)
{
AccountType = MachineAccount;
}
else if (_stricmp(argv[Index+1],"domain") == 0)
{
AccountType = DomainTrustAccount;
}
else
{
printf("Illegal account type: %s\n",argv[Index+1]);
goto Cleanup;
}
Index++;
}
else if (_stricmp(argv[Index],"-crypt") == 0)
{
Command = EncryptData;
if (argc < Index + 1)
{
goto Cleanup;
}
sscanf(argv[++Index],"%d",&CryptType);
}
else if (_stricmp(argv[Index],"-sum") == 0)
{
Command = ChecksumData;
if (argc < Index + 1)
{
goto Cleanup;
}
sscanf(argv[++Index],"%d",&SumType);
}
else if (_stricmp(argv[Index],"-enum") == 0)
{
Command = EnumTypes;
}
else
{
goto Cleanup;
}
Index++;
}
if (Command == NoAction)
{
goto Cleanup;
}
switch(Command)
{
case EnumTypes:
break;
case HashPassword:
KerbErr = KerbBuildKeySalt(
&Domain,
&User,
AccountType,
&Salt
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to build key salt: 0x%x\n",KerbErr);
goto Cleanup;
}
printf("KeySalt = %wZ\n",&Salt);
KerbErr = KerbHashPasswordEx(
&Password,
&Salt,
HashType,
&Key
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to hash password: 0x%x\n",KerbErr);
goto Exit;
}
printf("Hash: ");
for (uI = 0; uI < Key.keyvalue.length ; uI++ )
{
printf("%0.2x ",Key.keyvalue.value[uI]);
}
printf("\n");
break;
case EncryptData:
//
// First hash the password
//
KerbErr= KerbHashPassword(
&Password,
CryptType,
&Key
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to hash password: %0x%x\n",KerbErr);
goto Exit;
}
KerbErr = KerbGetEncryptionOverhead(
CryptType,
&Overhead,
&BlockSize
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to get enc overhead: 0x%x\n",KerbErr);
goto Exit;
}
BufferLength = sizeof(OriginalBuffer);
memset(OriginalBuffer,'A',BufferLength);
#ifdef notdef
KerbErr = KerbRandomFill(
OriginalBuffer,
BufferLength
);
if (!KERB_SUCCESS(KerbErr))
{
printf("Failed to init random buffer: 0x%x\n",KerbErr);
goto Exit;
}
#endif
ReqBufferLength = ROUND_UP_COUNT(BufferLength + Overhead, BlockSize);
EncryptedBuffer = (PUCHAR) LocalAlloc(LMEM_ZEROINIT, ReqBufferLength);
if (EncryptedBuffer == NULL)
{
printf("Failed to allocate 0x%x bytes: %d\n",ReqBufferLength, GetLastError());
goto Exit;
}
Status = CDLocateCSystem(
CryptType,
&Crypto
);
if (!NT_SUCCESS(Status))
{
printf("Failed to locate crypt system 0x%x: 0x%x\n",CryptType,Status);
goto Exit;
}
Status = Crypto->Initialize(
Key.keyvalue.value,
(ULONG) Key.keyvalue.length,
0, // no options
&StateBuffer
);
if (!NT_SUCCESS(Status))
{
printf("failed to initialize crypto system: 0x%x\n",Status);
goto Exit;
}
Status = Crypto->Encrypt(
StateBuffer,
OriginalBuffer,
BufferLength,
EncryptedBuffer,
&ReqBufferLength
);
if (!NT_SUCCESS(Status))
{
printf("Failed to encrypt data: 0x%x\n",Status);
goto Exit;
}
Status = Crypto->Discard(&StateBuffer);
if (!NT_SUCCESS(Status))
{
printf("Failed to discard state buffer: 0x%x\n",Status);
goto Exit;
}
//
// Now turn around and decrypt it.
//
DecryptedBuffer = (PUCHAR) LocalAlloc(LMEM_ZEROINIT, ReqBufferLength);
if (EncryptedBuffer == NULL)
{
printf("Failed to allocate 0x%x bytes: %d\n",ReqBufferLength, GetLastError());
goto Exit;
}
Status = Crypto->Initialize(
Key.keyvalue.value,
(ULONG) Key.keyvalue.length,
0, // no options
&StateBuffer
);
if (!NT_SUCCESS(Status))
{
printf("failed to initialize crypto system: 0x%x\n",Status);
goto Exit;
}
Status = Crypto->Decrypt(
StateBuffer,
EncryptedBuffer,
ReqBufferLength,
DecryptedBuffer,
&ReqBufferLength
);
if (!NT_SUCCESS(Status))
{
printf("Failed to decrypt data: 0x%x\n",Status);
goto Exit;
}
Status = Crypto->Discard(&StateBuffer);
if (!NT_SUCCESS(Status))
{
printf("Failed to discard state buffer: 0x%x\n",Status);
goto Exit;
}
//
// Now compare
//
if (!RtlEqualMemory(
OriginalBuffer,
DecryptedBuffer,
BufferLength
))
{
printf("Buffers don't match!\n");
}
else
{
printf("Encryption/decryption succeeded!\n");
}
break;
case ChecksumData:
BufferLength = sizeof(OriginalBuffer);
memset(OriginalBuffer,'A',BufferLength);
DoMd5(OriginalBuffer,BufferLength);
}
Exit:
return;
Cleanup:
printf("Usage: %s { -crypt cryptalg -sum sumtype -hash cryptalg -enum } -pass password\n",
argv[0]);
return;
}