IdBlockCipherIntercept.pas 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. { $HDR$}
  2. {**********************************************************************}
  3. { Unit archived using Team Coherence }
  4. { Team Coherence is Copyright 2002 by Quality Software Components }
  5. { }
  6. { For further information / comments, visit our WEB site at }
  7. { http://www.TeamCoherence.com }
  8. {**********************************************************************}
  9. {}
  10. { $Log: 10083: IdBlockCipherIntercept.pas
  11. {
  12. { Rev 1.0 2002.11.12 10:31:44 PM czhower
  13. }
  14. unit IdBlockCipherIntercept;
  15. {-----------------------------------------------------------------------------
  16. UnitName: IdBlockCipherIntercept
  17. Author: Andrew P.Rybin [[email protected]]
  18. Creation: 27.02.2002
  19. Version: 0.9.0b
  20. Purpose: Secure communications
  21. History:
  22. -----------------------------------------------------------------------------}
  23. {$I IdCompilerDefines.inc}
  24. interface
  25. uses
  26. Classes,
  27. IdIntercept, IdException;
  28. const
  29. IdBlockCipherBlockSizeDefault = 16;
  30. IdBlockCipherBlockSizeMax = 256;
  31. type
  32. TIdBlockCipherIntercept = class;
  33. //OneBlock event
  34. TIdBlockCipherInterceptDataEvent = procedure (ASender: TIdBlockCipherIntercept; ASrcData, ADstData: Pointer) of object;
  35. TIdBlockCipherIntercept = class(TIdConnectionIntercept)
  36. protected
  37. FBlockSize: Integer;
  38. FData: TObject; //commonly password
  39. FRecvStream: TMemoryStream;
  40. FSendStream: TMemoryStream;
  41. //
  42. procedure Decrypt (const ASrcData; var ADstData); virtual;
  43. procedure Encrypt (const ASrcData; var ADstData); virtual;
  44. function GetOnReceive: TIdBlockCipherInterceptDataEvent;
  45. function GetOnSend: TIdBlockCipherInterceptDataEvent;
  46. procedure SetOnReceive(const Value: TIdBlockCipherInterceptDataEvent);
  47. procedure SetOnSend(const Value: TIdBlockCipherInterceptDataEvent);
  48. procedure SetBlockSize(const Value: Integer);
  49. public
  50. constructor Create(AOwner: TComponent); override;
  51. destructor Destroy; override;
  52. procedure Receive(ABuffer: TStream); override; //Decrypt
  53. procedure Send(ABuffer: TStream); override; //Encrypt
  54. procedure CopySettingsFrom (ASrcBlockCipherIntercept: TIdBlockCipherIntercept);
  55. //
  56. property Data: TObject read FData write FData;
  57. published
  58. property BlockSize: Integer read FBlockSize write SetBlockSize default IdBlockCipherBlockSizeDefault;
  59. // events
  60. property OnReceive: TIdBlockCipherInterceptDataEvent read GetOnReceive write SetOnReceive;
  61. property OnSend: TIdBlockCipherInterceptDataEvent read GetOnSend write SetOnSend;
  62. End;//TIdBlockCipherIntercept
  63. EIdBlockCipherInterceptException = EIdException; {block length}
  64. IMPLEMENTATION
  65. Uses
  66. IdGlobal,
  67. IdResourceStrings,
  68. SysUtils;
  69. { TIdBlockCipherIntercept }
  70. const
  71. bitLongTail = $80; //future: for IdBlockCipherBlockSizeMax>256
  72. constructor TIdBlockCipherIntercept.Create(AOwner: TComponent);
  73. Begin
  74. inherited Create(AOwner);
  75. FBlockSize := IdBlockCipherBlockSizeDefault;
  76. FRecvStream:= TMemoryStream.Create;
  77. FSendStream:= TMemoryStream.Create;
  78. End;//Create
  79. destructor TIdBlockCipherIntercept.Destroy;
  80. Begin
  81. FreeAndNIL(FSendStream);
  82. FreeAndNIL(FRecvStream);
  83. inherited Destroy;
  84. End;//Destroy
  85. procedure TIdBlockCipherIntercept.Encrypt(const ASrcData; var ADstData);
  86. Begin
  87. if Assigned(FOnSend) then begin
  88. TIdBlockCipherInterceptDataEvent(FOnSend)(SELF, @ASrcData, @ADstData);
  89. end;//ex: EncryptAES(LTempIn, ExpandedKey, LTempOut);
  90. End;//Encrypt
  91. procedure TIdBlockCipherIntercept.Decrypt(const ASrcData; var ADstData);
  92. Begin
  93. if Assigned(FOnReceive) then begin
  94. TIdBlockCipherInterceptDataEvent(FOnReceive)(SELF, @ASrcData, @ADstData);
  95. end;//ex: DecryptAES(LTempIn, ExpandedKey, LTempOut);
  96. End;//Decrypt
  97. procedure TIdBlockCipherIntercept.Send(ABuffer: TStream);
  98. var
  99. LTempIn, LTempOut: array [0..IdBlockCipherBlockSizeMax] of Byte;
  100. LCount: Integer;
  101. LBS: Integer; //block size-1
  102. Begin
  103. FSendStream.LoadFromStream(ABuffer);
  104. LCount := FSendStream.Seek(0,soFromEnd);//size
  105. ABuffer.Seek(0,0); //bof
  106. FSendStream.Seek(0,0);
  107. if LCount <= 0 then begin
  108. EXIT;
  109. end;
  110. LBS := FBlockSize-1;
  111. while LCount >= LBS do begin
  112. FSendStream.Read(LTempIn, LBS); //?ReadBuffer
  113. LTempIn[LBS]:= LBS;
  114. Encrypt(LTempIn,LTempOut);
  115. ABuffer.Write(LTempOut, FBlockSize);//? WriteBuffer
  116. Dec(LCount, LBS);
  117. end;//while
  118. if LCount > 0 then begin
  119. FSendStream.Read(LTempIn, LCount);//? ReadBuffer
  120. FillChar(LTempIn[LCount], FBlockSize - LCount, 0); //SizeOf(LTempIn)-Cnt
  121. LTempIn[LBS]:= LCount;
  122. Encrypt(LTempIn, LTempOut);
  123. ABuffer.Write(LTempOut, FBlockSize); //?WriteBuffer
  124. end;//if
  125. End;//Send
  126. procedure TIdBlockCipherIntercept.Receive(ABuffer: TStream);
  127. var
  128. LTempIn, LTempOut: array [0..IdBlockCipherBlockSizeMax] of Byte;
  129. LCount: Integer;
  130. LBS: Integer;
  131. LRcvBlkSize: Integer; //received block data length
  132. Begin
  133. FRecvStream.CopyFrom(ABuffer,0);//append
  134. LCount := FRecvStream.Seek(0,soFromEnd);//size
  135. ABuffer.Seek(0,0); //bof
  136. FRecvStream.Seek(0,0);
  137. if LCount <= 0 then begin
  138. exit;
  139. end;
  140. LBS := FBlockSize-1;
  141. while LCount >= FBlockSize do begin
  142. FRecvStream.Read(LTempIn, FBlockSize); //?ReadBuffer
  143. Decrypt(LTempIn, LTempOut);
  144. LRcvBlkSize := LTempOut[LBS]; //real data_in_block length
  145. if LRcvBlkSize > 0 then begin
  146. if LRcvBlkSize < FBlockSize then begin
  147. ABuffer.Write(LTempOut, LRcvBlkSize);
  148. end else begin
  149. raise EIdBlockCipherInterceptException.Create(RSBlockIncorrectLength);
  150. end;
  151. end;//if block with data
  152. Dec(LCount, FBlockSize);
  153. end;//while
  154. // cache for round block
  155. if LCount >0 then begin
  156. FRecvStream.Read(LTempIn, LCount);
  157. FRecvStream.Seek(0,0);//bof
  158. FRecvStream.Write(LTempIn, LCount);
  159. FRecvStream.SetSize(LCount);
  160. end else begin
  161. FRecvStream.Clear;
  162. end;
  163. ABuffer.Size := ABuffer.Position;//truncate
  164. End;//Receive
  165. function TIdBlockCipherIntercept.GetOnReceive: TIdBlockCipherInterceptDataEvent;
  166. Begin
  167. Result := TIdBlockCipherInterceptDataEvent(FOnReceive);
  168. End;
  169. function TIdBlockCipherIntercept.GetOnSend: TIdBlockCipherInterceptDataEvent;
  170. Begin
  171. Result := TIdBlockCipherInterceptDataEvent(FOnSend);
  172. End;
  173. procedure TIdBlockCipherIntercept.SetOnReceive(const Value: TIdBlockCipherInterceptDataEvent);
  174. Begin
  175. TIdBlockCipherInterceptDataEvent(FOnReceive):= Value;
  176. End;
  177. procedure TIdBlockCipherIntercept.SetOnSend(const Value: TIdBlockCipherInterceptDataEvent);
  178. Begin
  179. TIdBlockCipherInterceptDataEvent(FOnSend):= Value;
  180. End;
  181. procedure TIdBlockCipherIntercept.CopySettingsFrom(
  182. ASrcBlockCipherIntercept: TIdBlockCipherIntercept);
  183. Begin
  184. with ASrcBlockCipherIntercept do begin
  185. SELF.FBlockSize := FBlockSize;
  186. SELF.FData:= FData;
  187. SELF.FOnConnect := FOnConnect;
  188. SELF.FOnDisconnect:= FOnDisconnect;
  189. SELF.FOnReceive := FOnReceive;
  190. SELF.FOnSend := FOnSend;
  191. end;
  192. End;//
  193. procedure TIdBlockCipherIntercept.SetBlockSize(const Value: Integer);
  194. Begin
  195. if (Value>0) and (Value<=IdBlockCipherBlockSizeMax) then begin
  196. FBlockSize := Value;
  197. end;
  198. End;//
  199. END.