sslbase.pp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. {$IFNDEF FPC_DOTTEDUNITS}
  2. unit sslbase;
  3. {$ENDIF FPC_DOTTEDUNITS}
  4. {
  5. This file is part of the Free Pascal run time library.
  6. Copyright (c) 1999-2022 by Michael van Canney and other members of the
  7. Free Pascal development team
  8. SSL Base unit
  9. See the file COPYING.FPC, included in this distribution,
  10. for details about the copyright.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. **********************************************************************}
  15. {$mode objfpc}{$H+}
  16. interface
  17. {$IFDEF FPC_DOTTEDUNITS}
  18. uses
  19. System.Classes, System.SysUtils;
  20. {$ELSE FPC_DOTTEDUNITS}
  21. uses
  22. Classes, SysUtils;
  23. {$ENDIF FPC_DOTTEDUNITS}
  24. Type
  25. TSSLType = (stAny,stSSLv2,stSSLv3,stTLSv1,stTLSv1_1,stTLSv1_2);
  26. { TSSLData }
  27. TSSLData = Class(TPersistent)
  28. private
  29. FFileName: String;
  30. FValue: TBytes;
  31. Public
  32. Function Empty : Boolean;
  33. Procedure Assign(Source : TPersistent);override;
  34. Property FileName : String Read FFileName Write FFileName;
  35. Property Value: TBytes Read FValue Write FValue;
  36. end;
  37. Const
  38. SSLDataCount = 4; // 0 based.
  39. StrDataCount = 2; // 0 based.
  40. Type
  41. { TSSLSocketHandler }
  42. { TCertificateData }
  43. TCertificateData = Class(TPersistent)
  44. Private
  45. FStrData : Array[0..StrDataCount] of string;
  46. FCertData : Array[0..SSLDataCount] of TSSLData;
  47. FTrustedCertsDir: String;
  48. function GetSSLData(AIndex: Integer): TSSLData;
  49. procedure SetSSLData(AIndex: Integer; AValue: TSSLData);
  50. function GetString(AIndex: Integer): String;
  51. procedure SetString(AIndex: Integer; const AValue: String);
  52. Public
  53. constructor Create;
  54. Destructor Destroy; override;
  55. Procedure Assign(Source : TPersistent); override;
  56. Function NeedCertificateData : Boolean;
  57. Published
  58. property KeyPassword: string Index 0 read GetString write SetString;
  59. property CipherList: string Index 1 read GetString write SetString;
  60. Property HostName : String Index 2 read GetString write SetString;
  61. property Certificate : TSSLData Index 0 Read GetSSLData Write SetSSLData;
  62. property TrustedCertificate : TSSLData Index 1 Read GetSSLData Write SetSSLData;
  63. property PrivateKey : TSSLData Index 2 Read GetSSLData Write SetSSLData;
  64. property PFX: TSSLData Index 3 Read GetSSLData Write SetSSLData;
  65. property CertCA: TSSLData Index 4 Read GetSSLData Write SetSSLData;
  66. // OpenSSL allows both a PEM file or a Dir. We separate out the dir.
  67. Property TrustedCertsDir : String Read FTrustedCertsDir Write FTrustedCertsDir;
  68. end;
  69. { TX509Certificate }
  70. TCertAndKey = Record
  71. Certificate : TBytes;
  72. PrivateKey : TBytes;
  73. end;
  74. TX509Certificate = Class (TObject)
  75. private
  76. FCommonName: string;
  77. FCountry: String;
  78. FHostName: string;
  79. FKeySize: Integer;
  80. FOrganization: String;
  81. FSerial: Integer;
  82. FValidFrom: TDateTime;
  83. FValidTo: TDateTime;
  84. FVersion: Integer;
  85. function GetKeySize: Integer;
  86. function GetValidFrom: TDateTime;
  87. function GetValidTo: TDateTime;
  88. function GetVersion: Integer;
  89. Protected
  90. Function GetRealSerial : Integer;
  91. Public
  92. Function CreateCertificateAndKey : TCertAndKey; virtual; abstract;
  93. Procedure CreateCertificateAndKey(Var aCertificate,aKey : TBytes);
  94. Property Country : String Read FCountry Write FCountry;
  95. Property HostName : string Read FHostName Write FHostName;
  96. Property CommonName : string Read FCommonName Write FCommonName;
  97. Property Organization : String Read FOrganization Write FOrganization;
  98. Property KeySize : Integer Read GetKeySize Write FKeySize;
  99. // Valid from. Default today -1;
  100. Property ValidFrom : TDateTime Read GetValidFrom Write FValidFrom;
  101. // Valid To. Default today + 31;
  102. Property ValidTo : TDateTime Read GetValidTo Write FValidTo;
  103. // Version Default 1.
  104. Property Version : Integer Read GetVersion Write FVersion;
  105. // Serial. If zero, then a serial is generated.
  106. Property Serial : Integer Read FSerial Write FSerial;
  107. end;
  108. implementation
  109. { TSSLData }
  110. Function TSSLData.Empty: Boolean;
  111. begin
  112. Result:=(Length(Value)=0) and (FileName='');
  113. end;
  114. Procedure TSSLData.Assign(Source: TPersistent);
  115. begin
  116. if Source is TSSLData then
  117. With TSSLData(Source) do
  118. begin
  119. Self.FValue:=FValue;
  120. Self.FFileName:=FFileName;
  121. end
  122. else
  123. inherited Assign(Source);
  124. end;
  125. { TCertificateData }
  126. function TCertificateData.GetSSLData(AIndex: Integer): TSSLData;
  127. begin
  128. Result:=FCertData[AIndex];
  129. end;
  130. procedure TCertificateData.SetSSLData(AIndex: Integer; AValue: TSSLData);
  131. begin
  132. FCertData[AIndex].Assign(AValue);
  133. end;
  134. function TCertificateData.GetString(AIndex: Integer): String;
  135. begin
  136. Result:=FStrData[AIndex];
  137. if (AIndex=2) and (result='') then
  138. Result:='localhost';
  139. end;
  140. procedure TCertificateData.SetString(AIndex: Integer; const AValue: String);
  141. begin
  142. FStrData[AIndex]:=aValue;
  143. end;
  144. constructor TCertificateData.Create;
  145. Var
  146. I : Integer;
  147. begin
  148. CipherList:='DEFAULT';
  149. HostName:='localhost';
  150. For I:=0 to SSLDataCount do
  151. FCertData[i]:=TSSLData.Create;
  152. end;
  153. destructor TCertificateData.Destroy;
  154. Var
  155. I : Integer;
  156. begin
  157. For I:=0 to SSLDataCount do
  158. FreeAndNil(FCertData[i]);
  159. inherited Destroy;
  160. end;
  161. procedure TCertificateData.Assign(Source: TPersistent);
  162. Var
  163. CD : TCertificateData;
  164. I : Integer;
  165. begin
  166. if Source is TCertificateData then
  167. begin
  168. CD:=Source as TCertificateData;
  169. For I:=0 to StrDataCount do
  170. FStrData[i]:=CD.FStrData[i];
  171. For I:=0 to SSLDataCount do
  172. FCertData[i].Assign(CD.FCertData[i])
  173. end
  174. else
  175. inherited Assign(Source);
  176. end;
  177. function TCertificateData.NeedCertificateData: Boolean;
  178. begin
  179. Result:=Certificate.Empty and PFX.Empty;
  180. end;
  181. function TX509Certificate.GetKeySize: Integer;
  182. begin
  183. Result:=FKeySize;
  184. if Result=0 then
  185. Result:=1024;
  186. end;
  187. function TX509Certificate.GetValidFrom: TDateTime;
  188. begin
  189. Result:=FValidFrom;
  190. If Result=0 then
  191. Result:=Date-1;
  192. end;
  193. function TX509Certificate.GetValidTo: TDateTime;
  194. begin
  195. Result:=FValidTo;
  196. If Result=0 then
  197. Result:=Date+31;
  198. end;
  199. function TX509Certificate.GetVersion: Integer;
  200. begin
  201. Result:=FVersion;
  202. if FVersion=0 then
  203. FVersion:=1;
  204. end;
  205. function TX509Certificate.GetRealSerial: Integer;
  206. begin
  207. Result:=FSerial;
  208. if Result=0 then
  209. Result:=10; // MinutesBetween(Now,EncodeDate(2019,1,1));
  210. end;
  211. procedure TX509Certificate.CreateCertificateAndKey(var aCertificate, aKey: TBytes);
  212. Var
  213. CK : TCertAndKey;
  214. begin
  215. CK:=CreateCertificateAndKey;
  216. aCertificate:=CK.Certificate;
  217. aKey:=CK.PrivateKey;
  218. end;
  219. end.