windows - Creating self‐signed certificates using LibCrypto-3.dll from OpenSSL, code in FreePascal - Stack Overflow

I’m having trouble with the x509_sign function in the following code.The error I get from LibCrypto vi

I’m having trouble with the x509_sign function in the following code. The error I get from LibCrypto via ERR_print_errors_fp is:

OPENSSL_Uplink(721B6200,08): no OPENSSL_Applink"

program createselfsignedcert;

{$MODE OBJFPC}
{$LONGSTRINGS ON}

uses
  SysUtils, Windows;

const
  OPENSSL_LIB = 'libcrypto-3.dll';
//  OPENSSL_LIB = 'libeay32.dll';
  MBSTRING_FLAG = $1000;
  MBSTRING_ASC = MBSTRING_FLAG or 1;
  MBSTRING_BMP = MBSTRING_FLAG or 2;
  MBSTRING_UNIV = MBSTRING_FLAG or 3;
  MBSTRING_UTF8 = MBSTRING_FLAG or 4;
  EVP_PKEY_RSA = 6; // RSA key type

type
  TCallback=procedure(str: PChar; len: size_t; u: Pointer); //cdecl;

  PX509=Pointer;
  PEVP_PKEY=Pointer;
  PEVP_MD=Pointer;
  PASN1_TIME=Pointer;
  PBIO=PAnsiChar;

  ASN1_STRING = packed record
    length: Integer;
    _type: Integer;
    data: PChar;
    flags: LongWord;
  end;

  PASN1_UTCTIME=^ASN1_UTCTIME;
  ASN1_UTCTIME=ASN1_STRING;
  ASN1_INTEGER=ASN1_STRING;
  PASN1_INTEGER=^ASN1_STRING;

// Create Objects
function X509_new: PX509; cdecl; external OPENSSL_LIB name 'X509_new';
function X509_NAME_new: Pointer; cdecl; external OPENSSL_LIB name 'X509_NAME_new';
function EVP_PKEY_new: PEVP_PKEY; cdecl; external OPENSSL_LIB name 'EVP_PKEY_new';
function RSA_generate_key(bits: Integer; e: Integer; callback: Pointer; arg: Pointer): Pointer; cdecl; external OPENSSL_LIB name 'RSA_generate_key';
function ASN1_UTCTIME_new: PASN1_TIME; cdecl; external OPENSSL_LIB name 'ASN1_UTCTIME_new';
function BN_new: Pointer; cdecl; external OPENSSL_LIB name 'BN_new';
function BIO_new_file(filename: PChar; mode: PChar): Pointer; cdecl; external OPENSSL_LIB name 'BIO_new_file';
// Free Objects
procedure X509_free(x: PX509); cdecl; external OPENSSL_LIB name 'X509_free';
procedure X509_NAME_free(n: Pointer); cdecl; external OPENSSL_LIB name 'X509_NAME_free';
procedure EVP_PKEY_free(pkey: PEVP_PKEY); cdecl; external OPENSSL_LIB name 'EVP_PKEY_free';
procedure RSA_free(r: Pointer); cdecl; external OPENSSL_LIB name 'RSA_free';
procedure ASN1_UTCTIME_free(a: PASN1_TIME); cdecl; external OPENSSL_LIB name 'ASN1_UTCTIME_free';
procedure BN_free(a: Pointer); cdecl; external OPENSSL_LIB name 'BN_free';
function BIO_free(a: pointer): integer;  cdecl; external OPENSSL_LIB name 'BIO_free';
// Handle Objects
function X509_set_version(x: PX509; version: Integer): Integer; cdecl; external OPENSSL_LIB name 'X509_set_version';
function X509_get_serialNumber(x: PX509): Integer; cdecl; external OPENSSL_LIB name 'X509_get_serialNumber';
procedure X509_set_serialNumber(x: PX509; serial: PASN1_INTEGER); cdecl; external OPENSSL_LIB name 'X509_set_serialNumber';
procedure X509_gmtime_adj(s: PASN1_TIME; adj: Integer); cdecl; external OPENSSL_LIB name 'X509_gmtime_adj';
function X509_get0_notBefore(x: PX509): PASN1_TIME; cdecl; external OPENSSL_LIB name 'X509_get0_notBefore';
function X509_get0_notAfter(x: PX509): PASN1_TIME; cdecl; external OPENSSL_LIB name 'X509_get0_notAfter';
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';
function X509_set_issuer_name(x: PX509; name: Pointer): Integer; cdecl; external OPENSSL_LIB name 'X509_set_issuer_name';
function X509_set_subject_name(x: PX509; name: Pointer): Integer; cdecl; external OPENSSL_LIB name 'X509_set_subject_name';
function X509_set_pubkey(x: PX509; pkey: PEVP_PKEY): integer; cdecl; external OPENSSL_LIB name 'X509_set_pubkey';
function X509_sign(x: PX509; pkey: PEVP_PKEY; md: PEVP_MD): Integer; cdecl; external OPENSSL_LIB name 'X509_sign';
function EVP_PKEY_set1_RSA(key: pEVP_PKEY; rsa: pointer): integer; cdecl; external OPENSSL_LIB name 'EVP_PKEY_set1_RSA';
function EVP_PKEY_assign(pkey: PEVP_PKEY; typ: integer; key: pointer): integer; cdecl; external OPENSSL_LIB name 'EVP_PKEY_assign';
function PEM_write_bio_X509(bp: pBIO; x: pX509): integer; cdecl; external OPENSSL_LIB name 'PEM_write_bio_X509';
procedure PEM_write_X509(filename: pchar; x: PX509); cdecl; external OPENSSL_LIB name 'PEM_write_X509';
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';
function PEM_write_PrivateKey(filename: pchar; pkey: PEVP_PKEY; enc: pointer; kstr: pointer; klen: integer; pem_password_cb: pointer; u: pointer): integer; cdecl; external OPENSSL_LIB name 'PEM_write_PrivateKey';
function ASN1_INTEGER_new: PASN1_INTEGER; cdecl; external OPENSSL_LIB name 'ASN1_INTEGER_new';
function ASN1_INTEGER_set_int64(a: PASN1_INTEGER; r: Int64): Integer; cdecl; external OPENSSL_LIB name 'ASN1_INTEGER_set_int64';
procedure ERR_print_errors_fp(filename: pchar); cdecl; external OPENSSL_LIB name 'ERR_print_errors_fp';
procedure ERR_print_errors_cb(callback: TCallBack; u: Pointer); cdecl; external OPENSSL_LIB name 'ERR_print_errors_cb';
procedure ERR_print_errors(bp: PBIO); cdecl; external OPENSSL_LIB name 'ERR_print_errors';
function  ERR_get_error: Cardinal; cdecl; external OPENSSL_LIB name 'ERR_get_error';

// Message Digest
function EVP_sha256: PEVP_MD; cdecl; external OPENSSL_LIB name 'EVP_sha256';
function EVP_sha1: PEVP_MD; cdecl; external OPENSSL_LIB name 'EVP_sha1';
function EVP_md5: PEVP_MD; cdecl; external OPENSSL_LIB name 'EVP_md5';

procedure HaltOnBadObj(Obj: pointer; Mess: string);
begin
  if not Assigned(Obj) then
    begin
      writeln(Mess);
      halt(1);
    end;
end;

procedure MyErrorCallback(str: PChar; len: size_t; u: Pointer); //cdecl;
begin
  WriteLn('OpenSSL Error: ', StrPas(str));
end;

procedure ShowFuncStat(RetVal: integer; Mess: string; ShowErr: boolean=False);
var
  err: Cardinal;
begin
  if RetVal=1 then
    writeln(Mess+' ok.')
  else
    begin
      writeln('Error:- '+Mess+'.');
      if ShowErr then
        ERR_print_errors_fp(@stderr);
    end;
end;

procedure GenerateRandomSerialNumber(var SerialNumber: PASN1_INTEGER);
var
  RandomValue: Int64;
  i: Integer;
begin
  // We generate a 64-bit random number
  RandomValue:=0;
  for i:=1 to 8 do
    RandomValue:=(RandomValue shl 8) or Random(256);
  // We make sure the number is positive
  RandomValue:=RandomValue and $7FFFFFFFFFFFFFFF;
  // We set the serial number
  ShowFuncStat(ASN1_INTEGER_set_int64(SerialNumber, RandomValue), 'Setting serial number');
end;

procedure CreateCertificate;
var
  x509: PX509;
  pkey: PEVP_PKEY;
  SerialNumber: PASN1_INTEGER;
  name: Pointer;
  time: PASN1_TIME;
  rsa: Pointer;
  bio: Pointer;
begin
  // Create a new X509 structure
  x509:=X509_new;
  HaltOnBadObj(x509, 'Error creating X509 structure');
  // Set the version of the certificate (X509v3)
  ShowFuncStat(X509_set_version(x509, 2), 'Setting X509 version');
  // Generate key pair
  pkey:=EVP_PKEY_new;
  HaltOnBadObj(pkey, 'Error creating private key');
  rsa:=RSA_generate_key(2048, $10001, nil, nil);
  HaltOnBadObj(rsa, 'Error generating RSA key');
  // Assign the generated key to the pkey structure
  ShowFuncStat(EVP_PKEY_set1_RSA(pkey, rsa), 'Assigning RSA to pkey');
  bio:=BIO_new_file('privatea_key.pem', 'w');
  HaltOnBadObj(bio, 'Error creating BIO for file');
  ShowFuncStat(PEM_write_bio_PrivateKey(bio, pkey, nil, nil, 0, nil, nil), 'Writing private key to file');
//  ShowFuncStat(PEM_write_PrivateKey(@stderr, pkey, nil, nil, 0, nil, nil), 'Writing private key to file');
  // Set the private key for the certificate
  ShowFuncStat(X509_set_pubkey(x509, pkey), 'Setting public key');
  // Set the serial number for x509
  SerialNumber:=ASN1_INTEGER_new;
  HaltOnBadObj(SerialNumber, 'Error creating Serial Number');
  GenerateRandomSerialNumber(SerialNumber);
  X509_set_serialNumber(x509, SerialNumber);
  // Set validity period (e.g., one year from now)
  time:=ASN1_UTCTIME_new;
 // HaltOnBadObj(time, 'Error creating time structure');
  X509_gmtime_adj(time, 60*60*24*365); // One year from now

 // X509_gmtime_adj(X509_get0_notBefore(x509), 0);
 // X509_gmtime_adj(X509_get0_notAfter(x509), 60*60*24*365);

  // Set the issuer and subject names (you can customize these)
  name:=X509_NAME_new;
  HaltOnBadObj(name, 'Error creating name structure');
  ShowFuncStat(X509_NAME_add_entry_by_txt(name, 'C', MBSTRING_ASC, PAnsiChar('US'), -1, -1, 0), 'Set Country');
  ShowFuncStat(X509_NAME_add_entry_by_txt(name, 'ST', MBSTRING_ASC, PAnsiChar('California'), -1, -1, 0), 'Set State');
  ShowFuncStat(X509_NAME_add_entry_by_txt(name, 'L', MBSTRING_ASC, PAnsiChar('San Francisco'), -1, -1, 0), 'Set Location');
  ShowFuncStat(X509_NAME_add_entry_by_txt(name, 'O', MBSTRING_ASC, PAnsiChar('My Organization'), -1, -1, 0), 'Set Organization');
  ShowFuncStat(X509_NAME_add_entry_by_txt(name, 'OU', MBSTRING_ASC, PAnsiChar('My Organizational Unit'), -1, -1, 0), 'Set Department');
  ShowFuncStat(X509_NAME_add_entry_by_txt(name, 'CN', MBSTRING_ASC, PAnsiChar('localhost'), -1, -1, 0), 'Set Common Name');
  // Set the issuer and subject names in the certificate
  ShowFuncStat(X509_set_issuer_name(x509, name), 'Setting issuer name');
  ShowFuncStat(X509_set_subject_name(x509, name), 'Setting subject name');
  // Sign the certificate with the private key
  //////////////////////// This fails
  ShowFuncStat(X509_sign(x509, pkey, EVP_sha256()), 'Signing Certificate', true);
  ////////////////////////
  // Save the certificate to a file (e.g., cert.pem)
  bio:=BIO_new_file('cert.pem', 'w');
  ShowFuncStat(PEM_write_bio_X509(bio, x509), 'Writing Certificate');
  // Free everything
  X509_free(x509);
  EVP_PKEY_free(pkey);
  ASN1_UTCTIME_free(time);
  X509_NAME_free(name);
  BN_free(rsa);
  BIO_free(bio);
end;

begin
  try
    CreateCertificate;
    Writeln('Self-signed certificate created successfully.');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

This this the output.

Setting X509 version ok.
Assigning RSA to pkey ok.
Writing private key to file ok.
Setting public key ok.
Setting serial number ok.
Set Country ok.
Set State ok.
Set Location ok.
Set Organization ok.
Set Department ok.
Set Common Name ok.
Setting issuer name ok.
Setting subject name ok.
Error:- Signing Certificate.
OPENSSL_Uplink(721B6200,08): no OPENSSL_Applink

I’ve seen this same error in several other coding languages and seen no solutions for this error.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744318793a4568310.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信