Sample code for 30+ languages & platforms
Pascal (Lazarus/Delphi)

Duplicate CSR Created by OpenSSL with Config.cnf

See more CSR Examples

Demonstrates how to duplicate a CSR created by the following commands:
# Generate Private Key
openssl ecparam -name secp256k1 -genkey -noout -out PrivateKey.pem

#Generate CSR
openssl req -new -sha256 -key PrivateKey.pem -extensions v3_req -config Config.cnf -out CSR.csr

Chilkat Pascal (Lazarus/Delphi) Downloads

Pascal (Lazarus/Delphi)
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.Prng,
  Chilkat.StringBuilder,
  Chilkat.PrivateKey,
  Chilkat.Csr,
  Chilkat.Xml,
  Chilkat.Ecc;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  sbCsr: TStringBuilder;
  csr0: TCsr;
  xml0: TXml;
  xml: TXml;
  ecdsa: TEcc;
  prng: TPrng;
  privKey: TPrivateKey;
  csr: TCsr;
  csrPem: string;

begin
  success := False;

  //  This example assumes the Chilkat API to have been previously unlocked.
  //  See Global Unlock Sample for sample code.

  //  This example duplicates the CSR created by OpenSSL with the following config file:

  //  oid_section = OIDs
  //  [ OIDs ]
  //  certificateTemplateName= 1.3.6.1.4.1.311.20.2
  //  
  //  [ req ]
  //  default_bits 	= 2048
  //  emailAddress 	= it@example.sa
  //  req_extensions	= v3_req
  //  x509_extensions 	= v3_ca
  //  prompt = no
  //  default_md = sha256
  //  req_extensions = req_ext
  //  distinguished_name = dn
  //  
  //  [ v3_req ]
  //  basicConstraints = CA:FALSE
  //  keyUsage = digitalSignature, nonRepudiation, keyEncipherment
  //  
  //  [req_ext]
  //  certificateTemplateName = ASN1:PRINTABLESTRING:ZATCA-Code-Signing
  //  subjectAltName = dirName:alt_names
  //  
  //  [ dn ]
  //  CN =EXAMPLE-CORP  				# Common Name
  //  C=SA									# Country Code e.g SA
  //  OU=HEAD-OFFICE							# Organization Unit Name
  //  O=ASC									# Organization Name
  //  
  //  [alt_names]
  //  SN=1-ASC|2-V01|3-1234567890				# EGS Serial Number 1-ABC|2-PQR|3-XYZ
  //  UID=312345678900003						# Organization Identifier (VAT Number)
  //  title=1100								# Invoice Type
  //  registeredAddress=Dammam  	 			# Address
  //  businessCategory=IT						# Business Category

  //  The OpenSSL commands we are duplicating:

  //  openssl ecparam -name secp256k1 -genkey -noout -out PrivateKey.pem
  //  openssl req -new -sha256 -key PrivateKey.pem -extensions v3_req -config Config.cnf -out CSR.csr

  //  The 1st step is to actually use OpenSSL to generate a sample CSR.csr that we wish to duplicate.
  //  With the sample CSR.csr, we get the ExtensionRequest as XML.  
  //  For example:

  sbCsr := TStringBuilder.Create;
  success := sbCsr.LoadFile('qa_data/csr/openssl_cnf/CSR.csr','utf-8');
  if (success = False) then
    begin
      WriteLn('Failed to load CSR.csr');
      Exit;
    end;

  csr0 := TCsr.Create;
  success := csr0.LoadCsrPem(sbCsr.GetAsString());
  if (success = False) then
    begin
      WriteLn(csr0.LastErrorText);
      Exit;
    end;

  xml0 := TXml.Create;
  success := csr0.GetExtensionRequest(xml0);
  if (success = False) then
    begin
      WriteLn(csr0.LastErrorText);
      Exit;
    end;

  //  Let's examine the extension request..
  WriteLn(xml0.GetXml());

  //  <?xml version="1.0" encoding="utf-8"?>
  //  <set>
  //      <sequence>
  //          <sequence>
  //              <oid>1.3.6.1.4.1.311.20.2</oid>
  //              <asnOctets>
  //                  <printable>ZATCA-Code-Signing</printable>
  //              </asnOctets>
  //          </sequence>
  //          <sequence>
  //              <oid>2.5.29.17</oid>
  //              <asnOctets>
  //                  <sequence>
  //                      <contextSpecific tag="4" constructed="1">
  //                          <sequence>
  //                              <set>
  //                                  <sequence>
  //                                      <oid>2.5.4.4</oid>
  //                                      <utf8>1-ASC|2-V01|3-1234567890</utf8>
  //                                  </sequence>
  //                              </set>
  //                              <set>
  //                                  <sequence>
  //                                      <oid>0.9.2342.19200300.100.1.1</oid>
  //                                      <utf8>312345678900003</utf8>
  //                                  </sequence>
  //                              </set>
  //                              <set>
  //                                  <sequence>
  //                                      <oid>2.5.4.12</oid>
  //                                      <utf8>1100</utf8>
  //                                  </sequence>
  //                              </set>
  //                              <set>
  //                                  <sequence>
  //                                      <oid>2.5.4.26</oid>
  //                                      <utf8>Dammam</utf8>
  //                                  </sequence>
  //                              </set>
  //                              <set>
  //                                  <sequence>
  //                                      <oid>2.5.4.15</oid>
  //                                      <utf8>IT</utf8>
  //                                  </sequence>
  //                              </set>
  //                          </sequence>
  //                      </contextSpecific>
  //                  </sequence>
  //              </asnOctets>
  //          </sequence>
  //      </sequence>
  //  </set>

  //  If you wish to generate the above XML without going through the above steps, copy the XML into
  //  the online tool at https://tools.chilkat.io/xmlCreate

  //  Here is the generated code for the above XML:

  xml := TXml.Create;
  xml.Tag := 'set';
  xml.UpdateChildContent('sequence|sequence|oid','1.3.6.1.4.1.311.20.2');
  xml.UpdateChildContent('sequence|sequence|asnOctets|printable','ZATCA-Code-Signing');
  xml.UpdateChildContent('sequence|sequence[1]|oid','2.5.29.17');
  xml.UpdateAttrAt('sequence|sequence[1]|asnOctets|sequence|contextSpecific',True,'tag','4');
  xml.UpdateAttrAt('sequence|sequence[1]|asnOctets|sequence|contextSpecific',True,'constructed','1');
  xml.UpdateChildContent('sequence|sequence[1]|asnOctets|sequence|contextSpecific|sequence|set|sequence|oid','2.5.4.4');
  xml.UpdateChildContent('sequence|sequence[1]|asnOctets|sequence|contextSpecific|sequence|set|sequence|utf8','1-ASC|2-V01|3-1234567890');
  xml.UpdateChildContent('sequence|sequence[1]|asnOctets|sequence|contextSpecific|sequence|set[1]|sequence|oid','0.9.2342.19200300.100.1.1');
  xml.UpdateChildContent('sequence|sequence[1]|asnOctets|sequence|contextSpecific|sequence|set[1]|sequence|utf8','312345678900003');
  xml.UpdateChildContent('sequence|sequence[1]|asnOctets|sequence|contextSpecific|sequence|set[2]|sequence|oid','2.5.4.12');
  xml.UpdateChildContent('sequence|sequence[1]|asnOctets|sequence|contextSpecific|sequence|set[2]|sequence|utf8','1100');
  xml.UpdateChildContent('sequence|sequence[1]|asnOctets|sequence|contextSpecific|sequence|set[3]|sequence|oid','2.5.4.26');
  xml.UpdateChildContent('sequence|sequence[1]|asnOctets|sequence|contextSpecific|sequence|set[3]|sequence|utf8','Dammam');
  xml.UpdateChildContent('sequence|sequence[1]|asnOctets|sequence|contextSpecific|sequence|set[4]|sequence|oid','2.5.4.15');
  xml.UpdateChildContent('sequence|sequence[1]|asnOctets|sequence|contextSpecific|sequence|set[4]|sequence|utf8','IT');

  //  We'll need a new secp256k1 private key, so let's generate it.
  ecdsa := TEcc.Create;
  prng := TPrng.Create;
  privKey := TPrivateKey.Create;
  success := ecdsa.GenKey('secp256k1',prng,privKey);
  if (success = False) then
    begin
      WriteLn(ecdsa.LastErrorText);
      Exit;
    end;
  WriteLn('Generated secp256k1 private key.');

  //  Use a new CSR object to generate a CSR with the private key and extension request.
  csr := TCsr.Create;

  //  Add the [dn] fields
  //   [ dn ]
  //   CN =EXAMPLE-CORP  				# Common Name
  //   C=SA									# Country Code e.g SA
  //   OU=HEAD-OFFICE							# Organization Unit Name
  //   O=ASC									# Organization Name
  csr.CommonName := 'EXAMPLE-CORP';
  csr.Country := 'SA';
  csr.CompanyDivision := 'HEAD-OFFICE';
  csr.Company := 'ASC';

  //  Add the extension request to the CSR
  csr.SetExtensionRequest(xml);

  //  Generate the CSR with the extension request
  csrPem := csr.GenCsrPem(privKey);
  if (csr.LastMethodSuccess = False) then
    begin
      WriteLn(csr.LastErrorText);
      Exit;
    end;

  WriteLn(csrPem);

  //  Sample output:

  //  -----BEGIN CERTIFICATE REQUEST-----
  //  MIIBuDCCAV8CAQAwSDEVMBMGA1UEAwwMRVhBTVBMRS1DT1JQMQswCQYDVQQGEwJT
  //  QTEUMBIGA1UECwwLSEVBRC1PRkZJQ0UxDDAKBgNVBAoMA0FTQzBWMBAGByqGSM49
  //  AgEGBSuBBAAKA0IABFI5rusr76HiJcMMr1r4L0B0BOAs6azLkt/RwHoT6A0xFRRt
  //  tulWT40tNhx3qJ4I5ePNgMceOEtuK1kMGVTovI6ggbcwgbQGCSqGSIb3DQEJDjGB
  //  pjCBozAhBgkrBgEEAYI3FAIEFBMSWkFUQ0EtQ29kZS1TaWduaW5nMH4GA1UdEQR3
  //  MHWkczBxMSEwHwYDVQQEDBgxLUFTQ3wyLVYwMXwzLTEyMzQ1Njc4OTAxHzAdBgoJ
  //  kiaJk/IsZAEBDA8zMTIzNDU2Nzg5MDAwMDMxDTALBgNVBAwMBDExMDAxDzANBgNV
  //  BBoMBkRhbW1hbTELMAkGA1UEDwwCSVQwCgYIKoZIzj0EAwIDRwAwRAIgJnbgpSGb
  //  diB+0M1VTqc1GU9sFsfnOvVN/8WhWRRxQIwCIF5eH9vgMgXyoU284X8Bx3dqOJ4q
  //  xashGWci87POxSvT
  //  -----END CERTIFICATE REQUEST-----


  sbCsr.Free;
  csr0.Free;
  xml0.Free;
  xml.Free;
  ecdsa.Free;
  prng.Free;
  privKey.Free;
  csr.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.