Recent

Author Topic: Creating Self Signed Certificates using LibCrypto-3.dll from openssl  (Read 1017 times)

Trax

  • Newbie
  • Posts: 6
I'm having trouble with following bits in this code.

  X509_set_serialNumber(x, serial);
  X509_sign(x, pkey, nil);
and
  PEM_write_bio_X509(PAnsiChar('cert.pem'), x);

I think the last two could be related to the first.

Code: Pascal  [Select][+][-]
  1. program createselfsignedcert;
  2.  
  3. {$MODE OBJFPC}
  4. {$LONGSTRINGS ON}
  5.  
  6. uses
  7.   SysUtils, Windows;
  8.  
  9. const
  10.   OPENSSL_LIB = 'libcrypto-3.dll';
  11.   MBSTRING_FLAG = $1000;
  12.   MBSTRING_ASC = MBSTRING_FLAG or 1;
  13.   MBSTRING_BMP = MBSTRING_FLAG or 2;
  14.   MBSTRING_UNIV = MBSTRING_FLAG or 3;
  15.   MBSTRING_UTF8 = MBSTRING_FLAG or 4;
  16.  
  17. type
  18.   PX509 = Pointer;
  19.   PEVP_PKEY = Pointer;
  20.   PASN1_TIME = Pointer;
  21.   pBIO=PAnsiChar;
  22.  
  23. function X509_new: PX509; cdecl; external OPENSSL_LIB name 'X509_new';
  24. procedure X509_free(x: PX509); cdecl; external OPENSSL_LIB name 'X509_free';
  25. function EVP_PKEY_new: PEVP_PKEY; cdecl; external OPENSSL_LIB name 'EVP_PKEY_new';
  26. procedure EVP_PKEY_free(pkey: PEVP_PKEY); cdecl; external OPENSSL_LIB name 'EVP_PKEY_free';
  27. function EVP_PKEY_set1_RSA(key: pEVP_PKEY; rsa: pointer): integer; cdecl; external OPENSSL_LIB name 'EVP_PKEY_set1_RSA';
  28. function X509_set_version(x: PX509; version: Integer): Integer; cdecl; external OPENSSL_LIB name 'X509_set_version';
  29. procedure X509_gmtime_adj(s: PASN1_TIME; adj: Integer); cdecl; external OPENSSL_LIB name 'X509_gmtime_adj';
  30. function ASN1_UTCTIME_new: PASN1_TIME; cdecl; external OPENSSL_LIB name 'ASN1_UTCTIME_new';
  31. procedure ASN1_UTCTIME_free(a: PASN1_TIME); cdecl; external OPENSSL_LIB name 'ASN1_UTCTIME_free';
  32. function X509_get_serialNumber(x: PX509): Integer; cdecl; external OPENSSL_LIB name 'X509_get_serialNumber';
  33. procedure X509_set_serialNumber(x: PX509; serial: Integer); cdecl; external OPENSSL_LIB name 'X509_set_serialNumber';
  34. function X509_NAME_new: Pointer; cdecl; external OPENSSL_LIB name 'X509_NAME_new';
  35. procedure X509_NAME_free(n: Pointer); cdecl; external OPENSSL_LIB name 'X509_NAME_free';
  36. function X509_NAME_add_entry_by_txt(name: Pointer; field: PAnsiChar; _type: Integer; bytes: PAnsiChar; len: Integer; location, _default: Integer): integer; cdecl; external OPENSSL_LIB name 'X509_NAME_add_entry_by_txt';
  37. function X509_set_issuer_name(x: PX509; name: Pointer): Integer; cdecl; external OPENSSL_LIB name 'X509_set_issuer_name';
  38. function X509_set_subject_name(x: PX509; name: Pointer): Integer; cdecl; external OPENSSL_LIB name 'X509_set_subject_name';
  39. function X509_set_pubkey(x: PX509; pkey: PEVP_PKEY): integer; cdecl; external OPENSSL_LIB name 'X509_set_pubkey';
  40. procedure BN_free(a: Pointer); cdecl; external OPENSSL_LIB name 'BN_free';
  41. function BN_new: Pointer; cdecl; external OPENSSL_LIB name 'BN_new';
  42. function RSA_generate_key(bits: Integer; e: Integer; callback: Pointer; arg: Pointer): Pointer; cdecl; external OPENSSL_LIB name 'RSA_generate_key';
  43. procedure RSA_free(r: Pointer); cdecl; external OPENSSL_LIB name 'RSA_free';
  44. function BIO_new_file(filename: PChar; mode: PChar): Pointer; cdecl; external OPENSSL_LIB name 'BIO_new_file';
  45. function X509_sign(x: PX509; pkey: PEVP_PKEY; md: Pointer): Integer; cdecl; external OPENSSL_LIB name 'X509_sign';
  46. function EVP_PKEY_assign(pkey: PEVP_PKEY; typ: integer; key: pointer): integer; cdecl; external OPENSSL_LIB name 'EVP_PKEY_assign';
  47. function PEM_write_bio_X509(bp: pBIO; x: pX509): integer; cdecl; external OPENSSL_LIB name 'PEM_write_bio_X509';
  48. function PEM_write_bio_PrivateKey(bp: pointer; pkey: PEVP_PKEY; enc: pointer; kstr: pointer; klen: integer; pem_password_cb: pointer; u: pointer): integer; cdecl; external OPENSSL_LIB name 'PEM_write_bio_PrivateKey';
  49.  
  50. procedure CreateCertificate;
  51. var
  52.   x: PX509;
  53.   pkey: PEVP_PKEY;
  54.   serial: Integer;
  55.   name: Pointer;
  56.   time: PASN1_TIME;
  57.   rsa: Pointer;
  58.   bio: Pointer;
  59. begin
  60.   // Create a new X509 structure
  61.   x := X509_new;
  62.   if not Assigned(x) then
  63.     raise Exception.Create('Error creating X509 structure');
  64.  
  65.   // Set the version of the certificate (X509v3)
  66.   if X509_set_version(x, 2) <> 1 then
  67.     raise Exception.Create('Error setting X509 version');
  68.  
  69.   // Generate key pair
  70.   pkey := EVP_PKEY_new;
  71.   if not Assigned(pkey) then
  72.     raise Exception.Create('Error creating private key');
  73.  
  74.   rsa := RSA_generate_key(2048, $10001, nil, nil);
  75.   if not Assigned(rsa) then
  76.     raise Exception.Create('Error generating RSA key');
  77. {  else      // Test to see if the private keys are written, it breaks EVP_PKEY_set1_RSA(pkey, rsa)
  78.     begin
  79.       if EVP_PKEY_assign(pkey, 6, rsa)<=0 then
  80.         raise Exception.Create('Error assigning RSA key to EVP_PKEY')
  81.       else
  82.         begin
  83.             bio:= BIO_new_file('privatea_key.pem', 'w');
  84.             if bio = nil then
  85.               raise Exception.Create('Error creating BIO for file')
  86.             else
  87.               if PEM_write_bio_PrivateKey(bio, pkey, nil, nil, 0, nil, nil) <= 0 then
  88.                 raise Exception.Create('Error writing private key to file');
  89.         end;
  90.     end;    }
  91.  
  92.   // Assign the generated key to the pkey structure
  93.   if EVP_PKEY_set1_RSA(pkey, rsa) <> 1 then
  94.     raise Exception.Create('Error assigning RSA to pkey');
  95.  
  96.   // Set the private key for the certificate
  97.   if X509_set_pubkey(x, pkey) <> 1 then
  98.     raise Exception.Create('Error setting public key');
  99.  
  100.   // Create a serial number
  101.   serial := Random($FFFFFFFF);
  102.   X509_set_serialNumber(x, serial);
  103.  
  104.   // Set validity period (e.g., one year from now)
  105.   time := ASN1_UTCTIME_new;
  106.   if not Assigned(time) then
  107.     raise Exception.Create('Error creating time structure');
  108.  
  109.   X509_gmtime_adj(time, 60 * 60 * 24 * 365); // One year from now
  110.  
  111.   // Set the issuer and subject names (you can customize these)
  112.   name := X509_NAME_new;
  113.   if not Assigned(name) then
  114.     raise Exception.Create('Error creating name structure');
  115.  
  116.   X509_NAME_add_entry_by_txt(name, 'C', MBSTRING_ASC, PAnsiChar('US'), Length('US'), -1, -1);
  117.   X509_NAME_add_entry_by_txt(name, 'ST', MBSTRING_ASC, PAnsiChar('California'), Length('California'), -1, -1);
  118.   X509_NAME_add_entry_by_txt(name, 'L', MBSTRING_ASC, PAnsiChar('San Francisco'), Length('San Francisco'), -1, -1);
  119.   X509_NAME_add_entry_by_txt(name, 'O', MBSTRING_ASC, PAnsiChar('My Organization'), Length('My Organization'), -1, -1);
  120.   X509_NAME_add_entry_by_txt(name, 'OU', MBSTRING_ASC, PAnsiChar('My Organizational Unit'), Length('My Organizational Unit'), -1, -1);
  121.   X509_NAME_add_entry_by_txt(name, 'CN', MBSTRING_ASC, PAnsiChar('localhost'), Length('localhost'), -1, -1);
  122.  
  123.   // Set the issuer and subject names in the certificate
  124.   if X509_set_issuer_name(x, name) <> 1 then
  125.     raise Exception.Create('Error setting issuer name');
  126.  
  127.   if X509_set_subject_name(x, name) <> 1 then
  128.     raise Exception.Create('Error setting subject name');
  129.  
  130.   // Sign the certificate with the private key
  131.   if X509_sign(x, pkey, nil) <> 1 then
  132.     raise Exception.Create('Error signing certificate');
  133.  
  134.   // Save the certificate to a file (e.g., cert.pem)
  135.   if PEM_write_bio_X509(PAnsiChar('cert.pem'), x) <> 1 then
  136. //  if SSL_write_file('cert.pem', x) <> 1 then
  137.     raise Exception.Create('Error writing certificate to file');
  138.  
  139.   // Free allocated resources
  140.   X509_free(x);
  141.   EVP_PKEY_free(pkey);
  142.   ASN1_UTCTIME_free(time);
  143.   X509_NAME_free(name);
  144.   BN_free(rsa);
  145. end;
  146.  
  147. begin
  148.   try
  149.     CreateCertificate;
  150.     Writeln('Self-signed certificate created successfully.');
  151.   except
  152.     on E: Exception do
  153.       Writeln(E.ClassName, ': ', E.Message);
  154.   end;
  155. end.
  156.  

Thanks for any help.

Trax

  • Newbie
  • Posts: 6
Re: Creating Self Signed Certificates using LibCrypto-3.dll from openssl
« Reply #1 on: March 17, 2025, 05:19:11 am »
OPENSSL_LIB = 'libcrypto-3.dll' in the code can be changed to libcrypto.dll or libcrypto.so for linux systems.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8364
Re: Creating Self Signed Certificates using LibCrypto-3.dll from openssl
« Reply #2 on: March 17, 2025, 08:32:01 am »
OPENSSL_LIB = 'libcrypto-3.dll' in the code can be changed to libcrypto.dll or libcrypto.so for linux systems.

Thanks for that, useful to know.

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

Trax

  • Newbie
  • Posts: 6
Re: Creating Self Signed Certificates using LibCrypto-3.dll from openssl
« Reply #3 on: March 18, 2025, 09:18:07 am »
Fixed
  X509_set_serialNumber(x, serial);
Fixed this by declaring the following in the type section.
Code: Pascal  [Select][+][-]
  1.   ASN1_STRING = packed record
  2.     length: Integer;
  3.     _type: Integer;
  4.     data: PChar;
  5.     flags: LongWord;
  6.   end;
  7.  
  8.   PASN1_UTCTIME=^ASN1_UTCTIME;
  9.   ASN1_UTCTIME=ASN1_STRING;
  10.   ASN1_INTEGER=ASN1_STRING;
  11.   PASN1_INTEGER=^ASN1_STRING;
  12.  


Declared serial as a PASN1_INTEGER in the 'procedure CreateCertificate' var section;

Changed X509_set_serialNumber to the following and added two extra function calls.
Code: Pascal  [Select][+][-]
  1. procedure X509_set_serialNumber(x: PX509; serial: PASN1_INTEGER); cdecl; external OPENSSL_LIB name 'X509_set_serialNumber';
  2. function ASN1_INTEGER_new: PASN1_INTEGER; cdecl; external OPENSSL_LIB name 'ASN1_INTEGER_new';
  3. function ASN1_INTEGER_set_int64(a: PASN1_INTEGER; r: Int64): Integer; cdecl; external OPENSSL_LIB name 'ASN1_INTEGER_set_int64';
  4.  

Found the following code to generate a random serial number.

Code: Pascal  [Select][+][-]
  1. procedure GenerateRandomSerialNumber(var SerialNumber: PASN1_INTEGER);
  2. var
  3.   RandomValue: Int64;
  4.   I: Integer;
  5. begin
  6.   // We generate a 64-bit random number
  7.   RandomValue := 0;
  8.   for I := 1 to 8 do
  9.     begin
  10.       RandomValue := (RandomValue shl 8) or Random(256);
  11.     end;
  12.   // We make sure the number is positive
  13.   RandomValue := RandomValue and $7FFFFFFFFFFFFFFF;
  14.  
  15.   // We set the serial number
  16.   if ASN1_INTEGER_set_int64(SerialNumber, RandomValue) = 0 then
  17.     raise Exception.Create('Error setting serial number');
  18. end;
  19.  

and changed the X509_set_serialNumber section in 'procedure CreateCertificate' to this.
Code: Pascal  [Select][+][-]
  1.   Serial:=ASN1_INTEGER_new;
  2.   GenerateRandomSerialNumber(Serial);
  3.   X509_set_serialNumber(x509, Serial);
  4.  

Trax

  • Newbie
  • Posts: 6
Re: Creating Self Signed Certificates using LibCrypto-3.dll from openssl
« Reply #4 on: March 18, 2025, 09:23:07 am »
Oh yeah changed x in 'procedure CreateCertificate;' var section to x509.
Still having trouble with X509_sign which I think maybe related having md encryption to nil.

Trax

  • Newbie
  • Posts: 6
Re: Creating Self Signed Certificates using LibCrypto-3.dll from openssl
« Reply #5 on: March 21, 2025, 11:22:19 am »
Okay only got one error so far the following code and that is with the x509_sign function.
Code: Pascal  [Select][+][-]
  1. program createselfsignedcert;
  2.  
  3. {$MODE OBJFPC}
  4. {$LONGSTRINGS ON}
  5.  
  6. uses
  7.   SysUtils, Windows;
  8.  
  9. const
  10.   OPENSSL_LIB = 'libcrypto-3.dll';
  11.   MBSTRING_FLAG = $1000;
  12.   MBSTRING_ASC = MBSTRING_FLAG or 1;
  13.   MBSTRING_BMP = MBSTRING_FLAG or 2;
  14.   MBSTRING_UNIV = MBSTRING_FLAG or 3;
  15.   MBSTRING_UTF8 = MBSTRING_FLAG or 4;
  16.   EVP_PKEY_RSA = 6; // RSA key type
  17.  
  18. type
  19.   PX509=Pointer;
  20.   PEVP_PKEY=Pointer;
  21.   PEVP_MD=Pointer;
  22.   PASN1_TIME=Pointer;
  23.   PBIO=PAnsiChar;
  24.  
  25.   ASN1_STRING = packed record
  26.     length: Integer;
  27.     _type: Integer;
  28.     data: PChar;
  29.     flags: LongWord;
  30.   end;
  31.  
  32.   PASN1_UTCTIME=^ASN1_UTCTIME;
  33.   ASN1_UTCTIME=ASN1_STRING;
  34.   ASN1_INTEGER=ASN1_STRING;
  35.   PASN1_INTEGER=^ASN1_STRING;
  36.  
  37. // Create Objects
  38. function X509_new: PX509; cdecl; external OPENSSL_LIB name 'X509_new';
  39. function X509_NAME_new: Pointer; cdecl; external OPENSSL_LIB name 'X509_NAME_new';
  40. function EVP_PKEY_new: PEVP_PKEY; cdecl; external OPENSSL_LIB name 'EVP_PKEY_new';
  41. function RSA_generate_key(bits: Integer; e: Integer; callback: Pointer; arg: Pointer): Pointer; cdecl; external OPENSSL_LIB name 'RSA_generate_key';
  42. function ASN1_UTCTIME_new: PASN1_TIME; cdecl; external OPENSSL_LIB name 'ASN1_UTCTIME_new';
  43. function BN_new: Pointer; cdecl; external OPENSSL_LIB name 'BN_new';
  44. function BIO_new_file(filename: PChar; mode: PChar): Pointer; cdecl; external OPENSSL_LIB name 'BIO_new_file';
  45. // Free Objects
  46. procedure X509_free(x: PX509); cdecl; external OPENSSL_LIB name 'X509_free';
  47. procedure X509_NAME_free(n: Pointer); cdecl; external OPENSSL_LIB name 'X509_NAME_free';
  48. procedure EVP_PKEY_free(pkey: PEVP_PKEY); cdecl; external OPENSSL_LIB name 'EVP_PKEY_free';
  49. procedure RSA_free(r: Pointer); cdecl; external OPENSSL_LIB name 'RSA_free';
  50. procedure ASN1_UTCTIME_free(a: PASN1_TIME); cdecl; external OPENSSL_LIB name 'ASN1_UTCTIME_free';
  51. procedure BN_free(a: Pointer); cdecl; external OPENSSL_LIB name 'BN_free';
  52. function BIO_free(a: pointer): integer;  cdecl; external OPENSSL_LIB name 'BIO_free';
  53. // Handle Objects
  54. function X509_set_version(x: PX509; version: Integer): Integer; cdecl; external OPENSSL_LIB name 'X509_set_version';
  55. procedure X509_gmtime_adj(s: PASN1_TIME; adj: Integer); cdecl; external OPENSSL_LIB name 'X509_gmtime_adj';
  56. function X509_get_serialNumber(x: PX509): Integer; cdecl; external OPENSSL_LIB name 'X509_get_serialNumber';
  57. procedure X509_set_serialNumber(x: PX509; serial: PASN1_INTEGER); cdecl; external OPENSSL_LIB name 'X509_set_serialNumber';
  58. function X509_NAME_add_entry_by_txt(name: Pointer; field: PAnsiChar; _type: Integer; bytes: PAnsiChar; len: Integer; location, _default: Integer): integer; cdecl; external OPENSSL_LIB name 'X509_NAME_add_entry_by_txt';
  59. function X509_set_issuer_name(x: PX509; name: Pointer): Integer; cdecl; external OPENSSL_LIB name 'X509_set_issuer_name';
  60. function X509_set_subject_name(x: PX509; name: Pointer): Integer; cdecl; external OPENSSL_LIB name 'X509_set_subject_name';
  61. function X509_set_pubkey(x: PX509; pkey: PEVP_PKEY): integer; cdecl; external OPENSSL_LIB name 'X509_set_pubkey';
  62. function X509_sign(x: PX509; pkey: PEVP_PKEY; md: PEVP_MD): Integer; cdecl; external OPENSSL_LIB name 'X509_sign';
  63. function EVP_PKEY_set1_RSA(key: pEVP_PKEY; rsa: pointer): integer; cdecl; external OPENSSL_LIB name 'EVP_PKEY_set1_RSA';
  64. function EVP_PKEY_assign(pkey: PEVP_PKEY; typ: integer; key: pointer): integer; cdecl; external OPENSSL_LIB name 'EVP_PKEY_assign';
  65. function PEM_write_bio_X509(bp: pBIO; x: pX509): integer; cdecl; external OPENSSL_LIB name 'PEM_write_bio_X509';
  66. procedure PEM_write_X509(filename: pchar; x: PX509); cdecl; external OPENSSL_LIB name 'PEM_write_X509';
  67. function PEM_write_bio_PrivateKey(bp: pointer; pkey: PEVP_PKEY; enc: pointer; kstr: pointer; klen: integer; pem_password_cb: pointer; u: pointer): integer; cdecl; external OPENSSL_LIB name 'PEM_write_bio_PrivateKey';
  68. function ASN1_INTEGER_new: PASN1_INTEGER; cdecl; external OPENSSL_LIB name 'ASN1_INTEGER_new';
  69. function ASN1_INTEGER_set_int64(a: PASN1_INTEGER; r: Int64): Integer; cdecl; external OPENSSL_LIB name 'ASN1_INTEGER_set_int64';
  70. // Message Digest
  71. function EVP_sha256: PEVP_MD; cdecl; external OPENSSL_LIB name 'EVP_sha256';
  72. function EVP_sha1: PEVP_MD; cdecl; external OPENSSL_LIB name 'EVP_sha1';
  73. function EVP_md5: PEVP_MD; cdecl; external OPENSSL_LIB name 'EVP_md5';
  74.  
  75. procedure HaltOnBadObj(Obj: pointer; Mess: string);
  76. begin
  77.   if not Assigned(Obj) then
  78.     begin
  79.       writeln(Mess);
  80.       halt(1);
  81.     end;
  82. end;
  83.  
  84. procedure ShowFuncStat(RetVal: integer; Mess: string);
  85. begin
  86.   if RetVal=1 then
  87.     writeln(Mess+' ok.')
  88.   else
  89.     writeln('Error:- '+Mess+'.');
  90. end;
  91.  
  92. procedure GenerateRandomSerialNumber(var SerialNumber: PASN1_INTEGER);
  93. var
  94.   RandomValue: Int64;
  95.   i: Integer;
  96. begin
  97.   // We generate a 64-bit random number
  98.   RandomValue:=0;
  99.   for i:=1 to 8 do
  100.     RandomValue:=(RandomValue shl 8) or Random(256);
  101.   // We make sure the number is positive
  102.   RandomValue:=RandomValue and $7FFFFFFFFFFFFFFF;
  103.   // We set the serial number
  104.   ShowFuncStat(ASN1_INTEGER_set_int64(SerialNumber, RandomValue), 'Setting serial number');
  105. end;
  106.  
  107. procedure CreateCertificate;
  108. var
  109.   x509: PX509;
  110.   pkey: PEVP_PKEY;
  111.   SerialNumber: PASN1_INTEGER;
  112.   name: Pointer;
  113.   time: PASN1_TIME;
  114.   rsa: Pointer;
  115.   bio: Pointer;
  116. begin
  117.   // Create a new X509 structure
  118.   x509:=X509_new;
  119.   HaltOnBadObj(x509, 'Error creating X509 structure');
  120.   // Set the version of the certificate (X509v3)
  121.   ShowFuncStat(X509_set_version(x509, 2), 'Setting X509 version');
  122.   // Generate key pair
  123.   pkey:=EVP_PKEY_new;
  124.   HaltOnBadObj(pkey, 'Error creating private key');
  125.   rsa:=RSA_generate_key(2048, $10001, nil, nil);
  126.   HaltOnBadObj(rsa, 'Error generating RSA key');
  127.   // Assign the generated key to the pkey structure
  128.   ShowFuncStat(EVP_PKEY_set1_RSA(pkey, rsa), 'Assigning RSA to pkey');
  129.   bio:=BIO_new_file('privatea_key.pem', 'w');
  130.   HaltOnBadObj(bio, 'Error creating BIO for file');
  131.   ShowFuncStat(PEM_write_bio_PrivateKey(bio, pkey, nil, nil, 0, nil, nil), 'Writing private key to file');
  132.   // Set the private key for the certificate
  133.   ShowFuncStat(X509_set_pubkey(x509, pkey), 'Setting public key');
  134.   // Set the serial number for x509
  135.   SerialNumber:=ASN1_INTEGER_new;
  136.   HaltOnBadObj(SerialNumber, 'Error creating Serial Number');
  137.   GenerateRandomSerialNumber(SerialNumber);
  138.   X509_set_serialNumber(x509, SerialNumber);
  139.   // Set validity period (e.g., one year from now)
  140.   time:=ASN1_UTCTIME_new;
  141.   HaltOnBadObj(time, 'Error creating time structure');
  142.   X509_gmtime_adj(time, 60*60*24*365); // One year from now
  143.   // Set the issuer and subject names (you can customize these)
  144.   name:=X509_NAME_new;
  145.   HaltOnBadObj(name, 'Error creating name structure');
  146.   ShowFuncStat(X509_NAME_add_entry_by_txt(name, 'C', MBSTRING_ASC, PAnsiChar('US'), Length('US'), -1, -1), 'Set Country');
  147.   ShowFuncStat(X509_NAME_add_entry_by_txt(name, 'ST', MBSTRING_ASC, PAnsiChar('California'), Length('California'), -1, -1), 'Set State');
  148.   ShowFuncStat(X509_NAME_add_entry_by_txt(name, 'L', MBSTRING_ASC, PAnsiChar('San Francisco'), Length('San Francisco'), -1, -1), 'Set Location');
  149.   ShowFuncStat(X509_NAME_add_entry_by_txt(name, 'O', MBSTRING_ASC, PAnsiChar('My Organization'), Length('My Organization'), -1, -1), 'Set Organization');
  150.   ShowFuncStat(X509_NAME_add_entry_by_txt(name, 'OU', MBSTRING_ASC, PAnsiChar('My Organizational Unit'), Length('My Organizational Unit'), -1, -1), 'Set Department');
  151.   ShowFuncStat(X509_NAME_add_entry_by_txt(name, 'CN', MBSTRING_ASC, PAnsiChar('localhost'), Length('localhost'), -1, -1), 'Set Common Name');
  152.   // Set the issuer and subject names in the certificate
  153.   ShowFuncStat(X509_set_issuer_name(x509, name), 'Setting issuer name');
  154.   ShowFuncStat(X509_set_subject_name(x509, name), 'Setting subject name');
  155.   // Sign the certificate with the private key
  156.   ShowFuncStat(X509_sign(x509, pkey, EVP_sha256()), 'Signing Certificate');
  157.   // Save the certificate to a file (e.g., cert.pem)
  158.   bio:=BIO_new_file('cert.pem', 'w');
  159.   ShowFuncStat(PEM_write_bio_X509(bio, x509), 'Writing Certificate');
  160.   // Free everything
  161.   X509_free(x509);
  162.   EVP_PKEY_free(pkey);
  163.   ASN1_UTCTIME_free(time);
  164.   X509_NAME_free(name);
  165.   BN_free(rsa);
  166.   BIO_free(bio);
  167. end;
  168.  
  169. begin
  170.   try
  171.     CreateCertificate;
  172.     Writeln('Self-signed certificate created successfully.');
  173.   except
  174.     on E: Exception do
  175.       Writeln(E.ClassName, ': ', E.Message);
  176.   end;
  177. end.
  178.  

 

TinyPortal © 2005-2018