program TestCrSysPKI;
{
Some tests for the Delphi/FreePascal interface to CryptoSys PKI
$Id: TestCrSysPKI.pas $
Copyright (C) 2010-23 David Ireland, DI Management Services Pty Limited.
All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net>
Provided as is with no warranties. Use at your own risk.
Last updated:
$Date: 2023-10-12 07:23 $
$Revision: 22.0.0 $
}
{$APPTYPE CONSOLE}
{$mode Delphi}
uses
SysUtils, diCrPKI;
const
CRLF = #13 + #10;
// UTILITIES WE USE IN THE TESTS...
Procedure pr_hexbytes(msg : String; arrbytes : Array of Byte);
// Displays an array of bytes as a hex string
var
i : Integer;
nbytes : Integer;
begin
Write(msg);
nbytes := Length(arrbytes);
For i := 0 to (nbytes - 1) do
Write(IntToHex(arrbytes[i], 2));
WriteLn;
end;
Procedure pr_text_file(fname: AnsiString);
var
myFile : TextFile;
s : AnsiString;
begin
AssignFile(myFile, fname);
Reset(myFile);
while not (eof(myFile)) do
begin
Readln(myFile, s);
writeln(s);
end;
CloseFile(myFile);
end;
// DO THE TESTS TO CALL CRYPTOSYS PKI FUNCTIONS
Procedure do_tests;
var
ret, nchars, nbytes : Integer;
buf : AnsiString;
ch : Char;
n, i : Integer;
arrbytes : Array of Byte;
fname, keyfile, pubkeyfile, certfile, dumpfile : AnsiString;
password : AnsiString;
nbits : Integer;
begin
WriteLn('Running ' + ExtractFileName(ParamStr(0)) + ' at ' + DateTimeToStr(Now));
WriteLn(CRLF + 'GENERAL:');
WriteLn('Interrogate the core diCrPKI DLL:');
WriteLn('PKI_Version='+(IntToStr(PKI_Version(NIL, NIL))));
nchars := PKI_CompileTime(NIL, 0);
WriteLn('PKI_CompileTime returns nchars=' + IntToStr(nchars));
buf := AnsiString(StringOfChar(#0,nchars));
nchars := PKI_CompileTime(Pointer(buf), nchars);
WriteLn('PKI_CompileTime=' + buf);
Assert (nchars > 0);
ch := Chr(PKI_LicenceType(0));
WriteLn('PKI_LicenceType='+ ch);
nchars := PKI_ModuleName(NIL, 0, 0);
WriteLn('PKI_ModuleName returns nchars=' + IntToStr(nchars));
buf := AnsiString(StringOfChar(#0, nchars));
PKI_ModuleName(Pointer(buf), nchars, 0);
WriteLn('PKI_ModuleName=' + Trim(string(buf)));
WriteLn(CRLF + 'GENERATE SOME RANDOM INTEGERS IN RANGE [0,MaxInt]:');
for i := 1 to 5 do
begin
n := RNG_Number(0, MaxInt);
WriteLn('RNG_Number returns ' + IntToStr(n));
end;
WriteLn(CRLF + 'GENERATE SOME RANDOM BYTE ARRAYS:');
nbytes := 16;
SetLength(arrbytes, nbytes);
for i := 1 to 5 do
begin
ret := RNG_Bytes(Pointer(arrbytes), nbytes, NIL, 0);
//WriteLn('RNG_Bytes returns ' + IntToStr(ret) + ' (expected 0)');
Assert(0 = ret);
pr_hexbytes('RNG=', arrbytes);
end;
// Define USE_PROMPT to make this work
{$IfDef USE_PROMPT}
WriteLn(CRLF + 'GENERATE RANDOM BYTES WITH PROMPT:');
nbytes := 24;
SetLength(arrbytes, nbytes);
// Use default prompt
ret := RNG_BytesWithPrompt(Pointer(arrbytes), nbytes, '', 0);
Assert(0 = ret);
pr_hexbytes('RNG=', arrbytes);
{$EndIf}
WriteLn(CRLF + 'GENERATE A PAIR OF RSA KEYS:');
nbits := 1024; // NB Not very secure length
keyfile := 'myprivate.key';
pubkeyfile := 'mypubkey.dat';
password := 'password'; // High security here!!
WriteLn('About to generate key of ' + IntToStr(nbits) + ' bits...');
ret := RSA_MakeKeysXtd(pubkeyfile, keyfile, password, nbits,
PKI_RSAEXP_EQ_65537, '', PKI_PBE_PBKDF2_AES128);
WriteLn('RSA_MakeKeys returns ' + IntToStr(ret) + ' (expected 0)');
WriteLn(CRLF + 'Check we can read these new key files...');
// Private key file
fname := keyfile;
nchars := RSA_ReadAnyPrivateKey(NIL, 0, fname, password, 0);
WriteLn('RSA_ReadAnyPrivateKey returns ' + IntToStr(nchars) + ' (expected +ve)');
Assert(nchars > 0);
buf := AnsiString(StringOfChar(#0, nchars));
nchars := RSA_ReadAnyPrivateKey(Pointer(buf), nchars, fname, password, 0);
Assert(nchars > 0);
n := RSA_KeyBits(buf);
WriteLn('Private key length=' + IntToStr(n));
n := RSA_KeyHashCode(buf);
WriteLn('KeyHashCode = 0x' + IntToHex(n, 8));
// Public key file
fname := pubkeyfile;
nchars := RSA_ReadAnyPublicKey(NIL, 0, fname, 0);
WriteLn('RSA_ReadAnyPublicKey returns ' + IntToStr(nchars) + ' (expected +ve)');
Assert(nchars > 0);
buf := AnsiString(StringOfChar(#0, nchars));
nchars := RSA_ReadAnyPublicKey(Pointer(buf), nchars, fname, 0);
Assert(nchars > 0);
n := RSA_KeyBits(buf);
WriteLn('Public key length=' + IntToStr(n));
n := RSA_KeyHashCode(buf);
WriteLn('KeyHashCode = 0x' + IntToHex(n, 8));
WriteLn(CRLF + 'MAKE A SELF-SIGNED X.509 CERTIFICATE...');
certfile := 'mycertca.cer';
ret := X509_MakeCertSelf(certfile, keyfile, $101, $5, 'c=AU;CN=me;O=me@here.com',
'rfc822Name=me@here.com;subjectKeyIdentifier=fedcba9876543210',
PKI_X509_KEYUSAGE_KEYCERTSIGN or PKI_X509_KEYUSAGE_CRLSIGN or PKI_X509_KEYUSAGE_DIGITALSIGNATURE,
'password', PKI_SIG_SHA256RSA);
WriteLn('X509_MakeCertSelf returns ' + IntToStr(ret) + ' (expected 0)');
WriteLn(CRLF + 'DUMP DETAILS OF X.509 CERTIFICATE...');
dumpfile := 'x509dump.txt';
ret := X509_TextDump(dumpfile, certfile, 0);
WriteLn('X509_TextDump returns ' + IntToStr(ret) + ' (expected 0)');
// Write out the text file we just created
pr_text_file(dumpfile);
WriteLn(CRLF+'ALL DONE.');
end;
// MAIN PROCEDURE
begin
try
do_tests;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.