| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- {
- $Project$
- $Workfile$
- $Revision$
- $DateUTC$
- $Id$
- This file is part of the Indy (Internet Direct) project, and is offered
- under the dual-licensing agreement described on the Indy website.
- (http://www.indyproject.org/)
- Copyright:
- (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
- }
- {
- $Log$
- }
- {
- Rev 1.4 5/12/2003 12:30:58 AM GGrieve
- Get compiling again with DotNet Changes
- Rev 1.3 10/12/2003 1:49:26 PM BGooijen
- Changed comment of last checkin
- Rev 1.2 10/12/2003 1:43:24 PM BGooijen
- Changed IdCompilerDefines.inc to Core\IdCompilerDefines.inc
- Rev 1.0 11/14/2002 02:13:56 PM JPMugaas
- }
- unit IdBlockCipherIntercept;
- {
- UnitName: IdBlockCipherIntercept
- Author: Andrew P.Rybin [[email protected]]
- Creation: 27.02.2002
- Version: 0.9.0b
- Purpose: Secure communications
- }
- interface
- {$i IdCompilerDefines.inc}
- uses
- Classes,
- IdGlobal,
- IdException,
- IdResourceStringsProtocols,
- IdIntercept;
- const
- IdBlockCipherBlockSizeDefault = 16;
- IdBlockCipherBlockSizeMax = 256;
- // why 256? not any block ciphers that can - or should - be used beyond this
- // length. You can extend this if you like. But the longer it is, the
- // more network traffic is wasted
- //256, as currently the last byte of the block is used to store the block size
- type
- TIdBlockCipherIntercept = class;
- // OnSend and OnRecieve Events will always be called with a blockSize Data
- TIdBlockCipherIntercept = class(TIdConnectionIntercept)
- protected
- FBlockSize: Integer;
- FIncoming : TIdBytes;
- procedure Decrypt (var VData : TIdBytes); virtual;
- procedure Encrypt (var VData : TIdBytes); virtual;
- procedure SetBlockSize(const Value: Integer);
- public
- constructor Create(AOwner: TComponent); override;
- procedure Receive(var VBuffer: TIdBytes); override; //Decrypt
- procedure Send(var VBuffer: TIdBytes); override; //Encrypt
- procedure CopySettingsFrom (ASrcBlockCipherIntercept: TIdBlockCipherIntercept); // warning: copies Data too
- published
- property BlockSize: Integer read FBlockSize write SetBlockSize default IdBlockCipherBlockSizeDefault;
- end;
- TIdServerBlockCipherIntercept = class(TIdServerIntercept)
- protected
- FBlockSize: Integer;
- public
- constructor Create(AOwner: TComponent); override;
- procedure Init; override;
- function Accept(AConnection: TComponent): TIdConnectionIntercept; override;
- published
- property BlockSize: Integer read FBlockSize write FBlockSize default IdBlockCipherBlockSizeDefault;
- end;
- EIdBlockCipherInterceptException = EIdException; {block length}
- implementation
- uses
- IdResourceStrings,
- SysUtils;
- { TIdBlockCipherIntercept }
- constructor TIdBlockCipherIntercept.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FBlockSize := IdBlockCipherBlockSizeDefault;
- SetLength(FIncoming, 0);
- end;
- //const
- // bitLongTail = $80; //future: for IdBlockCipherBlockSizeMax>256
- procedure TIdBlockCipherIntercept.Encrypt(var VData : TIdBytes);
- begin
- if Assigned(FOnSend) then begin
- FOnSend(Self, VData);
- end;//ex: EncryptAES(LTempIn, ExpandedKey, LTempOut);
- end;
- procedure TIdBlockCipherIntercept.Decrypt(var VData : TIdBytes);
- Begin
- if Assigned(FOnReceive) then begin
- FOnReceive(Self, VData);
- end;//ex: DecryptAES(LTempIn, ExpandedKey, LTempOut);
- end;
- procedure TIdBlockCipherIntercept.Send(var VBuffer: TIdBytes);
- var
- LSrc, LBlock : TIdBytes;
- LSize, LCount, LMaxDataSize: Integer;
- LCompleteBlocks, LRemaining: Integer;
- begin
- LSrc := nil; // keep the compiler happy
- LSize := Length(VBuffer);
- if LSize > 0 then begin
- LSrc := VBuffer;
- LMaxDataSize := FBlockSize - 1;
- SetLength(VBuffer, ((LSize + LMaxDataSize - 1) div LMaxDataSize) * FBlockSize);
- SetLength(LBlock, FBlockSize);
- LCompleteBlocks := LSize div LMaxDataSize;
- LRemaining := LSize mod LMaxDataSize;
- //process all complete blocks
- for LCount := 0 to LCompleteBlocks-1 do
- begin
- CopyTIdBytes(LSrc, LCount * LMaxDataSize, LBlock, 0, LMaxDataSize);
- LBlock[LMaxDataSize] := LMaxDataSize;
- Encrypt(LBlock);
- CopyTIdBytes(LBlock, 0, VBuffer, LCount * FBlockSize, FBlockSize);
- end;
- //process the possible remaining bytes, ie less than a full block
- if LRemaining > 0 then
- begin
- CopyTIdBytes(LSrc, LSize - LRemaining, LBlock, 0, LRemaining);
- LBlock[LMaxDataSize] := LRemaining;
- Encrypt(LBlock);
- CopyTIdBytes(LBlock, 0, VBuffer, Length(VBuffer) - FBlockSize, FBlockSize);
- end;
- end;
- // let the next Intercept in the chain encode its data next
- // RLebeau: DO NOT call inherited! It will trigger the OnSend event
- // again with the entire altered buffer as input, which can cause user
- // code to re-encrypt the already-encrypted data. We do not want that
- // here! Just call the next Intercept directly...
- //inherited Send(VBuffer);
- if Intercept <> nil then begin
- Intercept.Send(VBuffer);
- end;
- end;
- procedure TIdBlockCipherIntercept.Receive(var VBuffer: TIdBytes);
- var
- LBlock : TIdBytes;
- LSize, LCount, LPos, LMaxDataSize, LCompleteBlocks: Integer;
- LRemaining: Integer;
- begin
- // let the next Intercept in the chain decode its data first
- // RLebeau: DO NOT call inherited! It will trigger the OnReceive event
- // with the entire decoded buffer as input, which can cause user
- // code to decrypt data prematurely/incorrectly. We do not want that
- // here! Just call the next Intercept directly...
- //inherited Receive(VBuffer);
- if Intercept <> nil then begin
- Intercept.Receive(VBuffer);
- end;
- LPos := 0;
- AppendBytes(FIncoming, VBuffer);
- LSize := Length(FIncoming);
- if LSize >= FBlockSize then
- begin
- // the length of ABuffer when we have finished is currently unknown, but must be less than
- // the length of FIncoming. We will reserve this much, then reallocate at the end
- SetLength(VBuffer, LSize);
- SetLength(LBlock, FBlockSize);
- LMaxDataSize := FBlockSize - 1;
- LCompleteBlocks := LSize div FBlockSize;
- LRemaining := LSize mod FBlockSize;
- for LCount := 0 to LCompleteBlocks-1 do
- begin
- CopyTIdBytes(FIncoming, LCount * FBlockSize, LBlock, 0, FBlockSize);
- Decrypt(LBlock);
- if (LBlock[LMaxDataSize] = 0) or (LBlock[LMaxDataSize] >= FBlockSize) then begin
- raise EIdBlockCipherInterceptException.CreateFmt(RSBlockIncorrectLength, [LBlock[LMaxDataSize]]);
- end;
- CopyTIdBytes(LBlock, 0, VBuffer, LPos, LBlock[LMaxDataSize]);
- Inc(LPos, LBlock[LMaxDataSize]);
- end;
- if LRemaining > 0 then begin
- CopyTIdBytes(FIncoming, LSize - LRemaining, FIncoming, 0, LRemaining);
- end;
- SetLength(FIncoming, LRemaining);
- end;
- SetLength(VBuffer, LPos);
- end;
- procedure TIdBlockCipherIntercept.CopySettingsFrom(ASrcBlockCipherIntercept: TIdBlockCipherIntercept);
- Begin
- FBlockSize := ASrcBlockCipherIntercept.FBlockSize;
- FDataObject := ASrcBlockCipherIntercept.FDataObject;
- FDataValue := ASrcBlockCipherIntercept.FDataValue;
- FOnConnect := ASrcBlockCipherIntercept.FOnConnect;
- FOnDisconnect:= ASrcBlockCipherIntercept.FOnDisconnect;
- FOnReceive := ASrcBlockCipherIntercept.FOnReceive;
- FOnSend := ASrcBlockCipherIntercept.FOnSend;
- end;
- procedure TIdBlockCipherIntercept.SetBlockSize(const Value: Integer);
- Begin
- if (Value > 0) and (Value <= IdBlockCipherBlockSizeMax) then begin
- FBlockSize := Value;
- end;
- end;
- { TIdServerBlockCipherIntercept }
- constructor TIdServerBlockCipherIntercept.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FBlockSize := IdBlockCipherBlockSizeDefault;
- end;
- procedure TIdServerBlockCipherIntercept.Init;
- begin
- end;
- function TIdServerBlockCipherIntercept.Accept(AConnection: TComponent): TIdConnectionIntercept;
- begin
- Result := TIdBlockCipherIntercept.Create(nil);
- TIdBlockCipherIntercept(Result).BlockSize := BlockSize;
- end;
- end.
|