JohnF 1 Posted October 28 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
DelphiUdIT 182 Posted October 28 (edited) You can read the sources of Indy to look how it works (with the OpenSSL 1.0.2u, the Indy develop with RAD Studio use this version). Look at guthub repo for more upgrades (https://github.com/IndySockets). Another way is to look how ICS works (https://wiki.overbyte.eu/wiki/index.php/ICS_Download or via GetIt). Edited October 28 by DelphiUdIT 1 Share this post Link to post