I think I found a bug in the uROSocket.pas unit, here:
procedure TROSocketOpenSSL.LoadCertificate;
begin
InternalLoadCertificate(fCertFile, fCertFile);
end;
In this form, an error EROOpenSSLApi occurs in the nested call to the TROSocketOpenSSL.InternalLoadCertificate method, here:
procedure TROSocketOpenSSL.InternalLoadCertificate(aCert, aKey: string);
var
l_cert: TBytes;
begin
{$IFDEF LOG}Log(Format(' ->TROSocketOpenSSL.InternalLoadCertificate(%s, %s)', [aCert, aKey])); try{$ENDIF}
if aCert <> '' then begin
l_cert := StringToUTF8Bytes(aCert + #0);
if (SSL_CTX_use_certificate_chain_file(fCTX, @l_cert[0]) <> 1) then begin
//"Error loading certificate from file"
SSLCheck;
Exit;
end;
l_cert := StringToUTF8Bytes(aKey + #0);
!!!!!!!! ---> this fails
if (SSL_CTX_use_PrivateKey_file(fCTX, @l_cert[0], SSL_FILETYPE_PEM) <> 1) then begin
//"Error loading private key from file"
SSLCheck;
Exit;
end;
if SSL_CTX_check_private_key(fCTX) <> 1 then begin
SSLCheck;
Exit;
end;
end;
{$IFDEF LOG}finally Log(' <-TROSocketOpenSSL.InternalLoadCertificate'); end;{$ENDIF}
end;
…because the value of aKey is the same as the value of aCert. I think it’s just a typo, but the consequences are quite fatal - in case of using an externally referenced certificate in the file, the server transport cannot be activated properly.
The TROSocketOpenSSL.LoadCertificate method should probably look like this:
procedure TROSocketOpenSSL.LoadCertificate;
begin
InternalLoadCertificate(fCertFile, {fCertFile} fCAKeyFile);
end;
According to your answer, meaning of CAFile, CAKeyFile and CertFile values in TROOpenSSL class is a bit different from meaning of RootCertFile, CertFile, KeyFile values in TIdSSLOptions class.
TROOpenSSL.CertFile value expects certificate to be present together with private key, but in the TIdSSLOptions class certificate must be stored in the CertFile value and the private key in the KeyFile value, i.e. separately. Is this correct?
Yes, I can read and understand comments in the code. I wanted to point out differences that might be important to other developers who have been using Indy and want to switch to TROHTTPServer… like me, for example.