Jump to content
JohnF

Openssl dll questions

Recommended Posts

Hi,

 

Using D12. I've just started playing with openssl, and thought how hard would it be calling the openssl libcrypto-3.dll.

 

Its a learning exercise more than anything. I'm trying to make a self signed X509 certifcate via the dll rather than the command line.

I havent played with returning struct from a C dll before.

 

Currently some of the call including the  X509_set_version(Cert, 2) call appears to work (not throw an error) but the X509_set_serialNumber(Cert, 1) and the X509_set_pubkey(Cert, PKey) throws an exceptions.

 

  • can I use a pointer to hold the return value to X509_new function?
  • can I use that pointer to pass into the other function?
  • or do I have to have a record that the struct is copied back into and then use that (I hope not)

 

TIA

 

Const

  LIB_CRYPTO = 'libcrypto-3.dll';


type
  PX509 = Pointer;
  PBIO = Pointer;
  PEVP_PKEY = Pointer;
  PEVP_MD = Pointer;
  PX509_NAME = Pointer;

  // OpenSSL X509 functions
  function X509_new: PX509; cdecl; external LIB_CRYPTO name 'X509_new';
  procedure X509_free(cert: PX509); cdecl; external LIB_CRYPTO name 'X509_free';
  function X509_set_version(cert: PX509; version: Integer; ): Integer; cdecl; external LIB_CRYPTO name 'X509_set_version';
  function X509_set_serialNumber(cert: PX509; serial: Integer; ): Integer; cdecl; external LIB_CRYPTO name 'X509_set_serialNumber';
  function X509_set_subject_name(cert: PX509; name: PX509_NAME): Integer; cdecl; external LIB_CRYPTO name 'X509_set_subject_name';
  function X509_set_issuer_name(cert: PX509; name: PX509_NAME): Integer; cdecl; external LIB_CRYPTO name 'X509_set_issuer_name';
  function X509_set_pubkey(cert: PX509; pkey: PEVP_PKEY): Integer; cdecl; external LIB_CRYPTO name 'X509_set_pubkey';
  function X509_sign(cert: PX509; pkey: PEVP_PKEY; md: PEVP_MD): Integer; cdecl; external LIB_CRYPTO name 'X509_sign';

  // Key management functions
  function EVP_PKEY_new: PEVP_PKEY; cdecl; external LIB_CRYPTO name 'EVP_PKEY_new';
  procedure EVP_PKEY_free(pkey: PEVP_PKEY); cdecl; external LIB_CRYPTO name 'EVP_PKEY_free';
  function EVP_PKEY_generate_key: PEVP_PKEY; cdecl; external LIB_CRYPTO name 'EVP_PKEY_keygen';


function CreateSelfSignedCert(CommonName, Country, Organization, OrganizationalUnit: string;
  ValidDays: Integer; out ACertificate, APrivateKey: TBytes): Boolean;

implementation



function CreateSelfSignedCert(CommonName, Country, Organization, OrganizationalUnit: string;
  ValidDays: Integer; out ACertificate, APrivateKey: TBytes): Boolean;
var
  Cert: PX509;
  PKey: PEVP_PKEY;
  Name: PX509_NAME;
  Digest: PEVP_MD;
  CertBio, KeyBio: PBIO;
begin
  Result := False;
  Cert := X509_new;

  if Cert = nil then
    Exit;

  try
    // Set certificate version to v3 as its self signed
    if X509_set_version(Cert, 2) <> 1 then
      Exit;

    // Set serial number
    if X509_set_serialNumber(Cert, 1) <> 1 then
      Exit;

    // Generate a new key
    PKey := EVP_PKEY_new;
    if PKey = nil then
      Exit;
    try
      PKey := EVP_PKEY_generate_key();
      if PKEY = nil then
        Exit;

      // Set public key for the certificate
      if X509_set_pubkey(Cert, PKey) <> 1 then
        Exit;

      // Set certificate subject and issuer (self-signed, so both are the same)

      // Set validity period

      // Sign the certificate

      // Write the certificate to TBytes

      Result := True;

    finally
      EVP_PKEY_free(PKey);
    end;
  finally
    X509_free(Cert);
  end;
end;

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×