Jump to content
José Antonio

Indy http.post with certificate: Could not load key

Recommended Posts

Good morning, in Delphi 10.3, when trying to make an https.post request with a certificate, I get the error: 

EIdOSSLLoadingKeyError with message: 'could not load key, check password. error: 0B080074:x509 certificate routines:X509_check_private_key:key values mismatch'.

Thanks for the help.

Share this post


Link to post

I never use password with private key, but i think that you should use the OnGetPassword event of the IOSSLHandler that you use.

Assign the correct value to "Password" parameter of the event.

 

Bye

 

 

  • Like 1

Share this post


Link to post

If I don't send the private key, I get the error 'HTTP/1.1 421 Misdirected Request'. My code:

 

  data := TIdMultiPartFormDataStream.Create;
   http := TIdHTTP.Create;
   IdSSLIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create;
   try
     IdSSLIOHandler.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
     IdSSLIOHandler.SSLOptions.Mode := sslmClient;
     IdSSLIOHandler.SSLOptions.Method := sslvSSLv23;
     IdSSLIOHandler.SSLOptions.CertFile := 'certificate.pem';
     //IdSSLIOHandler.SSLOptions.KeyFile := 'privatekey.pem';

     IdSSLIOHandler.OnStatusInfoEx := IdSSLIOHandlerSocketOpenSSL1StatusInfoEx;
     IdSSLIoHandler.OnGetPassword := getPassword;
     http.IOHandler := IdSSLIOHandler;

 

     http.ReadTimeout := READ_TIMEOUT;
     http.Request.ContentEncoding := 'utf-8';
     http.Request.ContentType := 'application/xml';
     http.Request.CharSet := 'utf-8';

     data.AddFile('UploadedXml', fileXml, '');
     try
       queAnswer := http.Post('https://xxxxxxxxxxxxxxxxx', data);

     except
       on e:Exception do begin
         ShowMessage(e.Message);
       end;
     end;

   finally
     http.Disconnect;
     http.Free;
     data.Free;
     IdSSLIOHandler.Free;
   end;

Edited by José Antonio

Share this post


Link to post

Use a certificate with Http client is normally not needed, but If you must use it (like in authentication purpose) then you must use also use private key.

(uncommented //IdSSLIOHandler.SSLOptions.KeyFile := 'privatekey.pem'; ) and in the GetPassword event write:

procedure xxx.GetPassword(var Password: string);
begin
  Password = YourPasswordForPrivateKey;
end;

The private key and the password of course will NOT be sent to server.

Remember that the password should not hard coded in the executable, but should be ask to operator and used like a cache (expire with time or after N. use).

Bye

 

Share this post


Link to post

The private key does not have a password. If I try to send again with the KeyFile uncommented it still gives me the same error.

OnGetPassword event is never executed.

 

My code:

 

  data := TIdMultiPartFormDataStream.Create;
   http := TIdHTTP.Create;
   IdSSLIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create;
   try
     IdSSLIOHandler.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
     IdSSLIOHandler.SSLOptions.Mode := sslmClient;
     IdSSLIOHandler.SSLOptions.Method := sslvSSLv23;
     IdSSLIOHandler.SSLOptions.CertFile := 'certificate.pem';
     IdSSLIOHandler.SSLOptions.KeyFile := 'privatekey.pem';

     IdSSLIOHandler.OnStatusInfoEx := IdSSLIOHandlerSocketOpenSSL1StatusInfoEx;
     IdSSLIoHandler.OnGetPassword := getPassword;
     http.IOHandler := IdSSLIOHandler;

 

     http.ReadTimeout := READ_TIMEOUT;
     http.Request.ContentEncoding := 'utf-8';
     http.Request.ContentType := 'application/xml';
     http.Request.CharSet := 'utf-8';

     data.AddFile('UploadedXml', fileXml, '');
     try
       queAnswer := http.Post('https://xxxxxxxxxxxxxxxxx', data);

     except
       on e:Exception do begin
         ShowMessage(e.Message);
       end;
     end;

   finally
     http.Disconnect;
     http.Free;
     data.Free;
     IdSSLIOHandler.Free;
   end;

 

The event:

procedure TTicketBai.getPassword(var Password: string);
begin
  Password := 'thepassword';
end;

 

Share this post


Link to post
  On 11/27/2023 at 9:13 AM, José Antonio said:

The private key does not have a password. If I try to send again with the KeyFile uncommented it still gives me the same error.

OnGetPassword event is never executed.

If the KeyFile not has any password, then event will not be trigger, but if you use a certificate you must use also the keyfile.

The error you'll refer here is the original (EIdOSSLLoadingKeyError with message: 'could not load key, check password. error: 0B080074:x509 certificate routines:X509_check_private_key:key values mismatch') ?

 

May be the KeyFile and and Certificate don't match ....

 

Also, suggestion for usage: don't use "Method" and "SSLVersions" of SSLIOHandler together, they override each others. Use only "SSLVersions".

Share this post


Link to post
  On 11/27/2023 at 11:41 AM, José Antonio said:

I have created the files again from the .pfx and now I get the error: 'HTTP/1.1 421 Misdirected Request'

Any suggestions?
Thank you

For this I have no suggestions .... seems that something about server configuration (SAN reference of certificate wrong or with *) but i have not experience with this.

You can try this: https://www.ssllabs.com/ssltest/ to verify the site (they expose the anomalies).

 

Bye

Edited by DelphiUdIT

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×