CryptoSys PKI Pro Manual

X509_MakeCert

Creates an X.509 certificate using subject's public key and issuer's private key files.

VBA/VB6 Syntax

Public Declare Function X509_MakeCert Lib "diCrPKI.dll" (ByVal strNewCertFile As String, ByVal strIssuerCertFile As String, ByVal strSubjectPubKeyFile As String, ByVal strIssuerPriKeyFile As String, ByVal nCertNum As Long, ByVal nYearsValid As Long, ByVal strDistName As String, ByVal strExtensions As String, ByVal KeyUsageFlags As Long, ByVal strPassword As String, ByVal nOptions As Long) As Long

nRet = X509_MakeCert(strNewCertFile, strIssuerCertFile, strSubjectPubKeyFile, strIssuerPriKeyFile, nCertNum, nYearsValid, strDistName, strExtensions, KeyUsageFlags, strPassword, nOptions)

C/C++ Syntax

long __stdcall X509_MakeCert(const char *szNewCertFile, const char *szIssuerCertFile, const char *szSubjectPubKeyFile, const char *szIssuerPriKeyFile, long nCertNum, long nYearsValid, const char *szDistName, const char *szExtensions, long nKeyUsageFlags, const char *szPassword, long nOptions);

Parameters

szNewCertFile
[in] Name of new certificate file to be created.
szIssuerCertFile
[in] Name of issuer's X.509 certificate file (or its base64 representation or as a PEM string).
szSubjectPubKeyFile
[in] Name of subject's public key file or a PEM string containing the key, or a valid internal key string.
szIssuerPriKeyFile
[in] Name of issuer's private key file (encrypted or unencrypted) or a PEM string containing the key, or a valid internal key string.
nCertNum
[in] Serial number for new certificate. Ignored if serialNumber is set in szExtensions.
nYearsValid
[in] Number of years certificate is to be valid from current date and hour (can be changed with szExtensions).
szDistName
[in] Distinguished name string. See Specifying Distinguished Names for more details.
szExtensions
[in] Extensions: a list of attribute-value pairs separated by semicolons (;). See X.509 Extensions Parameter. Specify "" or NULL to ignore.
nKeyUsageFlags
[in] Bit flags to set Key Usage extension:
OptionTo set
PKI_X509_KEYUSAGE_DIGITALSIGNATUREdigitalSignature
PKI_X509_KEYUSAGE_NONREPUDIATIONnonRepudiation
PKI_X509_KEYUSAGE_KEYENCIPHERMENTkeyEncipherment
PKI_X509_KEYUSAGE_DATAENCIPHERMENTdataEncipherment
PKI_X509_KEYUSAGE_KEYAGREEMENTkeyAgreement
PKI_X509_KEYUSAGE_KEYCERTSIGNkeyCertSign
PKI_X509_KEYUSAGE_CRLSIGNcRLSign
PKI_X509_KEYUSAGE_ENCIPHERONLYencipherOnly
PKI_X509_KEYUSAGE_DECIPHERONLYdecipherOnly
Add to combine options. Specify zero to omit Key Usage extension.
szPassword
[in] Password for issuer's encrypted private key file. Specify the empty string "" if key not encrypted [New in v12.0].
nOptions
[in] Option flags. Choose one signature algorithm from:
PKI_SIG_SHA1RSA (0) to use sha1WithRSAEncryption (default - CAUTION)
PKI_SIG_SHA224RSA to use sha224WithRSAEncryption
PKI_SIG_SHA256RSA to use sha256WithRSAEncryption [minimum recommended]
PKI_SIG_SHA384RSA to use sha384WithRSAEncryption
PKI_SIG_SHA512RSA to use sha512WithRSAEncryption
PKI_SIG_MD5RSA to use md5WithRSAEncryption [legacy, not recommended]
PKI_SIG_MD2RSA to use md2WithRSAEncryption [legacy, definitely not recommended]
PKI_SIG_RSA_PSS_SHA1 to use RSA-PSS-SHA1
PKI_SIG_RSA_PSS_SHA224 to use RSA-PSS-SHA224
PKI_SIG_RSA_PSS_SHA256 to use RSA-PSS-SHA256
PKI_SIG_RSA_PSS_SHA384 to use RSA-PSS-SHA384
PKI_SIG_RSA_PSS_SHA512 to use RSA-PSS-SHA512
PKI_SIG_ECDSA_SHA1 to use ecdsaWithSHA1
PKI_SIG_ECDSA_SHA224 to use ecdsaWithSHA224
PKI_SIG_ECDSA_SHA256 to use ecdsaWithSHA256
PKI_SIG_ECDSA_SHA384 to use ecdsaWithSHA384
PKI_SIG_ECDSA_SHA512 to use ecdsaWithSHA512
PKI_SIG_ED25519 to use Ed25519 [New in v20.0]
PKI_SIG_ED448 to use Ed448 [New in v22.0]

And add any combination of these:-
PKI_X509_VERSION1 to generate a Version 1 certificate, i.e. no extensions (default = Version 3).
PKI_X509_CA_TRUE to set the basicConstraints subject type to be a CA (default = End Entity)
PKI_X509_NO_BASIC to disable the basicConstraints extension (default = include)
PKI_X509_UTF8 to encode the subject's DN fields as UTF8String (default = PrintableString)
PKI_X509_FORMAT_PEM to save the certificate in PEM format (default = DER-encoded binary)
PKI_X509_AUTHKEYID to add the issuer's KeyIdentifier, if present, as an AuthorityKeyIdentifer (default = do not add)

Specialist options:-
PKI_PSS_SALTLEN_ZERO to use a zero-length salt in an RSA-PSS signature.
PKI_SIG_DETERMINISTIC to use the deterministic digital signature generation procedure of [RFC6979] for an ECDSA signature.

Returns (VBA/C)

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

.NET Equivalent

X509.MakeCert Method

C++ (STL) Equivalent

static int dipki::X509::MakeCert (const std::string &newCertFile, const std::string &issuerCert, const std::string &subjectPubKeyFile, const std::string &issuerPriKeyFile, const std::string &password, int certNum, int yearsValid, const std::string distName, const std::string extns="", KeyUsageOptions keyUsageOptions=KeyUsageOptions::NoKeyUsageOption, SigAlg sigAlg=SigAlg::Default, CertOptions opts=CertOptions::Default_CertOpt)

Python Equivalent

static X509.make_cert(newcertfile, issuercert, subject_pubkeyfile, issuer_prikeyfile, password, certnum=0, yearsvalid=0, distname="", extns="", keyusage=KeyUsageFlags.NONE, sigalg=0, opts=0)

Remarks

At least one valid attribute for the subject's distinguished name (DN) must be included. A version 1 certificate created using the PKI_X509_VERSION1 flag will, by definition, exclude any version 3 extensions.

If the PKI_X509_UTF8 flag is set, each attribute of the subject's DN will be encoded as a UTF8String. Otherwise the default encoding will be PrintableString or, if a non-printable character is specified, then as either IA5String or T61String - see Specifying Distinguished Names for more details. The encoding of the issuer's DN will be exactly as in the issuer's certficate.

If the PKI_X509_AUTHKEYID flag is set then an authorityKeyIdentifer extension will be set if there is a corresponding subjectKeyIdentifer in the issuer's certificate. Otherwise no such extension will be set.

The default validity period is from one minute ago by the system clock for a period of a whole number of years set by the nYearsValid parameter. This time will always have the seconds set to 01. A different validity period can be set using the notBefore and notAfter attributes in the szExtensions parameter (see X509 Extensions Parameter).

The serial number can be set to be an integer in the range 1 to 2,147,483,647 using the nCertNum parameter, or (once you have used these up!) it can be set to a larger value, perhaps a random large integer represented by a hexadecimal string, using the serialNumber attribute in the szExtensions parameter (see X509 Extensions Parameter).

As an alternative, you can create a new X.509 certificate using a PKCS-10 certificate signing request (CSR) file. Pass the name of the CSR file in the szSubjectPubKeyFile parameter and set the szDistName empty "". The empty distinguished name parameter is a flag that a CSR file is being used. See the example below.

[New in v12.0] Added support for unencrypted private key files for szIssuerPriKeyFile as well as encrypted ones. Specify szPassword="" to flag an unencrypted key.

[New in v12.0] Added support for RSA-PSS and ECDSA signatures. Both the signing key and the subject's public key must be either both RSA keys for the RSA options, or both EC keys for the ECDSA signature options. The MGF hash function for RSA-PSS signatures in an X.509 certificate is always the same as the signature hash function. The signing key must be long enough to include the specified digest value and other encoding bytes. For example, a 1024-bit RSA key is too short to sign using RSA-PSS-SHA512 (see RSA signature and encryption schemes). Not all signature options provided may be accepted by other applications. Note also that both these signature schemes are probabilistic and each new signature contains randomly generated salt values, so you won't reproduce the same certificate even with identical inputs. Use the specialist options PKI_PSS_SALTLEN_ZERO and PKI_SIG_DETERMINISTIC with RSA-PSS and ECDSA, respectively, to force a deterministic (fixed) result.

[New in v12.3] Added ability to specify an empty subjectName, to set extKeyUsage extension purposes in the X.509 Extensions Parameter, and mark an arbitrary extension as critical. Setting szDistName = "$" will create an X.509 document with an empty subjectName. At least one field for a subject alternative name extension (altSubjectName) must be specified and the extension will automatically be marked critical.

char *dn = "$";
char *extns = "iPAddress=192.168.15.1;extKeyUsage=serverAuth,clientAuth,emailProtection,critical;";

[New in v20.5] Added ability to pass an internal key string for the subject's public key and signer's private key.

Example

Dim nRet As Long
Dim strNewCertFile As String
Dim strIssuerCert As String
Dim strSubjectPubKeyFile As String
Dim strIssuerPriKeyFile As String
Dim strPassword As String
Dim nCertNum As Long
Dim nYearsValid As Long
Dim strDistName As String
Dim strEmail As String
strNewCertFile = "myuser.cer"
strIssuerCert = "myca.cer"
strSubjectPubKeyFile = "mykey.pub"
strIssuerPriKeyFile = "myca.p8e"
strPassword = "password"  '!!
nCertNum = &H101
nYearsValid = 4
strDistName = "CN=My User;O=Test Org;OU=Unit;C=AU;L=My Town;S=State;E=myuser@testorg.com"
strEmail = "myuser@testorg.com"

nRet = X509_MakeCert(strNewCertFile, strIssuerCert, strSubjectPubKeyFile, strIssuerPriKeyFile, _
    nCertNum, nYearsValid, strDistName, strEmail, 0, strPassword, 0)
If nRet <> 0 Then
    Debug.Print nRet & " " & pkiErrorLookup(nRet)
Else
    Debug.Print "Success, created X.509 cert " & strNewCertFile
End If

The above example will create a new X.509 certificate with filename myuser.cer. The certificate will be issued by "myca" with serial number 257 (0x101) for the subject with common name "My User", etc. It will be valid from one minute ago today for 4 years. The subject's public key in file mykey.pub will be included and it will be signed by the issuer with certificate myca.cer and private key in file myca.p8e.

The next example in C uses the advanced szExtensions parameter to re-create exactly Alice's certificate from the S/MIME examples [SMIME-EX].

char *certname;
char *issuercert = "CarlRSASelf.cer";
char *pubfile = "AlicePubRSA.pub";
char *epkfile = "CarlPrivRSASign.p8e";
char *password = "password";

char *certfile = "AliceRSA-dup.cer";
char *dn = "CN=AliceRSA";
char *extns = "rfc822name=AliceRSA@example.com;"
	"serialNumber=46346BC7800056BC11D36E2EC410B3B0;"
	"subjectKeyIdentifier=77D2B4D1B74C8A8AA3CE459DCEEC3CA03AE3FF50;"
	"notBefore=1999-09-19T01:08:47;"
	"notAfter=2039-12-31;"
	;
long keyUsage = PKI_X509_KEYUSAGE_DIGITALSIGNATURE + PKI_X509_KEYUSAGE_NONREPUDIATION;
long lRet;
char digest[PKI_SHA1_CHARS+1];

/* Make an end-user cert identical to RFC4134 AliceRSASignByCarl.cer */
certname = certfile;
lRet = X509_MakeCert(certname, issuercert, pubfile, epkfile, 
	0, 99, dn, extns, keyUsage, password, PKI_X509_AUTHKEYID);
assert(lRet == 0);
printf("Created end-user X.509 certificate '%s'\n", certname);

/* Check its SHA-1 thumbprint */
X509_CertThumb(certname, digest, sizeof(digest)-1, 0);
printf("SHA-1 Thumb=%s\n", digest);

This should give the output

Created end-user X.509 certificate 'AliceRSA-dup.cer'
SHA-1 Thumb=b30c48855055c2e64ce3196492d4b83831a6b3cb

See Also

X509_MakeCertSelf

[Contents] [Index]

[PREV: X509_KeyUsageFlags...]   [Contents]   [Index]   
   [NEXT: X509_MakeCertSelf...]

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