sslsockets.pp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 1999-2000 by the Free Pascal development team
  4. SSL support for ssockets
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit sslsockets;
  12. {$mode objfpc}{$H+}
  13. interface
  14. uses
  15. Classes, SysUtils, sockets, ssockets, sslbase;
  16. Const
  17. SUseCertData = 'use CertificateData instead';
  18. Type
  19. ESSLSocketError = Class(ESocketError);
  20. TSSLSocketHandler = class;
  21. TVerifyCertificateEvent = Procedure(Sender : TObject; var Allow : Boolean) of object;
  22. TSSLSocketHandlerClass = class of TSSLSocketHandler;
  23. { TSSLSocketHandler }
  24. TSSLSocketHandler = class(TSocketHandler)
  25. private
  26. FCertGenerator: TX509Certificate;
  27. FCertificateData: TCertificateData;
  28. FVerifyPeerCert: Boolean;
  29. FOnVerifyCertificate: TVerifyCertificateEvent;
  30. FSSLType: TSSLType;
  31. FSSLActive : Boolean;
  32. FSendHostAsSNI : Boolean;
  33. function GetSSLData(AIndex: Integer): TSSLData;
  34. function GetString(AIndex: Integer): string;
  35. procedure SetCertificateData(AValue: TCertificateData);
  36. procedure SetSSLData(AIndex: Integer; AValue: TSSLData);
  37. procedure SetString(AIndex: Integer; AValue: string);
  38. Private
  39. Class Var FDefaultHandlerClass : TSSLSocketHandlerClass;
  40. protected
  41. Procedure SetSSLActive(aValue : Boolean);
  42. function DoVerifyCert: boolean; virtual; // if event define's change not accceptable, suggest to set virtual
  43. Function GetLastSSLErrorString : String; virtual; abstract;
  44. Function GetLastSSLErrorCode : Integer; virtual; abstract;
  45. public
  46. constructor Create; override;
  47. Destructor Destroy; override;
  48. Function GetLastErrorDescription : String;override;
  49. // Class factory methods
  50. Class Procedure SetDefaultHandlerClass(aClass : TSSLSocketHandlerClass);
  51. Class Function GetDefaultHandlerClass : TSSLSocketHandlerClass;
  52. Class Function GetDefaultHandler : TSSLSocketHandler;
  53. // Socket methods
  54. Function CreateCertificateData : TCertificateData; virtual;
  55. Function CreateCertGenerator : TX509Certificate; virtual;
  56. function CreateSelfSignedCertificate: Boolean; virtual;
  57. Property CertGenerator : TX509Certificate Read FCertGenerator;
  58. Property SSLActive: Boolean read FSSLActive;
  59. Property LastSSLErrorString : String Read GetLastSSLErrorString;
  60. Property LastSSLErrorCode : Integer Read GetLastSSLErrorCode;
  61. published
  62. property SSLType: TSSLType read FSSLType write FSSLType;
  63. property VerifyPeerCert: Boolean read FVerifyPeerCert Write FVerifyPeerCert;
  64. Property SendHostAsSNI : Boolean Read FSendHostAsSNI Write FSendHostAsSNI;
  65. Property CertificateData : TCertificateData Read FCertificateData Write SetCertificateData;
  66. // Deprecated, use CertificateData instead.
  67. property KeyPassword: string Index 0 read GetString write SetString; deprecated 'use CertificateData instead';
  68. property CipherList: string Index 1 read GetString write SetString; deprecated 'use CertificateData instead';
  69. // In case a certificate must be generated as server, this is the hostname that will be used.
  70. property RemoteHostName : String Index 2 read GetString write SetString; deprecated 'use CertificateData instead';
  71. property Certificate : TSSLData Index 0 Read GetSSLData Write SetSSLData; deprecated 'use CertificateData instead';
  72. property TrustedCertificate : TSSLData Index 1 Read GetSSLData Write SetSSLData;deprecated 'use CertificateData instead';
  73. property PrivateKey : TSSLData Index 2 Read GetSSLData Write SetSSLData;deprecated 'use CertificateData instead';
  74. property PFX: TSSLData Index 3 Read GetSSLData Write SetSSLData;deprecated 'use CertificateData instead';
  75. property CertCA: TSSLData Index 4 Read GetSSLData Write SetSSLData;deprecated 'use CertificateData instead';
  76. property OnVerifyCertificate: TVerifyCertificateEvent read FOnVerifyCertificate write FOnVerifyCertificate;
  77. end;
  78. implementation
  79. Resourcestring
  80. SErrNoSSLSupport =
  81. 'No SSL Socket support compiled in.'+sLineBreak+
  82. 'Please include opensslsockets unit in program and recompile it.';
  83. SErrNoX509Certificate =
  84. 'Cannot create a X509 certificate without SLL support';
  85. SSSLErrorCode = 'SSL error code: %d';
  86. { TSSLSocketHandler }
  87. function TSSLSocketHandler.GetSSLData(AIndex: Integer): TSSLData;
  88. begin
  89. Case aIndex of
  90. 0 : Result:=FCertificateData.Certificate;
  91. 1 : Result:=FCertificateData.TrustedCertificate;
  92. 2 : Result:=FCertificateData.PrivateKey;
  93. 3 : Result:=FCertificateData.PFX;
  94. 4 : Result:=FCertificateData.CertCA;
  95. end;
  96. end;
  97. function TSSLSocketHandler.GetString(AIndex: Integer): string;
  98. begin
  99. Case AIndex of
  100. 0 : Result:=FCertificateData.KeyPassword;
  101. 1 : Result:=FCertificateData.CipherList;
  102. 2 : Result:=FCertificateData.HostName;
  103. end;
  104. end;
  105. procedure TSSLSocketHandler.SetCertificateData(AValue: TCertificateData);
  106. begin
  107. if FCertificateData=AValue then Exit;
  108. FCertificateData.Assign(AValue);
  109. end;
  110. procedure TSSLSocketHandler.SetSSLData(AIndex: Integer; AValue: TSSLData);
  111. begin
  112. Case aIndex of
  113. 0 : FCertificateData.Certificate:=AValue;
  114. 1 : FCertificateData.TrustedCertificate:=AValue;
  115. 2 : FCertificateData.PrivateKey:=AValue;
  116. 3 : FCertificateData.PFX:=AValue;
  117. 4 : FCertificateData.CertCA:=AValue;
  118. end;
  119. end;
  120. procedure TSSLSocketHandler.SetString(AIndex: Integer; AValue: string);
  121. begin
  122. Case AIndex of
  123. 0 : FCertificateData.KeyPassword:=AValue;
  124. 1 : FCertificateData.CipherList:=AValue;
  125. 2 : begin
  126. FCertificateData.HostName:=AValue;
  127. FCertGenerator.HostName:=aValue;
  128. end;
  129. end;
  130. end;
  131. procedure TSSLSocketHandler.SetSSLActive(aValue: Boolean);
  132. begin
  133. FSSLActive:=aValue;
  134. end;
  135. function TSSLSocketHandler.DoVerifyCert: boolean;
  136. begin
  137. Result:=True;
  138. If Assigned(OnVerifyCertificate) then
  139. OnVerifyCertificate(Self,Result);
  140. end;
  141. constructor TSSLSocketHandler.Create;
  142. begin
  143. inherited Create;
  144. FSendHostAsSNI:=True;
  145. FCertGenerator:=CreateCertGenerator;
  146. FCertificateData:=CreateCertificateData;
  147. end;
  148. Destructor TSSLSocketHandler.Destroy;
  149. begin
  150. FreeAndNil(FCertificateData);
  151. FreeAndNil(FCertGenerator);
  152. inherited Destroy;
  153. end;
  154. function TSSLSocketHandler.GetLastErrorDescription: String;
  155. begin
  156. Result:='';
  157. if LastSSLErrorCode<>0 then
  158. Result:=Format(SSSLErrorCode,[GetLastSSLErrorCode]);
  159. if LastSSLErrorString<>'' then
  160. begin
  161. if (Result<>'') then
  162. Result:=Result+': ';
  163. Result:=Result+LastSSLErrorString;
  164. end;
  165. end;
  166. class procedure TSSLSocketHandler.SetDefaultHandlerClass(aClass: TSSLSocketHandlerClass);
  167. begin
  168. FDefaultHandlerClass:=aClass;
  169. end;
  170. class function TSSLSocketHandler.GetDefaultHandlerClass: TSSLSocketHandlerClass;
  171. begin
  172. Result:=FDefaultHandlerClass;
  173. end;
  174. class function TSSLSocketHandler.GetDefaultHandler: TSSLSocketHandler;
  175. begin
  176. if FDefaultHandlerClass=Nil then
  177. Raise ESSLSocketError.Create(SErrNoSSLSupport);
  178. Result:=FDefaultHandlerClass.Create;
  179. end;
  180. function TSSLSocketHandler.CreateCertificateData: TCertificateData;
  181. begin
  182. Result:=TCertificateData.Create;
  183. end;
  184. function TSSLSocketHandler.CreateCertGenerator: TX509Certificate;
  185. begin
  186. Raise ESSLSocketError.Create(SErrNoX509Certificate);
  187. end;
  188. function TSSLSocketHandler.CreateSelfSignedCertificate: Boolean;
  189. Var
  190. CK:TCertAndKey;
  191. begin
  192. CK:=CertGenerator.CreateCertificateAndKey;
  193. CertificateData.Certificate.Value:=CK.Certificate;
  194. CertificateData.PrivateKey.Value:=CK.PrivateKey;
  195. Result:=(Length(CK.Certificate)<>0) and (Length(CK.PrivateKey)<>0);
  196. end;
  197. end.