#ifdef WIN32
# include <windows.h>
#endif
#include "npki.h"
#include "pkierr.h"
#define SECONDS_IN_YEARS 365 * 24 * 60 * 60
#define MAX_KEY_GEN_SIZE 1024
NWRCODE CreateUserCertificate(void)
{
NWRCODE ccode = PKI_SUCCESS;
NPKIContext myPKI = NPKI_INVALID_CONTEXT;
unicode const *organizationalCADN = NULL;
unicode const *keyGenSeverDN = NULL;
unicode const *signingServerDN = NULL;
nuint32 numberOfServers = 0;
nuint32 currentServerTime = 0;
nuint32 keyGenerationAlgorithms = 0;
nuint32 signatureAlgorithms = 0;
nuint32 maxValidFromTime = 0;
nuint32 maxValidToTime = 0;
nuint32 caOperational = 0;
nuint32 keyGenCAStatus = 0;
nuint32 maxKeyEncryptKeySize = 0;
nuint32 maxSignKeySize = 0;
nuint32 maxKeySize = 0;
unicode myTree[] = {'T','E','S','T',0};
unicode myUser[] = {'A','d','m','i','n','.','n','o','v','e','l','l',0};
char password[] = {'t','e','s','t',0};
char* startIPAddress = "192.168.0.2";
unicode myNameContext[] = {'n','o','v','e','l','l',0};
unicode myNick[] = {'n','i','c','k','n','a','m','e',0};
unicode myEmailName[] = {'u','s','e','r','@','c','o','m','p','a','n','y','.c','o','m',0};
nuint32 publicKeyFlags = PUBLIC_KEY_TWO_SERVER;
nuint16 sslKeyUsage = X509_KEY_USAGE_DIGITAL_SIGNATURE | X509_KEY_USAGE_KEY_ENCIPHERMENT;
NPKI_Extension keyUsage = {0};
NPKI_ExtAltNames subAltNames = {0};
NPKI_AltName altName[1] = {0};
ccode = NPKICreateContext(&myPKI);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
ccode = NPKISetTreeName(myPKI, myTree);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
ccode = NPKIConnectToIPAddress(myPKI, 0, 0, startIPAddress, NULL, NULL);
ccode = NPKIDSLogin(myPKI, myUser, password);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
ccode = NPKIFindOrganizationalCA(myPKI, &organizationalCADN);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
ccode = NPKIGetHostServerDN(myPKI, organizationalCADN, &signingServerDN);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
ccode = NPKIGetServerUTCTime
(
myPKI,
signingServerDN,
¤tServerTime
);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
ccode = NPKIGetServerInfo
(
myPKI,
signingServerDN,
PKI_USER_INFO,
NULL,
&signatureAlgorithms,
&maxValidFromTime,
&maxValidToTime,
&caOperational,
NULL,
NULL,
NULL,
NULL
);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
if (caOperational != PKI_ORGANIZATIONAL_CA)
{
ccode = PKI_E_CA_NOT_OPERATIONAL;
goto ERR_EXIT;
}
if (!(signatureAlgorithms & PKI_SIGN_WITH_RSA_AND_SHA1))
{
ccode = PKI_E_ALGORITHM_NOT_SUPPORTED;
goto ERR_EXIT;
}
ccode = NPKIFindKeyGenServersForUser(myPKI, myNameContext, &numberOfServers);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
if (numberOfServers < 1)
{
ccode = PKI_E_NOT_CONNECTED_TO_SERVICE;
goto ERR_EXIT;
}
ccode = NPKIServerNames (myPKI, 0, &keyGenSeverDN, NULL);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
ccode = NPKIGetServerInfo
(
myPKI,
keyGenSeverDN,
PKI_USER_INFO,
&keyGenerationAlgorithms,
&signatureAlgorithms,
NULL,
NULL,
&keyGenCAStatus,
NULL,
NULL,
NULL,
NULL
);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
if (keyGenCAStatus == PKI_ORGANIZATIONAL_CA)
{
publicKeyFlags = PUBLIC_KEY_SINGLE_SERVER;
}
if (!(keyGenerationAlgorithms & PKI_RSA_ALGORITHM))
{
ccode = PKI_E_ALGORITHM_NOT_SUPPORTED;
goto ERR_EXIT;
}
if (!(signatureAlgorithms & PKI_SIGN_WITH_RSA_AND_SHA1))
{
ccode = PKI_E_ALGORITHM_NOT_SUPPORTED;
goto ERR_EXIT;
}
ccode = NPKIGetAlgorithmInfo
(
myPKI,
PKI_RSA_ALGORITHM,
&maxKeyEncryptKeySize,
&maxSignKeySize,
NULL,
NULL,
NULL
);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
maxKeySize = maxSignKeySize;
if (maxKeyEncryptKeySize < maxKeySize)
maxKeySize = maxKeyEncryptKeySize;
if (maxKeySize > MAX_KEY_GEN_SIZE)
maxKeySize = MAX_KEY_GEN_SIZE;
if (maxValidFromTime < currentServerTime)
maxValidFromTime = currentServerTime;
if (maxValidToTime > currentServerTime + (2 * SECONDS_IN_YEARS))
maxValidToTime = currentServerTime + (2 * SECONDS_IN_YEARS);
altName[0].type = X509_SUBJECT_ALT_NAME_RFC822_NAME;
altName[0].length = 2 * (unilen(myEmailName) + 1);
altName[0].value = (nuint8 *)myEmailName;
subAltNames.flags = PKI_EXTENSION_INCLUDE;
subAltNames.numberOfNames = 1;
subAltNames.altName = altName;
#ifndef HI_LO_MACH_TYPE
{
nuint16 newValue = 0;
nuint8 *oldValuePtr = (nuint8 *)&sslKeyUsage;
nuint8 *newValuePtr = (nuint8 *)&newValue;
newValuePtr[0] = oldValuePtr[1];
newValuePtr[1] = oldValuePtr[0];
sslKeyUsage = newValue;
}
#endif
keyUsage.flags = PKI_EXTENSION_INCLUDE;
keyUsage.length = sizeof(sslKeyUsage);
keyUsage.value = (nuint8 *) &sslKeyUsage;
ccode = NPKICreateUserCertificate
(
myPKI,
keyGenSeverDN,
signingServerDN,
myUser,
myNick,
PKI_RSA_ALGORITHM,
maxKeySize,
NULL,
PKI_SIGN_WITH_RSA_AND_SHA1,
DEFAULT_YEAR_ENCODING,
maxValidFromTime,
maxValidToTime,
publicKeyFlags,
PRIVATE_KEY | PRIVATE_KEY_EXTRACTABLE,
&keyUsage,
NULL,
&subAltNames,
NULL,
NULL,
NULL,
NULL
);
ERR_EXIT:
NPKIDSLogout(myPKI);
if (myPKI != NPKI_INVALID_CONTEXT)
NPKIFreeContext(myPKI);
return ccode;
}