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.
409 lines
10 KiB
409 lines
10 KiB
//+-----------------------------------------------------------------------
|
|
//
|
|
// 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 -user user -domain domain -type accounttype \n",
|
|
argv[0]);
|
|
return;
|
|
}
|
|
|