我正在尝试验证服务器证书。 我使用Indy 10和OpenSSL。 我指定了根证书文件(RootCertFile
)和VerifyDepth
为MaxInt
。 在OnVerifyPeer
函数中一切正常 - AOk
为true
。 我想知道如何从 Windows受信任的根证书颁发机构加载证书。 下面是客户端的代码:
uses
{Delphi}
IdSSLOpenSSL
, IdHTTP
, IdHeaderList
, System.Classes
{Project}
;
type
TUnicodeHTTPPoster = class
strict private
FidHTTP: TIdHTTP;
FLastError: string;
FCertPassword: string;
procedure OnGetPassword(var Password: string);
function OnVerifySSLPeer(Certificate: TIdX509;AOk: Boolean; ADepth, AError: Integer): Boolean;
public
constructor Create(const ASSLVersion: TIdSSLVersion; const AAccept: string = 'application/xml';
const ACharSet: string = 'utf-8'; const ACertFile: string = ''; const AKeyFile: string = '';
const ACertPassword: string = ''); reintroduce;
destructor Destroy; override;
function Post(const ACustomHeaders: TIdHeaderList; const ARawBody: TStream;
const AURL: string; out AResponse: string): integer;
end;
implementation
uses
{Delphi}
System.SysUtils
, IdURI
, IdGlobal
{Project}
;
constructor TUnicodeHTTPPoster.Create(const ASSLVersion: TIdSSLVersion; const AAccept: string = 'application/xml';
const ACharSet: string = 'utf-8'; const ACertFile: string = ''; const AKeyFile: string = '';
const ACertPassword: string = '');
var
_IdSSLIOHandlerSocketOpenSSL: TIdSSLIOHandlerSocketOpenSSL;
begin
inherited Create;
FidHTTP := TIdHTTP.Create(nil);
FidHTTP.Request.Accept := 'application/xml';
if AAccept <> '' then
FidHTTP.Request.Accept := AAccept;
FidHTTP.Request.Charset := 'utf-8';
if ACharSet <> '' then
FidHTTP.Request.Charset := ACharSet;
_IdSSLIOHandlerSocketOpenSSL := TIdSSLIOHandlerSocketOpenSSL.Create(FidHTTP);
if FileExists(ACertFile) then
_IdSSLIOHandlerSocketOpenSSL.SSLOptions.CertFile := ACertFile;
if FileExists(AKeyFile) then
_IdSSLIOHandlerSocketOpenSSL.SSLOptions.KeyFile := AKeyFile;
FCertPassword := ACertPassword;
FidHTTP.Request.BasicAuthentication := False;
_IdSSLIOHandlerSocketOpenSSL.SSLOptions.Mode := sslmClient;
_IdSSLIOHandlerSocketOpenSSL.SSLOptions.Method := ASSLVersion;
_IdSSLIOHandlerSocketOpenSSL.OnGetPassword := OnGetPassword;
_IdSSLIOHandlerSocketOpenSSL.SSLOptions.VerifyMode := [sslvrfPeer];
_IdSSLIOHandlerSocketOpenSSL.SSLOptions.VerifyDepth := MaxInt;
_IdSSLIOHandlerSocketOpenSSL.OnVerifyPeer := OnVerifySSLPeer;
_IdSSLIOHandlerSocketOpenSSL.SSLOptions.RootCertFile := 'C:\Users\ekolesnikovics\Desktop\Projects\nDentity\ndentify\Build\dc_ofisas.nsoft.lt.pem';
FidHTTP.IOHandler := _IdSSLIOHandlerSocketOpenSSL;
end;
function TUnicodeHTTPPoster.OnVerifySSLPeer(Certificate: TIdX509;AOk: Boolean; ADepth, AError: Integer): Boolean;
begin
Result := AOk;
end;
procedure TUnicodeHTTPPoster.OnGetPassword(var Password: string);
begin
Password := FCertPassword;
end;
function TUnicodeHTTPPoster.Post(const ACustomHeaders: TIdHeaderList; const ARawBody: TStream;
const AURL: string; out AResponse: string): integer;
var
_URL: string;
_ResponseStream: TStringStream;
begin
Result := 500;
FLastError := '';
try
if Trim(AURL) = '' then
raise EArgumentException.Create('URL is not provided.');
_URL := TIdURI.URLEncode(AURL, IndyTextEncoding_UTF8);
_ResponseStream := TStringStream.Create('', TEncoding.UTF8);
try
if Assigned(FidHTTP.Request.CustomHeaders) then
FidHTTP.Request.CustomHeaders.Clear;
if Assigned(ACustomHeaders) then
FidHTTP.Request.CustomHeaders := ACustomHeaders;
FidHTTP.Post(_URL, ARawBody, _ResponseStream);
_ResponseStream.Position := 0;
AResponse := _ResponseStream.DataString;
finally
FreeAndNil(_ResponseStream);
end;
Result := 200;
except
on E: EIdHTTPProtocolException do
begin
Result := E.ErrorCode;
FLastError := E.ErrorMessage;
FidHTTP.Disconnect;
end;
on E: Exception do
begin
FLastError := E.Message;
FidHTTP.Disconnect;
end;
end;
end;