IdHashIntf.pas 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. unit IdHashIntf;
  2. interface
  3. {$i IdCompilerDefines.inc}
  4. uses
  5. Classes,
  6. IdFIPS,
  7. IdGlobal, IdHash;
  8. type
  9. TIdHashInt = class(TIdHash)
  10. protected
  11. function HashToHex(const AHash: TIdBytes): String; override;
  12. function GetHashInst : TIdHashInst; virtual; abstract;
  13. function InitHash : TIdHashIntCtx; virtual;
  14. procedure UpdateHash(ACtx : TIdHashIntCtx; const AIn : TIdBytes);
  15. function FinalHash(ACtx : TIdHashIntCtx) : TIdBytes;
  16. function GetHashBytes(AStream: TStream; ASize: Int64): TIdBytes; override;
  17. public
  18. class function IsAvailable : Boolean; override;
  19. end;
  20. TIdHashSHA224 = class(TIdHashInt)
  21. protected
  22. function GetHashInst : TIdHashInst; override;
  23. public
  24. class function IsAvailable : Boolean; override;
  25. end;
  26. TIdHashSHA256 = class(TIdHashInt)
  27. protected
  28. function GetHashInst : TIdHashInst; override;
  29. public
  30. class function IsAvailable : Boolean; override;
  31. end;
  32. TIdHashSHA386 = class(TIdHashInt)
  33. protected
  34. function GetHashInst : TIdHashInst; override;
  35. public
  36. class function IsAvailable : Boolean; override;
  37. end;
  38. TIdHashSHA512 = class(TIdHashInt)
  39. protected
  40. function GetHashInst : TIdHashInst; override;
  41. public
  42. class function IsAvailable : Boolean; override;
  43. end;
  44. EIdDigestError = class(EIdOpenSSLAPICryptoError);
  45. EIdDigestFinalEx = class(EIdDigestError);
  46. EIdDigestInitEx = class(EIdDigestError);
  47. EIdDigestUpdate = class(EIdDigestError);
  48. implementation
  49. uses
  50. IdCTypes;
  51. { TIdHashInt }
  52. function TIdHashInt.FinalHash(ACtx: TIdHashIntCtx): TIdBytes;
  53. var
  54. LLen, LRet : TIdC_UInt;
  55. begin
  56. SetLength(Result,OPENSSL_EVP_MAX_MD_SIZE);
  57. LRet := IdSslEvpDigestFinalEx(@ACtx,@Result[0],LLen);
  58. if LRet <> 1 then begin
  59. EIdDigestFinalEx.RaiseException('EVP_DigestFinal_ex error');
  60. end;
  61. SetLength(Result,LLen);
  62. IdSslEvpMDCtxCleanup(@ACtx);
  63. end;
  64. function TIdHashInt.GetHashBytes(AStream: TStream; ASize: Int64): TIdBytes;
  65. var
  66. LBuf : TIdBytes;
  67. LSize : Int64;
  68. LCtx : TIdHashIntCtx;
  69. begin
  70. LCtx := InitHash;
  71. try
  72. SetLength(LBuf,2048);
  73. repeat
  74. LSize := ReadTIdBytesFromStream(AStream,LBuf,2048);
  75. if LSize = 0 then begin
  76. Break;
  77. end;
  78. if LSize < 2048 then begin
  79. SetLength(LBuf,LSize);
  80. UpdateHash(LCtx,LBuf);
  81. break;
  82. end else begin
  83. UpdateHash(LCtx,LBuf);
  84. end;
  85. until False;
  86. finally
  87. Result := FinalHash(LCtx);
  88. end;
  89. end;
  90. function TIdHashInt.HashToHex(const AHash: TIdBytes): String;
  91. begin
  92. Result := ToHex(AHash);
  93. end;
  94. function TIdHashInt.InitHash: TIdHashIntCtx;
  95. var
  96. LHash : TIdHashInst;
  97. LRet : TIdC_Int;
  98. begin
  99. LHash := GetHashInst;
  100. IdSslEvpMDCtxInit(@Result);
  101. LRet := IdSslEvpDigestInitEx(@Result, LHash, nil);
  102. if LRet <> 1 then begin
  103. EIdDigestInitEx.RaiseException('EVP_DigestInit_ex error');
  104. end;
  105. end;
  106. class function TIdHashInt.IsAvailable: Boolean;
  107. begin
  108. Result := Assigned(IdSslEvpDigestInitEx) and
  109. Assigned(IdSslEvpDigestUpdate) and
  110. Assigned(IdSslEvpDigestFinalEx);
  111. end;
  112. procedure TIdHashInt.UpdateHash(ACtx: TIdHashIntCtx; const AIn: TIdBytes);
  113. var
  114. LRet : TIdC_Int;
  115. begin
  116. LRet := IdSslEvpDigestUpdate(@ACtx,PByte(Ain),Length(AIn));
  117. if LRet <> 1 then begin
  118. EIdDigestInitEx.RaiseException('EVP_DigestUpdate error');
  119. end;
  120. end;
  121. { TIdHashSHA224 }
  122. function TIdHashSHA224.GetHashInst: TIdHashInst;
  123. begin
  124. Result := IdSslEvpSHA224;
  125. end;
  126. class function TIdHashSHA224.IsAvailable: Boolean;
  127. begin
  128. Result := Assigned(IdSslEvpSHA224) and inherited IsAvailable;
  129. end;
  130. { TIdHashSHA256 }
  131. function TIdHashSHA256.GetHashInst: TIdHashInst;
  132. begin
  133. Result := IdSslEvpSHA256;
  134. end;
  135. class function TIdHashSHA256.IsAvailable: Boolean;
  136. begin
  137. Result := Assigned(IdSslEvpSHA256) and inherited IsAvailable;
  138. end;
  139. { TIdHashSHA386 }
  140. function TIdHashSHA386.GetHashInst: TIdHashInst;
  141. begin
  142. Result := IdSslEvpSHA384;
  143. end;
  144. class function TIdHashSHA386.IsAvailable: Boolean;
  145. begin
  146. Result := Assigned(IdSslEvpSHA384) and inherited IsAvailable;
  147. end;
  148. { TIdHashSHA512 }
  149. function TIdHashSHA512.GetHashInst: TIdHashInst;
  150. begin
  151. Result := IdSslEvpSHA512;
  152. end;
  153. class function TIdHashSHA512.IsAvailable: Boolean;
  154. begin
  155. Result := Assigned(IdSslEvpSHA512) and inherited IsAvailable;
  156. end;
  157. end.