Creates an X.509 certificate using subject's public key and issuer's private key files.
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)
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);
serialNumber
is set in szExtensions.""
or NULL
to ignore.
Option | To set |
---|---|
PKI_X509_KEYUSAGE_DIGITALSIGNATURE | digitalSignature |
PKI_X509_KEYUSAGE_NONREPUDIATION | nonRepudiation |
PKI_X509_KEYUSAGE_KEYENCIPHERMENT | keyEncipherment |
PKI_X509_KEYUSAGE_DATAENCIPHERMENT | dataEncipherment |
PKI_X509_KEYUSAGE_KEYAGREEMENT | keyAgreement |
PKI_X509_KEYUSAGE_KEYCERTSIGN | keyCertSign |
PKI_X509_KEYUSAGE_CRLSIGN | cRLSign |
PKI_X509_KEYUSAGE_ENCIPHERONLY | encipherOnly |
PKI_X509_KEYUSAGE_DECIPHERONLY | decipherOnly |
""
if key not encrypted [New in v12.0].sha1WithRSAEncryption
(default - CAUTION)sha224WithRSAEncryption
sha256WithRSAEncryption
[minimum recommended]sha384WithRSAEncryption
sha512WithRSAEncryption
md5WithRSAEncryption
[legacy, not recommended]md2WithRSAEncryption
[legacy, definitely not recommended]RSA-PSS-SHA1
RSA-PSS-SHA224
RSA-PSS-SHA256
RSA-PSS-SHA384
RSA-PSS-SHA512
ecdsaWithSHA1
ecdsaWithSHA224
ecdsaWithSHA256
ecdsaWithSHA384
ecdsaWithSHA512
Ed25519
[New in v20.0]Ed448
[New in v22.0]basicConstraints
subject type to be a CA (default = End Entity)basicConstraints
extension (default = include)UTF8String
(default = PrintableString)If successful, the return value is zero; otherwise it returns a nonzero error code.
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)
static X509.make_cert(newcertfile, issuercert, subject_pubkeyfile, issuer_prikeyfile, password, certnum=0, yearsvalid=0, distname="", extns="", keyusage=KeyUsageFlags.NONE, sigalg=0, opts=0)
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.
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