{*****************************************************************************
The DEC team (see file NOTICE.txt) licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. A copy of this licence is found in the root directory of
this project in the file LICENCE.txt or alternatively at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*****************************************************************************}
unit MainForm;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts,
FMX.StdCtrls, FMX.ListBox, FMX.Controls.Presentation, FMX.Edit, System.Rtti,
{$IF RTLVersion < 31}
{$ELSE}
FMX.Grid.Style,
{$ENDIF}
FMX.Grid, FMX.ScrollBox, DECCipherBase, DECFormatBase;
type
///
/// Form of the cross platform FMX Cipher demo
///
TFormMain = class(TForm)
VertScrollBox1: TVertScrollBox;
LayoutTop: TLayout;
Label2: TLabel;
ComboBoxCipherAlgorithm: TComboBox;
Label5: TLabel;
ComboBoxInputFormatting: TComboBox;
Label6: TLabel;
ComboBoxOutputFormatting: TComboBox;
Label1: TLabel;
EditKey: TEdit;
Label3: TLabel;
EditInitVector: TEdit;
Label4: TLabel;
EditFiller: TEdit;
Label7: TLabel;
ComboBoxChainingMethod: TComboBox;
CheckBoxLiveCalc: TCheckBox;
Label8: TLabel;
StringGridContext: TStringGrid;
StringColumn1: TStringColumn;
StringColumn2: TStringColumn;
Label9: TLabel;
Label10: TLabel;
EditPlainText: TEdit;
EditCipherText: TEdit;
ButtonEncrypt: TButton;
ButtonDecrypt: TButton;
LabelVersion: TLabel;
procedure FormResize(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ComboBoxCipherAlgorithmChange(Sender: TObject);
procedure ButtonEncryptClick(Sender: TObject);
procedure EditPlainTextChangeTracking(Sender: TObject);
procedure ButtonDecryptClick(Sender: TObject);
private
procedure InitFormatCombos;
procedure InitCipherCombo;
procedure InitCipherModes;
procedure ShowErrorMessage(ErrorMsg: string);
function GetSelectedCipherMode: TCipherMode;
function GetSettings(var InputFormatting : TDECFormatClass;
var OutputFormatting : TDECFormatClass): Boolean;
function GetCipherAlgorithm(var Cipher: TDECCipher): Boolean;
public
end;
var
FormMain: TFormMain;
implementation
uses
System.TypInfo, Generics.Collections, FMX.Platform,
DECBaseClass, DECFormat, DECCipherModes,
DECCipherFormats, DECCiphers, DECUtil
{$IFDEF Android}
,
Androidapi.JNI.GraphicsContentViewText,
Androidapi.Helpers,
Androidapi.JNI.App
{$ENDIF};
{$R *.fmx}
procedure TFormMain.ButtonDecryptClick(Sender: TObject);
var
Cipher : TDECCipher;
InputFormatting : TDECFormatClass;
OutputFormatting : TDECFormatClass;
InputBuffer : TBytes;
OutputBuffer : TBytes;
begin
if not GetSettings(InputFormatting, OutputFormatting) then
exit;
if ComboBoxCipherAlgorithm.ItemIndex >= 0 then
begin
if not GetCipherAlgorithm(Cipher) then
exit;
try
InputBuffer := System.SysUtils.BytesOf(EditCipherText.Text);
if InputFormatting.IsValid(InputBuffer) then
begin
OutputBuffer := (Cipher as TDECFormattedCipher).DecodeBytes(InputFormatting.Decode(InputBuffer));
EditPlainText.Text := string(DECUtil.BytesToRawString(OutputFormatting.Encode(OutputBuffer)));
end
else
ShowErrorMessage('Input has wrong format');
finally
Cipher.Free;
end;
end
else
ShowErrorMessage('No cipher algorithm selected');
end;
procedure TFormMain.ButtonEncryptClick(Sender: TObject);
var
Cipher : TDECCipher;
InputFormatting : TDECFormatClass;
OutputFormatting : TDECFormatClass;
InputBuffer : TBytes;
OutputBuffer : TBytes;
begin
if not GetSettings(InputFormatting, OutputFormatting) then
exit;
if ComboBoxCipherAlgorithm.ItemIndex >= 0 then
begin
if not GetCipherAlgorithm(Cipher) then
exit;
try
InputBuffer := System.SysUtils.BytesOf(EditPlainText.Text);
if InputFormatting.IsValid(InputBuffer) then
begin
OutputBuffer := (Cipher as TDECFormattedCipher).EncodeBytes(InputFormatting.Decode(InputBuffer));
EditCipherText.Text := string(DECUtil.BytesToRawString(OutputFormatting.Encode(OutputBuffer)));
end
else
ShowErrorMessage('Input has wrong format');
finally
Cipher.Free;
end;
end
else
ShowErrorMessage('No cipher algorithm selected');
end;
function TFormMain.GetSettings(var InputFormatting : TDECFormatClass;
var OutputFormatting : TDECFormatClass): Boolean;
begin
result := false;
if ComboBoxInputFormatting.ItemIndex >= 0 then
begin
// Find the class type of the selected formatting class and create an instance of it
InputFormatting := TDECFormat.ClassByName(
ComboBoxInputFormatting.Items[ComboBoxInputFormatting.ItemIndex]);
end
else
begin
ShowErrorMessage('No input format selected');
exit;
end;
if ComboBoxOutputFormatting.ItemIndex >= 0 then
begin
// Find the class type of the selected formatting class and create an instance of it
OutputFormatting := TDECFormat.ClassByName(
ComboBoxOutputFormatting.Items[ComboBoxOutputFormatting.ItemIndex]);
end
else
begin
ShowErrorMessage('No output format selected');
exit;
end;
if EditKey.Text.IsEmpty or EditInitVector.Text.IsEmpty or EditFiller.Text.IsEmpty then
begin
ShowErrorMessage('No key, initialization vector or filler byte given');
exit;
end;
result := true;
end;
function TFormMain.GetCipherAlgorithm(var Cipher : TDECCipher):Boolean;
begin
result := false;
// Find the class type of the selected cipher class and create an instance of it
Cipher := TDECCipher.ClassByName(
ComboBoxCipherAlgorithm.Items[ComboBoxCipherAlgorithm.ItemIndex]).Create;
if TFormat_HEX.IsValid(RawByteString(EditInitVector.Text)) and
TFormat_HEX.IsValid(RawByteString(EditFiller.Text)) then
begin
Cipher.Init(RawByteString(EditKey.Text),
TFormat_HEX.Decode(RawByteString(EditInitVector.Text)),
StrToInt('0x' + EditFiller.Text));
Cipher.Mode := GetSelectedCipherMode;
end
else
begin
ShowErrorMessage('Init vector or filler byte not given in hexadecimal representation');
exit;
end;
result := true;
end;
function TFormMain.GetSelectedCipherMode:TCipherMode;
begin
// Determine selected block chaining method via RTTI (runtime type information)
result := TCipherMode(System.TypInfo.GetEnumValue(
TypeInfo(TCipherMode),
ComboBoxChainingMethod.Items[ComboBoxChainingMethod.ItemIndex]));
end;
procedure TFormMain.ShowErrorMessage(ErrorMsg: string);
{$IF RTLVersion > 30}
var
AsyncDlg : IFMXDialogServiceASync;
{$ENDIF}
begin
{$IF RTLVersion > 30}
if TPlatformServices.Current.SupportsPlatformService(IFMXDialogServiceAsync,
IInterface(AsyncDlg)) then
AsyncDlg.MessageDialogAsync(Translate(ErrorMsg),
TMsgDlgType.mtError, [TMsgDlgBtn.mbOk], TMsgDlgBtn.mbOk, 0,
procedure (const AResult: TModalResult)
begin
end);
{$ELSE}
MessageDlg(Translate(ErrorMsg),
TMsgDlgType.mtError, [TMsgDlgBtn.mbOk], 0);
{$ENDIF}
end;
procedure TFormMain.ComboBoxCipherAlgorithmChange(Sender: TObject);
var
Context : TCipherContext;
begin
Context := TDECCipher.ClassByName(
ComboBoxCipherAlgorithm.Items[ComboBoxCipherAlgorithm.ItemIndex]).Context;
StringGridContext.RowCount := 7;
StringGridContext.Cells[0, 0] := 'Key size (bit)';
StringGridContext.Cells[0, 1] := 'Block size (bit)';
StringGridContext.Cells[0, 2] := 'Buffer size (bit)';
StringGridContext.Cells[0, 3] := 'User size (bit)';
StringGridContext.Cells[0, 4] := 'User save';
StringGridContext.Cells[0, 5] := 'Cipher mode';
StringGridContext.Cells[0, 6] := 'Cipher key';
StringGridContext.Cells[1, 0] := IntToStr(Context.KeySize*8);
StringGridContext.Cells[1, 1] := IntToStr(Context.BlockSize*8);
StringGridContext.Cells[1, 2] := IntToStr(Context.BufferSize*8);
StringGridContext.Cells[1, 3] := IntToStr(Context.AdditionalBufferSize*8);
StringGridContext.Cells[1, 4] := BoolToStr(Context.NeedsAdditionalBufferBackup, true);
if ctBlock in Context.CipherType then
StringGridContext.Cells[1, 5] := 'block cipher'
else
StringGridContext.Cells[1, 5] := 'stream cipher';
if ctSymmetric in Context.CipherType then
StringGridContext.Cells[1, 6] := 'symmetric'
else
StringGridContext.Cells[1, 6] := 'asymmetric';
end;
procedure TFormMain.EditPlainTextChangeTracking(Sender: TObject);
begin
if CheckBoxLiveCalc.IsChecked then
ButtonEncryptClick(self)
end;
procedure TFormMain.FormCreate(Sender: TObject);
var
AppService : IFMXApplicationService;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationService,
IInterface(AppService)) then
LabelVersion.Text := format(LabelVersion.Text, [AppService.AppVersion])
else
LabelVersion.Text := format(LabelVersion.Text, ['']);
InitFormatCombos;
InitCipherCombo;
InitCipherModes;
end;
procedure TFormMain.FormResize(Sender: TObject);
begin
LayoutTop.Width := VertScrollBox1.Width;
end;
procedure TFormMain.InitFormatCombos;
var
MyClass : TPair;
Formats : TStringList;
CopyIdx : Integer;
begin
Formats := TStringList.Create;
try
for MyClass in TDECFormat.ClassList do
Formats.Add(MyClass.Value.ClassName);
Formats.Sort;
ComboBoxInputFormatting.Items.AddStrings(Formats);
ComboBoxOutputFormatting.Items.AddStrings(Formats);
if Formats.Count > 0 then
begin
if Formats.Find('TFormat_Copy', CopyIdx) then
begin
ComboBoxInputFormatting.ItemIndex := CopyIdx;
ComboBoxOutputFormatting.ItemIndex := CopyIdx;
end
else
begin
ComboBoxInputFormatting.ItemIndex := 0;
ComboBoxOutputFormatting.ItemIndex := 0;
end;
end;
finally
Formats.Free;
end;
end;
procedure TFormMain.InitCipherCombo;
var
MyClass : TPair;
Ciphers : TStringList;
begin
Ciphers := TStringList.Create;
try
// Alternatively you can use TDECCipher.ClassList.GetClassList(Ciphers); but
// then it's harder to remove TCipher_Null from the list
for MyClass in TDECCipher.ClassList do
begin
if (MyClass.Value <> TCipher_Null) then
Ciphers.Add(MyClass.Value.ClassName);
end;
Ciphers.Sort;
ComboBoxCipherAlgorithm.Items.AddStrings(Ciphers);
if Ciphers.Count > 0 then
ComboBoxCipherAlgorithm.ItemIndex := 0;
finally
Ciphers.Free;
end;
end;
procedure TFormMain.InitCipherModes;
var
Mode : TCipherMode;
begin
for Mode := low(TCipherMode) to high(TCipherMode) do
begin
ComboBoxChainingMethod.Items.Add(System.TypInfo.GetEnumName(
TypeInfo(TCipherMode),
Integer(Mode)));
end;
if ComboBoxChainingMethod.Items.Count > 0 then
ComboBoxChainingMethod.ItemIndex := 0;
end;
end.