简体   繁体   中英

Changing SSL certificates on the fly in IdHTTPServer

I'm developing a MITM proxy with SSL support in delphi 10.3, using indy. I use IdHttpServer component, which does work in CommandOther event. I managed to make it to decrypt and dump data on the fly, and reencrypt and send it to browser, but I need to change idhttpserver certificate for each domain. I can generate them and install my own CA, but i cant find a way to change them while my proxy is working . I will greatly appreciate if someone will show me how!

 procedure TForm3.IdHTTPServer1CommandOther(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
 var
S: string;
LClient: TIdtcpClient;
 newsize:int64;
LBuf: TIdBytes;
Len: Integer;

var response:integer;
s3: TStringDynArray;
var cmd:string;
bytes:tidbytes;

oldstr,newstr:string;
ResponseCode, ResponseText: string;
  Size: Int64;
ssl:tIdServerIOHandlerSSLopenssl;


begin
 if not TextIsSame(ARequestInfo.Command, 'CONNECT') then Exit;


 LClient := TIdtcpClient.Create(nil);
  try

S := ARequestInfo.URI;
LClient.Host := Fetch(S, ':', True);
LClient.Port := StrToIntDef(S, 443);


LClient.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(LClient);


LClient.ConnectTimeout := 5000;



// connect and activate SSL between this proxy and the target server

LClient.Connect;
try
  AResponseInfo.ResponseNo := 200;
  AResponseInfo.ResponseText := 'Connection established';
  AResponseInfo.WriteHeader;


  // activate SSL between this proxy and the client
  TIdSSLIOHandlerSocketOpenSSL(AContext.Connection.Socket).PassThrough:=false;

  // pass data between AContext.Connection.IOHandler and LClient.IOHandler
//as needed.


  // received data will be decrypted, and sent data will be encryted...
  while AContext.Connection.Connected and lclient.Connected do
  begin

    //mitm traffic modification routine      


  end;

finally

 LClient.Disconnect;

end;
 finally
 LClient.Free;

end;
 end;

This is cert switching code:

procedure TForm3.IdHTTPServer1Connect(AContext: TIdContext);
var

SSL: TIdSSLIOHandlerSocketOpenSSL;
begin

if AContext.Connection.Socket.Binding.Port = 443 then
        begin



sslh:=tIdSSLIOHandlerSocketOpenSSL(AContext.Connection.IOHandler);



          sslh.SSLOptions.CertFile:='Certificate.pem';
     sslh.SSLOptions.keyfile:='PrivateKey.pem';
    sslh.SSLOptions.RootCertFile:='certificateAuthorityCertificate.pem';
     sslh.SSLOptions.SSLVersions:=[sslvSSLv23];
     sslh.ssloptions.mode:=sslmBoth;
   sslh.OnGetPassword:= IdServerIOHandlerSSLOpenSSL1GetPassword;

     sslh.PassThrough:=false;

      TIdSSLIOHandlerSocketOpenSSL(AContext.Connection).PassThrough:=false;
       //memo2.Text:=AContext.Connection.IOHandler.ReadLn();

        end;

  end;

On a form I have a tidhttpserver and TIdServerIOHandlerSSLOpenSSL as iohandler for it.

Assign on OnQuerySSLPort event handler that unconditionally sets the VUseSSL parameter to False regardless of the APort requested. Then, in the OnConnect event, if the AContext.Connection.Socket.Binding.Port property is 443 (or whatever port you want to use HTTPS on), you can typecast the AContext.Connection.IOHandler property to TIdSSLIOHandlerSocketBase (or descendant, like TIdSSLIOHandlerSocketOpenSSL if using OpenSSL), configure its certificates as needed, and then set its PassThrough property to False to complete the SSL/TLS handshake.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM