Quantcast
Channel: Active questions tagged https - Stack Overflow
Viewing all articles
Browse latest Browse all 1516

Error 'Could not load certificate' when load a self-signed certificate into a Indy web server

$
0
0

I want to get a token from a desktop app that calls an OAuth2 authentication server that requires an HTTPS connection for the callback.

For this, I created a local Indy web server and use a self-signed SSL certificate created with Indy and OpenSSL after many discussions with ChatGPT - I have already been informed :) That's a great way to write bad code!

The error is:

raised exception class EIdOSSLLoadingCertError with message 'Could not load certificate. error:0D07209B:asn1 encoding routines:ASN1_get_object:too long'.

I assume that the certificate was not generated correctly

The app code is as follows:

type  TForm2 = class(TForm)    ...    Memo1: TMemo;    btnLoginANAF: TButton;    RESTClient1: TRESTClient;    RESTRequest1: TRESTRequest;    RESTResponse1: TRESTResponse;    Label1: TLabel;    procedure Label1DblClick(Sender: TObject);    procedure btnLoginANAFClick(Sender: TObject);    procedure Label1DblClick(Sender: TObject);    procedure btnLoginANAFClick(Sender: TObject);    procedure FormCreate(Sender: TObject);    procedure FormDestroy(Sender: TObject);  private    FHTTPServer: TIdHTTPServer;    FIOHandler: TIdServerIOHandlerSSLOpenSSL;    FAuthCode: string;    procedure StartLocalServer;    procedure StopLocalServer;    procedure HandleRequest(AContext: TIdContext;      ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);    function RequestAccessToken(AuthCode: string): Boolean;  public    { Public declarations }  end;var  Form2: TForm2;const  ...implementation{$R *.dfm}...procedure TForm2.FormCreate(Sender: TObject);begin  FHTTPServer := TIdHTTPServer.Create(nil);  if IdSSLOpenSSL.LoadOpenSSLLibrary then  begin    Memo1.Lines.Add('OpenSSL version: '+ IdSSLOpenSSL.OpenSSLVersion);    Memo1.Lines.Add('');    FIOHandler := TIdServerIOHandlerSSLOpenSSL.Create(FHTTPServer);    FHTTPServer.IOHandler := FIOHandler;    // Configurarea SSL    FIOHandler.SSLOptions.CertFile := '.\CertificatTest.pem';    FIOHandler.SSLOptions.KeyFile := '.\CheiePrivata.crt';    // Același fișier ca CertFile    FIOHandler.SSLOptions.RootCertFile := '';    // Nu este necesar pentru certificat auto-semnat    FIOHandler.SSLOptions.Mode := sslmServer;    FIOHandler.SSLOptions.VerifyMode := [];    FIOHandler.SSLOptions.VerifyDepth := 0;  end  else    raise Exception.Create(IdSSLOpenSSLHeaders.WhichFailedToLoad());  StartLocalServer;end;procedure TForm2.StartLocalServer;begin  FHTTPServer.DefaultPort := 8080;  FHTTPServer.OnCommandGet := HandleRequest;  FHTTPServer.Active := True; // <-- Error Hereend;procedure TForm2.StopLocalServer;begin  FHTTPServer.Active := False;  FHTTPServer.Free;end;procedure TForm2.FormDestroy(Sender: TObject);begin  StopLocalServer;end;procedure TForm2.HandleRequest(AContext: TIdContext;  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);var  Code: string;begin  if ARequestInfo.Document = '/callback' then  begin    Code := ARequestInfo.Params.Values['code'];    if Code <> '' then    begin      FAuthCode := Code;      AResponseInfo.ContentText :='Successful authorization. You can close this window.';      if RequestAccessToken(Code) then      begin        // Successful authorization. You can close this window.)        Memo1.Lines.Add('Successful authorization. AuthCode='+ Code)      end;    end    else    begin      AResponseInfo.ContentText := 'Error: The authorization code was not received.';    end;  end  else  begin    AResponseInfo.ResponseNo := 404;    AResponseInfo.ContentText := 'Page not found';  end;end;function TForm2.RequestAccessToken(AuthCode: string): Boolean;var  Response: TJSONObject;  AccessToken: string;begin  Result := False;  RESTClient1.BaseURL := TOKEN_ENDPOINT;  RESTRequest1.Method := rmPOST;  RESTRequest1.Params.Clear;  RESTRequest1.Params.AddItem('grant_type', 'authorization_code');  RESTRequest1.Params.AddItem('code', AuthCode);  RESTRequest1.Params.AddItem('redirect_uri', REDIRECT_URI);  RESTRequest1.Params.AddItem('client_id', CLIENT_ID);  RESTRequest1.Params.AddItem('client_secret', CLIENT_SECRET);  try    RESTRequest1.Execute;    if RESTResponse1.StatusCode = 200 then    begin      Response := RESTResponse1.JSONValue as TJSONObject;      AccessToken := Response.GetValue('access_token').Value;      // Save or use AccessToken as needed      Memo1.Lines.Add('Acces token:');      Memo1.Lines.Add(AccessToken);      Result := True;    end;  except    on E: Exception do    begin      ShowMessage('Error obtaining the access token: '+ E.Message);    end;  end;end;procedure TForm2.Label1DblClick(Sender: TObject);  procedure GenerateSelfSignedCertificate(const AFileName: string);    procedure GenerateRandomSerialNumber(SerialNumber: PASN1_INTEGER);    var      RandomValue: Integer;      I: Integer;    begin      RandomValue := 0;      for I := 1 to 4 do      begin        RandomValue := (RandomValue shl 8) or Random(256);      end;      // We make sure that the number is positive      RandomValue := RandomValue and $7FFFFFFF;      // We set the serial number      if ASN1_INTEGER_set(SerialNumber, RandomValue) = 0 then        raise Exception.Create('Error setting the serial number');    end;    function DateToASN1_TIME(const ADate: TDateTime): PASN1_TIME;    var      AStruct: TSystemTime;      ASN1_Time: PASN1_TIME;    begin      DateTimeToSystemTime(ADate, AStruct);      ASN1_Time := ASN1_TIME_set(nil, SystemTimeToDateTime(AStruct));      Result := ASN1_Time;    end;  var    Cert: PX509;    PrivateKey: PEVP_PKEY;    SerialNumber: PASN1_INTEGER;    Name: PX509_NAME;    BioCert, BioKey: PBIO;    NotBefore, NotAfter: TDateTime;    LoadOpenSSLLibraryErr: string;  begin    // Create new certificate    try       Cert := X509_new;    except      raise Exception.Create('Error creating certificate X509')    end;    try      // New RSA Private Key Generation      PrivateKey := EVP_PKEY_new;      try        if EVP_PKEY_assign(PrivateKey, EVP_PKEY_RSA,          PByte(RSA_generate_key(2048, RSA_F4, nil, nil))) = 0 then          raise Exception.Create('Error generating private key');        // Certificate Version Setting (X509 v3)        X509_set_version(Cert, 2);        // Random Serial Number Generation        SerialNumber := ASN1_INTEGER_new;        if SerialNumber = nil then          raise Exception.Create('Error creating ASN1_INTEGER');        try          GenerateRandomSerialNumber(SerialNumber);          if X509_set_serialNumber(Cert, SerialNumber) = 0 then            raise Exception.Create              ('Error setting the serial number for the certificate');        finally          ASN1_INTEGER_free(SerialNumber);        end;        // Set the start and end date of the certificate        NotBefore := Now - 1; // The certificate is valid from yesterday        NotAfter := NotBefore + 364; // The certificate is valid for one year        X509_set_notBefore(Cert, DateToASN1_TIME(NotBefore));        X509_set_notAfter(Cert, DateToASN1_TIME(NotAfter));        // Public Key Setting        X509_set_pubkey(Cert, PrivateKey);        // Setting Issuer and Subject Name (localhost)        Name := X509_get_subject_name(Cert);        X509_NAME_add_entry_by_txt(Name, 'CN', MBSTRING_ASC,          PAnsiChar('localhost'), -1, -1, 0);        X509_set_issuer_name(Cert, Name);        // Certificate Signing        if X509_sign(Cert, PrivateKey, EVP_sha256) = 0 then          raise Exception.Create('Error signing the certificate');        // Save certificate to PEM file        BioCert := BIO_new_file(PAnsiChar(AnsiString(AFileNamePem)), 'w+');        try          if PEM_write_bio_X509(BioCert, Cert) = 0 then            raise Exception.Create              ('Error saving certificate to PEM file');        finally          BIO_free(BioCert);        end;        // Save Private Key to CRT File        BioKey := BIO_new_file(PAnsiChar(AnsiString(AFileNameCrt)), 'w+');        try          if PEM_write_bio_PrivateKey(BioKey, PrivateKey, nil, nil, 0, nil,            nil) = 0 then            raise Exception.Create              ('Error saving private key to CRT file');        finally          BIO_free(BioKey);        end;      finally        EVP_PKEY_free(PrivateKey);      end;    finally      X509_free(Cert);    end;  end;begin  GenerateSelfSignedCertificate('.\CertificatTest.pem', '.\CheiePrivata.crt');  ShowMessage('Certificate and private key successfully generated!');end;procedure TForm2.btnLoginANAFClick(Sender: TObject);var  URL: string;begin  URL := AUTH_ENDPOINT +'?response_type=code'+'&client_id='+    TNetEncoding.URL.Encode(CLIENT_ID) +'&redirect_uri='+    TNetEncoding.URL.Encode(REDIRECT_URI) +'&scope='+    TNetEncoding.URL.Encode(SCOPE);  ShellExecute(0, 'open', PChar(URL), nil, nil, SW_SHOWNORMAL);end;...InitializationRandomize;IdOpenSSLSetLibPath(ExtractFilePath(Application.ExeName));end.

Viewing all articles
Browse latest Browse all 1516

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>