Recent

Author Topic: How to generate certificates example the easy way  (Read 3613 times)

Thaddy

  • Hero Member
  • *****
  • Posts: 16168
  • Censorship about opinions does not belong here.
How to generate certificates example the easy way
« on: March 01, 2024, 06:53:34 pm »
How about this, can be improved (factor out the write loop, save to file, etc)
but it generates a key pair that is accepted, apart from the CA part in browsers of course, but you know that.
Code: Pascal  [Select][+][-]
  1. program testcert;
  2. {$mode objfpc}{$I-}{$H+}
  3. uses
  4.    sysutils, base64, classes, sslbase, openssl, fpopenssl;
  5.  
  6. var
  7.    X509:TOpenSSLX509Certificate;
  8.    certkey:TCertAndKey;
  9.    pk,cr:TBytes;
  10.    e:ansistring;
  11.    i:integer;
  12. begin
  13.    X509:=TOpenSSLX509Certificate.Create;
  14.    try
  15.      certkey:=X509.CreateCertificateAndKey;
  16.      cr:=certkey.certificate;
  17.      pk:=certkey.privatekey;
  18.      setstring(e,Pchar(certkey.Certificate),length(certkey.Certificate));
  19.      e:=EncodeStringBase64(e);
  20.      writeln('-----BEGIN CERTIFICATE-----');
  21.      for i :=1 to length(e) do
  22.      begin
  23.        write(e[i]);
  24.        if (i mod 64 = 0) or (i >=length(e)) then writeln;
  25.      end;
  26.      writeln('-----END CERTIFICATE-----');
  27.      writeln;
  28.      setstring(e,PAnsiChar(certkey.PrivateKey),length(certkey.PrivateKey));
  29.      e:=EncodeStringBase64(e);
  30.      writeln('-----BEGIN RSA PRIVATE KEY-----');
  31.      for i :=1 to length(e) do
  32.      begin
  33.        write(e[i]);
  34.        if (i mod 64 = 0) or (i >=length(e)) then writeln;
  35.      end;
  36.      writeln('-----END RSA PRIVATE KEY-----');
  37.    finally
  38.      X509.Free;
  39.    end;
  40. end.
It is a 40 liner, but be careful. The certificates are accepted, though.
I got fed up with complex code, as usual, and this is a 40 liner.
Users must in reality split up the code to cer and pem. But this is how it works, provided openssl is installed correctly. (cross platform tested)
« Last Edit: March 11, 2024, 08:20:42 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8027
Re: How to generate certificates example the easy way
« Reply #1 on: March 02, 2024, 09:34:51 am »
I like it, and I can assure you that I'd be the last person to criticise you for putting straightforward code into an example.

Can I ask for a bit more: if you wanted to get a fingerprint of a file, sign this with the private key you've just generated, and later validate it with the corresponding public key, how would you go about it?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 16168
  • Censorship about opinions does not belong here.
Re: How to generate certificates example the easy way
« Reply #2 on: March 02, 2024, 09:46:41 am »
Mark, there is other code in that default tree that I am exploring now.
I might be able to come up with a clear solution for your request.
Point is, there is a lot of code available to us that is largely unexplored.
If I smell bad code it usually is bad code and that includes my own code.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8027
Re: How to generate certificates example the easy way
« Reply #3 on: March 02, 2024, 01:43:24 pm »
It's certainly interesting, and you've got a better grounding in this than I have.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

TRon

  • Hero Member
  • *****
  • Posts: 3623
Re: How to generate certificates example the easy way
« Reply #4 on: March 02, 2024, 02:20:23 pm »
It's certainly interesting, and you've got a better grounding in this than I have.
+1

Thank you for that example Thaddy. My problem is more that the interwebs is scattered with examples using deprecated functionality (not to mention that openssl documentation is ... of another category  :)  ) . It might be able to work fantastic but there is a lot of functionality missing our header files in that case (I do not even have the capacity/knowledge to be able to tell whether that is a good or bad thing).
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

Thaddy

  • Hero Member
  • *****
  • Posts: 16168
  • Censorship about opinions does not belong here.
Re: How to generate certificates example the easy way
« Reply #5 on: March 02, 2024, 02:35:07 pm »
The headers in trunk are up to date enough.
I chose simply Michael's defaults in fpopenssl.
but the class can set the properties, so that is OK.

There will be updates, though.
I have a lot to play with, including some small patches for fcl-net. (TLS1.3 and higher support)
If I smell bad code it usually is bad code and that includes my own code.

Fibonacci

  • Hero Member
  • *****
  • Posts: 602
  • Internal Error Hunter
Re: How to generate certificates example the easy way
« Reply #6 on: March 02, 2024, 03:28:34 pm »
Why fpopenssl.pp by default has {$DEFINE DUMPCERT} which dumps the cert to /tmp/x509.txt or C:\temp\x509.txt? I dont think this is what is expected.

Thaddy

  • Hero Member
  • *****
  • Posts: 16168
  • Censorship about opinions does not belong here.
Re: How to generate certificates example the easy way
« Reply #7 on: March 02, 2024, 03:34:56 pm »
The unit is quite new. That should not be enabled by default, I agree.
Anyway I added a dot.. :) And submitted a bug report.
edit
Already fixed in trunk. Thank you Michael!
« Last Edit: March 02, 2024, 05:56:20 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

Fibonacci

  • Hero Member
  • *****
  • Posts: 602
  • Internal Error Hunter
Re: How to generate certificates example the easy way
« Reply #8 on: March 02, 2024, 08:20:33 pm »
And submitted a bug report.
edit
Already fixed in trunk. Thank you Michael!

Where is thank you for me? I found this "bug" :D

BTW. Is this unit really that new? That define was there since 5 years.

Thaddy

  • Hero Member
  • *****
  • Posts: 16168
  • Censorship about opinions does not belong here.
Re: How to generate certificates example the easy way
« Reply #9 on: March 02, 2024, 08:49:47 pm »
Well, I found it too, but  thanks... ;D :D
If I smell bad code it usually is bad code and that includes my own code.

BSaidus

  • Hero Member
  • *****
  • Posts: 596
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Re: How to generate certificates example the easy way
« Reply #10 on: March 15, 2024, 11:17:58 pm »
Hello.
Thanks @Thaddy for this code.
I indeed generate a pair of certificate, just want to informe while decoding the public cert, I do not take account of dates ( ValidFrom, ValidTo)
Code: Pascal  [Select][+][-]
  1. program testcert;
  2.  
  3. {$mode objfpc}
  4. {$I-}
  5. {$H+}
  6.  
  7.  
  8. uses
  9.    sysutils,
  10.    DateUtils,
  11.    base64,
  12.    classes,
  13.    sslbase,
  14.    openssl,
  15.    fpopenssl;
  16.  
  17.  
  18.  
  19. var
  20.    XL509    : TOpenSSLX509Certificate;
  21.    LCertkey : TCertAndKey;
  22.    LPk ,LCr : TBytes;
  23.    LE       : AnsiString;
  24.    I        : Integer;
  25.    LNow, L10Now: TDateTime;
  26. begin
  27.  
  28.    LNow := TDateTime( Now() );
  29.    L10Now := TDateTime( IncYear(Now(), 10) );
  30.  
  31.    XL509 := TOpenSSLX509Certificate.Create;
  32.    XL509.CommonName   := 'uccenos.net';
  33.    XL509.Country      := 'DZ';
  34.    XL509.HostName     := 'uc1.uccenos.net';
  35.    XL509.Organization := 'uccen';
  36.    XL509.ValidFrom    := LNow;
  37.    XL509.ValidTo      := L10Now;
  38.  
  39.    //XL509.Version      := 1;
  40.    XL509.KeySize      := 2048;
  41.  
  42.    try
  43.  
  44.      LCertkey := XL509.CreateCertificateAndKey;
  45.  
  46.  
  47.  
  48.      LCr      := LCertkey.certificate;
  49.      LPk      := LCertkey.privatekey;
  50.      SetString( LE, PChar(LCertkey.Certificate), Length(LCertkey.Certificate) );
  51.      LE       := EncodeStringBase64(LE);
  52.  
  53.      writeln('-----BEGIN CERTIFICATE-----');
  54.  
  55.      for I :=1 to length(LE) do
  56.      begin
  57.        write(LE[I]);
  58.        if (I mod 64 = 0) or (I >=length(LE)) then writeln;
  59.      end;
  60.  
  61.      writeln('-----END CERTIFICATE-----');
  62.      writeln;
  63.  
  64.      SetString( LE, PAnsiChar(LCertkey.PrivateKey), Length(LCertkey.PrivateKey) );
  65.      LE       := EncodeStringBase64(LE);
  66.  
  67.      writeln('-----BEGIN RSA PRIVATE KEY-----');
  68.  
  69.      for I :=1 to length(LE) do
  70.      begin
  71.        write(LE[I]);
  72.        if (I mod 64 = 0) or (I >=length(LE)) then writeln;
  73.      end;
  74.  
  75.      writeln('-----END RSA PRIVATE KEY-----');
  76.  
  77.    finally
  78.  
  79.      XL509.Free;
  80.  
  81.    end;
  82.  
  83. end.                    
  84.  
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

toby

  • Sr. Member
  • ****
  • Posts: 270
Re: How to generate certificates example the easy way
« Reply #11 on: March 17, 2024, 09:31:31 pm »
BSaidus


adding writeln for the following variables gives
lnow :  4.5368843078414349E+004  l10now :  4.9020843078414349E+004
xl509.validfrom :  4.5368843078414349E+004  xl509.validto :  4.9020843078414349E+004

but using
openssl x509 -in x509.txt -text -noout
gives Validity
            Not Before: Bad time value
            Not After : Bad time value

using
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout x509.txt -out x509.txt
gives good dates with
openssl x509 -in x509.txt -text -noout

openssl version   gives
OpenSSL 3.0.5 5 Jul 2022 (Library: OpenSSL 3.0.5 5 Jul 2022)


Fibonacci

  • Hero Member
  • *****
  • Posts: 602
  • Internal Error Hunter
Re: How to generate certificates example the easy way
« Reply #12 on: March 17, 2024, 09:39:53 pm »
Works for me

Code: Pascal  [Select][+][-]
  1. openssl x509 -in x509.txt -text -noout

Code: Pascal  [Select][+][-]
  1.         Version: 1 (0x0)
  2.         Serial Number: 10 (0xa)
  3.         Signature Algorithm: sha1WithRSAEncryption
  4.         Issuer: C = DZ, CN = uc1.uccenos.net, O = uccen
  5.         Validity
  6.             Not Before: Mar 17 21:39:13 2024 GMT
  7.             Not After : Mar 17 21:39:13 2034 GMT
  8.         Subject: C = DZ, CN = uc1.uccenos.net, O = uccen

DLL version OpenSSL 3.0.1 14 Dec 2021 (writeln(OpenSSLGetVersion(0)))
CLI version OpenSSL 1.1.1l 24 Aug 2021
« Last Edit: March 17, 2024, 09:48:47 pm by Fibonacci »

toby

  • Sr. Member
  • ****
  • Posts: 270
Re: How to generate certificates example the easy way
« Reply #13 on: March 17, 2024, 10:16:23 pm »
writeln(now);
LNow := TDateTime(Now());
writeln(lnow);
both writelns give the same 'now' output - shouldn't tdatetime(now) convert to a readable date/time?

openssl x509 -in x509.txt -text -noout
        Version: 1 (0x0)
        Serial Number: 10 (0xa)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C = DZ, CN = uc1.uccenos.net, O = uccen
        Validity
            Not Before: Bad time value
            Not After : Bad time value
        Subject: C = DZ, CN = uc1.uccenos.net, O = uccen


« Last Edit: March 17, 2024, 10:23:15 pm by toby »

Fibonacci

  • Hero Member
  • *****
  • Posts: 602
  • Internal Error Hunter
Re: How to generate certificates example the easy way
« Reply #14 on: March 17, 2024, 10:23:45 pm »
writeln(now);
LNow := TDateTime(Now());
writeln(lnow);
both writelns give the same 'now' output - shouldn't tedatetime(now) convert to a readable date/time?

No. Why should it if both Now() and LNow return the same type? Now() is already TDateTime, dont cast it to TDateTime, it wont do anything. You can use DateTimeToStr() from SysUtils to convert it to a readable format.

 

TinyPortal © 2005-2018