CryptoSys PKI Pro Manual

PFX_MakeFile

Creates a simple PFX (PKCS-12) file from an X.509 certificate and (optional) encrypted private key file.

VBA/VB6 Syntax

Public Declare Function PFX_MakeFile Lib "diCrPKI.dll" (ByVal strOutputFile As String, ByVal strCertList As String, ByVal strKeyFile As String, ByVal strPassword As String, ByVal strFriendlyName As String, ByVal nOptions As Long) As Long

nRet = PFX_MakeFile(strOutputFile, strCertList, strKeyFile, strPassword, strFriendlyName, nOptions)

C/C++ Syntax

long __stdcall PFX_MakeFile(const char *szFileOut, const char *szCertList, const char *szEpkFile, const char *szPassword, const char *szFriendlyName, long nOptions);

Parameters

szFileOut
[in] name of output file to be created.
szCertList
[in] (required) filename of the subject's X.509 certificate (or a string containing the certificate in base64 representation) followed by optional extra certificates to be included separated by a semicolon (;).
szEpkFile
[in] filename of the subject's pkcs-8 encrypted private key (or a string containing the key in PEM format). Pass an empty string "" to exclude the private key.
szPassword
[in] password for the encrypted private key.
szFriendlyName
[in] friendly name identification for the subject (optional).
nOptions
[in] option flags:
PKI_DEFAULT (0) for default options: re-encrypt private key with "TripleDES-SHA1", encrypt certificate with 40-bit RC2, output in DER binary form.
PKI_PFX_CLONE_KEY to store the private key in the exact form of the pkcs-8 input file (default is to re-encrypt with 3DES)
Add one of the following:
PKI_PFX_PLAIN_CERT to store the certificate in unencrypted form (default is encrypted)
PKI_PFX_STRONG_CERT to encrypt the certificate with "stronger" TripleDES-SHA1 (default is "weak" 40-bit RC2)
Or, new in [v20.5], to override the above encryption options, use instead
PKI_PFX_AES256_SHA256 to encrypt both the private key and certificate using "AES256-SHA256"
Then add any of these options:
PKI_KEY_FORMAT_PEM to create the output file in PEM format (default is DER-encoded binary)
PKI_PFX_ALT_FORMAT to create a PFX file with the exact peculiarities used by Microsoft (default is OpenSSL format)

Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero error code.

VBA Wrapper Syntax

Public Function pfxMakeFile (szFileOut As String, szCertList As String, Optional szKeyFile As String = "", Optional szPassword As String = "", Optional szFriendlyName As String = "", Optional nOptions As Long = 0) As Long

.NET Equivalent

Pfx.MakeFile Method

C++ (STL) Equivalent

static int dipki::Pfx::MakeFile (const std::string &fileToMake, const std::string &certList, const std::string &privateKeyFile="", const std::string &password="", const std::string &friendlyName="", Opts opts=Opts::Default)

Python Equivalent

static Pfx.make_file(outputfile, certlist, prikeyfile="", password="", friendlyname="", opts=0)

Remarks

At least one certificate must be specified in the szCertList argument. Add additional certificate names (or base64 representations) separated by a semicolon (;). The first certificate in the list must be the matching certificate for the private key, if included. The default behaviour is to save the certificate(s) encrypted using the "standard" weak 40-bit RC2 encryption (pbeWithSHAAnd40BitRC2-CBC) as used (until recently) by Windows Certificate Manager and OpenSSL, and the private key is re-encrypted using the "standard" TripleDES-SHA1 algorithm (pbeWithSHAAnd3-KeyTripleDES-CBC).

[New in v12.3] Use the PKI_PFX_STRONG_CERT option to encrypt the certificate with "stronger" Triple DES, the same as the default key encryption algorithm. The PKI_PFX_PLAIN_CERT option takes precedence.

[New in v20.5] Use the PKI_PFX_AES256_SHA256 option to encrypt both the private key and certificate using "AES256-SHA256".

The szFriendlyName parameter is optional. To exclude the private key just pass an empty szKeyFile parameter.

To help users of a certain brain-dead web service in Mexico which cannot cope with anything else, the default file format is the exact format that would be created by OpenSSL. If you really need Microsoft's peculiarities†, then add the PKI_PFX_ALT_FORMAT option flag.

Any form of PKCS-12 file created by this function should be importable into Windows Certificate Manager/Outlook (use a .pfx extension for the output file) and Mozilla/Firefox (use a .p12 extension). The PKCS-12 standard is notorious for its peculiarities - see PFX - How Not to Design a Crypto Protocol/Standard [GUTPFX]. If you do not have success with your target application, try changing the options. In particular, using the PKI_PFX_CLONE_KEY option may cause problems if the target application cannot decrypt the super-secure algorithm you've used to protect your private key (error messages about a missing cryptographic provider are a clue here). That's why the default behaviour is to re-encrypt using the "standard" algorithm.

If you specify both a certificate and a private key, their RSA keys must match or a PKI_NO_MATCH_ERROR error will occur. The PKCS-12 file will be protected using the specified szPassword, which must match the password for the encrypted private key file, if included. The password is optional for the case where there is just a certificate, but is required if you need the certificate to be encrypted. If you don't use a password for a cert-only file, just enter an empty password when importing the PFX into Windows.

If you use the PKI_KEY_FORMAT_PEM option, the output file will be in PEM format with the first line "-----BEGIN PKCS12-----". Be warned, Windows does not recognise such a file as a valid PFX/PKCS-12 format!

† The difference between the OpenSSL and Microsoft forms is that the Microsoft form has a "preferredAbsent" NULL parameter added to the message digest object for "sha1" and uses 8 instead of 20 bytes for the MacData salt. Both combinations are perfectly valid according to the PKCS12 specification.

Example

This example uses Bob's X.509 certificate and encrypted private key file to create a pkcs-12 file and then verifies the signature. The resulting file should be importable into Windows Certficate Manager or Mozilla with an exportable private key.

Dim strOutputFile As String
Dim strCertFile As String
Dim strKeyFile As String
Dim strPassword As String
Dim nRet As Long

strOutputFile = "Bob1.pfx"
strCertFile = "BobRSASignByCarl.cer"
strKeyFile = "BobPrivRSAEncrypt.p8e"
strPassword = "password"

' Given Bob's certificate and encrypted private key file (with password "password"),
' create a PKCS-12 (pfx/p12) file.
nRet = PFX_MakeFile(strOutputFile, strCertFile, strKeyFile, strPassword, "Bob's ID", 0)
Debug.Print "PFX_MakeFile returns " & nRet

' Now verify that the signature is OK
nRet = PFX_VerifySig(strOutputFile, strPassword, 0)
Debug.Print "PFX_VerifySig returns " & nRet

' Clean up
Call WIPE_String(strPassword, Len(strPassword))

Both functions should return zero.

The next example uses Carl's X.509 certificate to create a "certificate-only" pkcs-12 file. This is useful for importing the certificate into Mozilla/Firefox. Enter a blank password when importing.

Dim strOutputFile As String
Dim strCertFile As String
Dim strKeyFile As String
Dim nRet As Long

strOutputFile = "CarlNoKey.p12"
strCertFile = "CarlRSASelf.cer"

' Given Carl's certificate only,
' create a PKCS-12 (pfx/p12) file with no private key.
nRet = PFX_MakeFile(strOutputFile, strCertFile, "", "", "Carl's ID", 0)
Debug.Print "PFX_MakeFile returns " & nRet

The next example in C/C++ creates a pkcs-12 file in PEM format, using key and certificate data passed as strings.

long nRet;
char *outfile = "bob-pemfull.p12";
char *pfile;

char *password = "password";
char *epkstr = /* From BobPrivRSAEncrypt.p8e */
"-----BEGIN ENCRYPTED PRIVATE KEY-----""\n"
"MIICojAcBgoqhkiG9w0BDAEDMA4ECFolTdEnFcG+AgIH0ASCAoBUZJEzzH//"
"TRl5ieAHPo9q1eoMlYQu6j/eF8iIMNQ/eUp41iQIXqt9gcO2YdU5ah+ooMu4"
"ef1+yMN0buWUKFLgyUTyoYdg3O8XrCB6GhCCPeTXYvt6vYs4w85HHaXMZdfz"
"6dXAq3ratOVGq0PYg9dF0nI5T6Yd8S29TX4ceWyhNVG9yXAQhsRO1mMlS1tw"
"aTtxME7OSsQXe4mFgqGiCTwmNA183VqXdXP+1D2IrpI2zN+JfmTvOQIQ0iU8"
"ZuqBDMDRm8M/60uh2RlrfLqaIXKlF1V9PddijM6ORu8FFyPfaXkwZ7VsuvRS"
"Iijpf9PNDh4J+E0Vy1lsc6r4RrZWHdc4kKwKpYalE45wME14sbvh+WCZmFfd"
"D/pLZM8Or/IVHGYPFbpoAZwy+bmsjjOH/dBg6q1CY8mme9dnCBVLfXoZXTTk"
"o9TOSFw4Tmd/YEH2yPylT78hw+ThNsNmG2PwUX+5yTFoI7PQA8oBg6sN4kbP"
"tuRSo1fcB9RqJEO5hhqo+xAoMdhlHWdbIXOcEa1S8zLisJmgVrdAHJz6PPBl"
"3LVe1LHZ/oOD8rxeal8GTTCLk4onhjr7IT+DipMJendcjIgyok5I14DiKmjt"
"UPL10bt+0XkRVCIM0jma80YIGs4OMgRdW4u4n4lzJ0c1pxbvQvz8LY65OLcI"
"M+6VqJCH360iN1CSLRbVBg6HqjMNEthEXExKh/b95u+sVd4qPINmsnD1DwTd"
"4vkWx1zM4T+sKdz2GnBrjNRu2nJ4Nqe/krxDEKvcowh0eNllS/J86LhLYFFg"
"z/JKcqq20+GPSaQALvVXK7mVKljZcKEI6YQKQMgt5+amnDixhbvppSn/my1o"
"0kG3"
"-----END ENCRYPTED PRIVATE KEY-----";
char *certstr = /* From BobRSASignByCarl.cer */ 
"-----BEGIN CERTIFICATE-----""\n"
"MIICJzCCAZCgAwIBAgIQRjRrx4AAVrwR024uzV1x0DANBgkqhkiG9w0BAQUFADAS"
"MRAwDgYDVQQDEwdDYXJsUlNBMB4XDTk5MDkxOTAxMDkwMloXDTM5MTIzMTIzNTk1"
"OVowETEPMA0GA1UEAxMGQm9iUlNBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB"
"gQCp4WeYPznVX/Kgk0FepnmJhcg1XZqRW/sdAdoZcCYXD72lItA1hW16mGYUQVzP"
"t7cIOwnJkbgZaTdt+WUee9mpMySjfzu7r0YBhjY0MssHA1lS/IWLMQS4zBgIFEjm"
"Txz7XWDE4FwfU9N/U9hpAfEF+Hpw0b6Dxl84zxwsqmqn6wIDAQABo38wfTAMBgNV"
"HRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFIDAfBgNVHSMEGDAWgBTp4JAnrHggeprT"
"TPJCN04irp44uzAdBgNVHQ4EFgQU6PS4Z9izlqQq8xGqKdOVWoYWtCQwHQYDVR0R"
"BBYwFIESQm9iUlNBQGV4YW1wbGUuY29tMA0GCSqGSIb3DQEBBQUAA4GBAHuOZsXx"
"ED8QIEyIcat7QGshM/pKld6dDltrlCEFwPLhfirNnJOIh/uLt359QWHh5NZt+eIE"
"VWFFvGQnRMChvVl52R1kPCHWRbBdaDOS6qzxV+WBfZjmNZGjOd539OgcOyncf1EH"
"l/M28FAK3Zvetl44ESv7V+qJba3JiNiPzyvT"
"-----END CERTIFICATE-----";

nRet = PFX_MakeFile(outfile, certstr, epkstr, password, "Bob's friendly ID", PKI_KEY_FORMAT_PEM);
if (nRet != 0) disp_error(nRet);
assert(nRet == 0);
printf("Created file '%s'\n", outfile);

pfile = outfile;
nRet = PFX_VerifySig(pfile, password, 0);
if (nRet != 0) disp_error(nRet);
assert(nRet == 0);
printf("Verified file '%s'\n", pfile);

See Also

PFX_VerifySig RSA_GetPrivateKeyFromPFX RSA_ReadPrivateKeyFromPFX

[Contents] [Index]

[PREV: PEM_FileToBinFile...]   [Contents]   [Index]   
   [NEXT: PFX_VerifySig...]

Copyright © 2004-23 D.I. Management Services Pty Ltd. All rights reserved. Generated 2023-10-22T11:11:11Z.