#ifdef WIN32
# include <windows.h>
#endif
#include "npki.h"
#include "pkierr.h"
#define SECONDS_IN_DAY 24 * 60 * 60
#define SECONDS_IN_YEARS 365 * 24 * 60 * 60
NWRCODE CreateCA(void)
{
NWRCODE ccode = PKI_SUCCESS;
NPKIContext myPKI = NPKI_INVALID_CONTEXT;
unicode const *organizationalCADN;
nuint32 signatureAlgorithms;
nuint32 keyGenerationAlgorithms;
nuint32 maxValidFromTime;
nuint32 maxValidToTime;
nuint32 currentServerTime;
nuint32 maxSignKeySize;
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 hostServerDN[] = {'T','e','s','t','5','1','.','n','o','v','e','l','l',0};
unicode cAName[] = {'O','r','g','a','n','i','z','a','t','i','o','n','a','l',' ','C','A',0};
NPKI_Extension basicConstraints = {PKI_EXTENSION_INCLUDE | X509_BASIC_CONSTRAINTS_CA, 0};
NPKI_Extension keyUsage;
nuint16 caKeyUsage = X509_KEY_USAGE_KEY_CERT_SIGN | X509_KEY_USAGE_CRL_SIGN;
unicode subjectDN[] = {'.','O','U','=','O','r','g','a','n','i','z','a','t','i','o','n','a','l',' ','C','A','.','O','=','C','o','m','p','a','n','y',' ','N','a','m','e',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 = NPKIGetServerUTCTime
(
myPKI,
hostServerDN,
¤tServerTime
);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
currentServerTime-= (2 * SECONDS_IN_DAY);
ccode = NPKIGetServerInfo
(
myPKI,
hostServerDN,
PKI_CA_INFO,
&keyGenerationAlgorithms,
&signatureAlgorithms,
&maxValidFromTime,
&maxValidToTime,
NULL,
NULL,
NULL,
NULL,
NULL
);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
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,
NULL,
&maxSignKeySize,
NULL,
NULL,
NULL
);
if (ccode != PKI_SUCCESS)
{
goto ERR_EXIT;
}
if (maxValidFromTime < currentServerTime)
maxValidFromTime = currentServerTime;
if (maxValidToTime > currentServerTime + (10 * SECONDS_IN_YEARS))
maxValidToTime = currentServerTime + (10 * SECONDS_IN_YEARS);
#ifndef HI_LO_MACH_TYPE
{
nuint16 newValue = 0;
nuint8 *oldValuePtr = (nuint8 *)&caKeyUsage;
nuint8 *newValuePtr = (nuint8 *)&newValue;
newValuePtr[0] = oldValuePtr[1];
newValuePtr[1] = oldValuePtr[0];
caKeyUsage = newValue;
}
#endif
keyUsage.flags = PKI_EXTENSION_INCLUDE;
keyUsage.length = sizeof(caKeyUsage);
keyUsage.value = (nuint8 *) &caKeyUsage;
ccode = NPKICreateOrganizationalCA
(
myPKI,
hostServerDN,
cAName,
PKI_RSA_ALGORITHM,
maxSignKeySize,
subjectDN,
PKI_SIGN_WITH_RSA_AND_SHA1,
DEFAULT_YEAR_ENCODING,
maxValidFromTime,
maxValidToTime,
PUBLIC_KEY_ORGANIZATIONAL_CA,
PRIVATE_KEY | PRIVATE_KEY_EXTRACTABLE,
&keyUsage,
&basicConstraints,
NULL,
NULL,
NULL,
&organizationalCADN,
0,
NULL,
NULL
);
if (ccode != PKI_SUCCESS)
{
int count = 0;
while (ccode == -601 && count < 5)
{
count++;
Sleep(1000*count);
ccode = NPKICreateOrganizationalCA
(
myPKI,
hostServerDN,
cAName,
PKI_RSA_ALGORITHM,
maxSignKeySize,
subjectDN,
PKI_SIGN_WITH_RSA_AND_SHA1,
DEFAULT_YEAR_ENCODING,
maxValidFromTime,
maxValidToTime,
PUBLIC_KEY_ORGANIZATIONAL_CA,
PRIVATE_KEY | PRIVATE_KEY_EXTRACTABLE,
&keyUsage,
&basicConstraints,
NULL,
NULL,
NULL,
&organizationalCADN,
1,
NULL,
NULL
);
}
}
ERR_EXIT:
NPKIDSLogout (myPKI);
if (myPKI != NPKI_INVALID_CONTEXT)
NPKIFreeContext(myPKI);
return ccode;
}