DWORD VMCASrvInitCA( VOID ) { DWORD dwError = 0; PVMCA_CERTIFICATE pRootCACert = NULL; PVMCA_KEY pPrivateKey = NULL; PSTR pszRootCertFile = NULL; PSTR pszPrivateKeyFile = NULL; PSTR pszPasswordFile = NULL; PVMCA_X509_CA pCA = NULL; DWORD dwCRLNumberCurrent = 0; BOOL bIsHoldingMutex = FALSE; dwError = VMCAGetRootCertificateFilePath(&pszRootCertFile); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetPrivateKeyPath(&pszPrivateKeyFile); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetPrivateKeyPasswordPath(&pszPasswordFile); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAReadCertificateChainFromFile(pszRootCertFile,&pRootCACert); BAIL_ON_VMCA_ERROR(dwError); // // TODO : Support Passwords for private key // dwError = VMCAReadPrivateKeyFromFilePrivate( pszPrivateKeyFile, NULL, &pPrivateKey); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAValidateCACertificatePrivate( (LPSTR) pRootCACert, NULL, pPrivateKey); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCACreateCA( pRootCACert, pPrivateKey, NULL, &pCA); BAIL_ON_VMCA_ERROR(dwError); if (BN_num_bits(pCA->pKey->pkey.rsa->n) < VMCA_MIN_CA_CERT_PRIV_KEY_LENGTH) { dwError = VMCA_ERROR_INVALID_KEY_LENGTH; BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCASrvSetCA(pCA); BAIL_ON_VMCA_ERROR(dwError); pthread_mutex_lock (&gVMCAServerGlobals.mutexCRL); bIsHoldingMutex = TRUE; dwError = VmcaDbGetCurrentCRLNumber(&dwCRLNumberCurrent); if (dwError == ERROR_OBJECT_NOT_FOUND) { dwError = 0; dwCRLNumberCurrent = 0; } BAIL_ON_VMCA_ERROR (dwError); gVMCAServerGlobals.dwCurrentCRLNumber = dwCRLNumberCurrent; pthread_mutex_unlock (&gVMCAServerGlobals.mutexCRL); bIsHoldingMutex = FALSE; error: if ( pPrivateKey != NULL ) { VMCAFreeKey(pPrivateKey); } if (pRootCACert != NULL) { VMCAFreeCertificate(pRootCACert); } if (bIsHoldingMutex) { pthread_mutex_unlock(&gVMCAServerGlobals.mutexCRL); } VMCA_SAFE_FREE_STRINGA(pszRootCertFile); VMCA_SAFE_FREE_STRINGA(pszPrivateKeyFile); VMCA_SAFE_FREE_STRINGA(pszPasswordFile); if (pCA) { VMCAReleaseCA(pCA); } return dwError; }
unsigned int VMCAAddRootCertificate( unsigned char *pszRootCertificate, PWSTR pszPassPhrase, unsigned char *pszPrivateKey, unsigned int dwOverWrite) { DWORD dwError = 0; BOOL bFileExists = FALSE; BOOL bOverWrite = FALSE; BOOLEAN bLocked = FALSE; PSTR pszRootCertFile = NULL; PSTR pszPrivateKeyFile = NULL; PSTR pszPasswordFile = NULL; PSTR pszDataDirectory = NULL; #ifndef _WIN32 struct stat buf = { 0 }; #else struct _stat buf = { 0 }; #endif bOverWrite = (dwOverWrite == 1); // // Grab exclusive lock since we are writing the Root Cert, // and all operations must serialize for this op. // VMCA_LOCK_MUTEX_EXCLUSIVE(&gVMCAServerGlobals.svcMutex, bLocked); dwError = VMCAValidateCACertificatePrivate((LPSTR) pszRootCertificate,NULL, (LPSTR)pszPrivateKey); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetRootCertificateFilePath(&pszRootCertFile); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetPrivateKeyPath(&pszPrivateKeyFile); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetPrivateKeyPasswordPath(&pszPasswordFile); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetDataDirectory(&pszDataDirectory); BAIL_ON_VMCA_ERROR(dwError); bFileExists = (stat(pszRootCertFile,&buf) == ERROR_SUCCESS); if (!bOverWrite && bFileExists) { dwError = VMCA_ROOT_CA_ALREADY_EXISTS; BAIL_ON_VMCA_ERROR(dwError); } if (bOverWrite && bFileExists) { dwError = VMCABackupRootCAFiles(pszRootCertFile, pszPrivateKeyFile, pszPasswordFile); BAIL_ON_VMCA_ERROR(dwError); } if (!bFileExists) { dwError = VMCACreateDirectory(pszDataDirectory, TRUE); BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAWriteCertificateChainToFile(pszRootCertFile, (PVMCA_CERTIFICATE) pszRootCertificate); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAWritePrivateKeyToFile( pszPrivateKeyFile, (LPSTR) pszPrivateKey, pszPasswordFile, pszPassPhrase); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCASetKeyPerm(pszPrivateKeyFile); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCASrvInitCA(); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCASrvNotifyDirSync(); BAIL_ON_VMCA_ERROR(dwError); #if 0 #ifdef DEBUG PrintCurrentState(); #endif #endif error : VMCA_LOCK_MUTEX_UNLOCK(&gVMCAServerGlobals.svcMutex, bLocked); if ( pszRootCertFile != NULL) { VMCAFreeStringA(pszRootCertFile); } if( pszPrivateKeyFile != NULL) { VMCAFreeStringA(pszPrivateKeyFile); } if( pszPasswordFile != NULL ) { VMCAFreeStringA(pszPasswordFile); } if (pszDataDirectory != NULL) { VMCAFreeStringA(pszDataDirectory); } return dwError; }