sslsockets.pp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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; 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;
  43. public
  44. constructor Create; override;
  45. Destructor Destroy; override;
  46. // Class factory methods
  47. Class Procedure SetDefaultHandlerClass(aClass : TSSLSocketHandlerClass);
  48. Class Function GetDefaultHandlerClass : TSSLSocketHandlerClass;
  49. Class Function GetDefaultHandler : TSSLSocketHandler;
  50. // Socket methods
  51. Function CreateCertificateData : TCertificateData; virtual;
  52. Function CreateCertGenerator : TX509Certificate; virtual;
  53. function CreateSelfSignedCertificate: Boolean; virtual;
  54. Property CertGenerator : TX509Certificate Read FCertGenerator;
  55. Property SSLActive: Boolean read FSSLActive;
  56. published
  57. property SSLType: TSSLType read FSSLType write FSSLType;
  58. property VerifyPeerCert: Boolean read FVerifyPeerCert Write FVerifyPeerCert;
  59. Property SendHostAsSNI : Boolean Read FSendHostAsSNI Write FSendHostAsSNI;
  60. Property CertificateData : TCertificateData Read FCertificateData Write SetCertificateData;
  61. // Deprecated, use CertificateData instead.
  62. property KeyPassword: string Index 0 read GetString write SetString; deprecated 'use CertificateData instead';
  63. property CipherList: string Index 1 read GetString write SetString; deprecated 'use CertificateData instead';
  64. // In case a certificate must be generated as server, this is the hostname that will be used.
  65. property RemoteHostName : String Index 2 read GetString write SetString; deprecated 'use CertificateData instead';
  66. property Certificate : TSSLData Index 0 Read GetSSLData Write SetSSLData; deprecated 'use CertificateData instead';
  67. property TrustedCertificate : TSSLData Index 1 Read GetSSLData Write SetSSLData;deprecated 'use CertificateData instead';
  68. property PrivateKey : TSSLData Index 2 Read GetSSLData Write SetSSLData;deprecated 'use CertificateData instead';
  69. property PFX: TSSLData Index 3 Read GetSSLData Write SetSSLData;deprecated 'use CertificateData instead';
  70. property CertCA: TSSLData Index 4 Read GetSSLData Write SetSSLData;deprecated 'use CertificateData instead';
  71. property OnVerifyCertificate: TVerifyCertificateEvent read FOnVerifyCertificate write FOnVerifyCertificate;
  72. end;
  73. implementation
  74. Resourcestring
  75. SErrNoSSLSupport =
  76. 'No SSL Socket support compiled in.'+sLineBreak+
  77. 'Please include opensslsockets unit in program and recompile it.';
  78. SErrNoX509Certificate =
  79. 'Cannot create a X509 certificate without SLL support';
  80. { TSSLSocketHandler }
  81. function TSSLSocketHandler.GetSSLData(AIndex: Integer): TSSLData;
  82. begin
  83. Case aIndex of
  84. 0 : Result:=FCertificateData.Certificate;
  85. 1 : Result:=FCertificateData.TrustedCertificate;
  86. 2 : Result:=FCertificateData.PrivateKey;
  87. 3 : Result:=FCertificateData.PFX;
  88. 4 : Result:=FCertificateData.CertCA;
  89. end;
  90. end;
  91. function TSSLSocketHandler.GetString(AIndex: Integer): string;
  92. begin
  93. Case AIndex of
  94. 0 : Result:=FCertificateData.KeyPassword;
  95. 1 : Result:=FCertificateData.CipherList;
  96. 2 : Result:=FCertificateData.HostName;
  97. end;
  98. end;
  99. procedure TSSLSocketHandler.SetCertificateData(AValue: TCertificateData);
  100. begin
  101. if FCertificateData=AValue then Exit;
  102. FCertificateData.Assign(AValue);
  103. end;
  104. procedure TSSLSocketHandler.SetSSLData(AIndex: Integer; AValue: TSSLData);
  105. begin
  106. Case aIndex of
  107. 0 : FCertificateData.Certificate:=AValue;
  108. 1 : FCertificateData.TrustedCertificate:=AValue;
  109. 2 : FCertificateData.PrivateKey:=AValue;
  110. 3 : FCertificateData.PFX:=AValue;
  111. 4 : FCertificateData.CertCA:=AValue;
  112. end;
  113. end;
  114. procedure TSSLSocketHandler.SetString(AIndex: Integer; AValue: string);
  115. begin
  116. Case AIndex of
  117. 0 : FCertificateData.KeyPassword:=AValue;
  118. 1 : FCertificateData.CipherList:=AValue;
  119. 2 : begin
  120. FCertificateData.HostName:=AValue;
  121. FCertGenerator.HostName:=aValue;
  122. end;
  123. end;
  124. end;
  125. procedure TSSLSocketHandler.SetSSLActive(aValue: Boolean);
  126. begin
  127. FSSLActive:=aValue;
  128. end;
  129. function TSSLSocketHandler.DoVerifyCert: boolean;
  130. begin
  131. Result:=True;
  132. If Assigned(OnVerifyCertificate) then
  133. OnVerifyCertificate(Self,Result);
  134. end;
  135. constructor TSSLSocketHandler.Create;
  136. begin
  137. inherited Create;
  138. FSendHostAsSNI:=True;
  139. FCertGenerator:=CreateCertGenerator;
  140. FCertificateData:=CreateCertificateData;
  141. end;
  142. Destructor TSSLSocketHandler.Destroy;
  143. begin
  144. FreeAndNil(FCertificateData);
  145. FreeAndNil(FCertGenerator);
  146. inherited Destroy;
  147. end;
  148. class procedure TSSLSocketHandler.SetDefaultHandlerClass(aClass: TSSLSocketHandlerClass);
  149. begin
  150. FDefaultHandlerClass:=aClass;
  151. end;
  152. class function TSSLSocketHandler.GetDefaultHandlerClass: TSSLSocketHandlerClass;
  153. begin
  154. Result:=FDefaultHandlerClass;
  155. end;
  156. class function TSSLSocketHandler.GetDefaultHandler: TSSLSocketHandler;
  157. begin
  158. if FDefaultHandlerClass=Nil then
  159. Raise ESSLSocketError.Create(SErrNoSSLSupport);
  160. Result:=FDefaultHandlerClass.Create;
  161. end;
  162. function TSSLSocketHandler.CreateCertificateData: TCertificateData;
  163. begin
  164. Result:=TCertificateData.Create;
  165. end;
  166. function TSSLSocketHandler.CreateCertGenerator: TX509Certificate;
  167. begin
  168. Raise ESSLSocketError.Create(SErrNoX509Certificate);
  169. end;
  170. function TSSLSocketHandler.CreateSelfSignedCertificate: Boolean;
  171. Var
  172. CK:TCertAndKey;
  173. begin
  174. CK:=CertGenerator.CreateCertificateAndKey;
  175. CertificateData.Certificate.Value:=CK.Certificate;
  176. CertificateData.PrivateKey.Value:=CK.PrivateKey;
  177. Result:=(Length(CK.Certificate)<>0) and (Length(CK.PrivateKey)<>0);
  178. end;
  179. end.