DWORD VMCASrvPublishRootCerts( VOID ) { DWORD dwError = 0; dwError = VMCASrvValidateCA(); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCASrvNotifyDirSync(); BAIL_ON_VMCA_ERROR(dwError); error: return dwError; }
DWORD VMCARevokeCertificate( unsigned char *pszCertificate) { DWORD dwError = 0; PVMCA_DB_CERTIFICATE_ENTRY pEntry = NULL; PVMCA_DB_CONTEXT pContext = NULL; BOOLEAN bLocked = FALSE; VMCA_LOCK_MUTEX_EXCLUSIVE(&gVMCAServerGlobals.svcMutex, bLocked); dwError = VMCASrvValidateCA(); BAIL_ON_VMCA_ERROR(dwError); dwError = VmcaDbCreateContext(&pContext); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCADecodeCert((LPSTR)pszCertificate, &pEntry); BAIL_ON_VMCA_ERROR(dwError); dwError = VmcaDbRevokeCertificate(pContext, pEntry->pwszSerial); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAUpdateCRL((LPSTR)pszCertificate, 0); //Reason Unknown BAIL_ON_VMCA_ERROR(dwError); error: VMCA_LOCK_MUTEX_UNLOCK(&gVMCAServerGlobals.svcMutex, bLocked); if (pContext != NULL) { VmcaDbReleaseContext(pContext); pContext = NULL; } if(pEntry != NULL) { VMCAFreeDBEntryFields(pEntry); } pEntry = NULL; return dwError; }
static DWORD VMCASrvUpdateRootCerts( PVMCA_DIR_SYNC_PARAMS pDirSyncParams, PBOOLEAN pbSynced ) { DWORD dwError = 0; PVMCA_X509_CA pCA = NULL; PSTR pszAccount = NULL; PSTR pszPassword = NULL; PSTR pszDomainName = NULL; PSTR pszCAContainerDN = NULL; PSTR pszCertificate = NULL; PSTR pszCRL = NULL; X509_CRL* pCrl = NULL; DWORD dwCount = 0; DWORD dwIndex = 0; PVMCA_LDAP_CONTEXT pContext = NULL; PSTR pszUPN = NULL; dwError = VMCASrvValidateCA(); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCASrvGetCA(&pCA); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCASrvGetMachineAccountInfoA( &pszAccount, &pszDomainName, &pszPassword); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringPrintfA( &pszUPN, "%s@%s", pszAccount, pszDomainName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCALdapConnect( "localhost", 0, /* use default port */ pszUPN, pszPassword, &pContext); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetDSERootAttribute( pContext, "configurationNamingContext", &pszCAContainerDN); BAIL_ON_VMCA_ERROR(dwError); dwError = VmcaSrvReGenCRL( &pCrl ); BAIL_ON_VMCA_ERROR (dwError); dwError = VMCACRLToPEM( pCrl, &pszCRL ); BAIL_ON_VMCA_ERROR (dwError); dwCount = sk_X509_num(pCA->skCAChain); for (; dwIndex <dwCount; dwIndex++) { X509 *pCert = sk_X509_value( pCA->skCAChain, dwIndex ); dwError = VMCAUpdatePkiCAAttribute( pContext, pszCAContainerDN, pCert ); BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAUpdateCrlCAAttribute( pContext, pszCAContainerDN, pszCRL ); BAIL_ON_VMCA_ERROR (dwError); *pbSynced = TRUE; cleanup: VMCA_SAFE_FREE_STRINGA(pszUPN); VMCA_SAFE_FREE_STRINGA(pszDomainName); VMCA_SAFE_FREE_STRINGA(pszCertificate); VMCA_SAFE_FREE_STRINGA(pszAccount); VMCA_SAFE_FREE_STRINGA(pszPassword); VMCA_SAFE_FREE_STRINGA(pszCRL); if (pContext) { VMCALdapClose(pContext); } if (pCA) { VMCAReleaseCA(pCA); } return dwError; error: *pbSynced = FALSE; VMCA_LOG_ERROR("Failed to update root certs due to error [%u]", dwError); // TODO : Check specific errors dwError = 0; goto cleanup; }
unsigned int VMCAGetSignedCertificate( unsigned char *pszPEMEncodedCSRRequest, unsigned int dwtmNotBefore, unsigned int dwtmNotAfter, PVMCA_CERTIFICATE_CONTAINER *ppCertContainer ) { DWORD dwError = 0; time_t now = dwtmNotBefore; time_t expire = dwtmNotAfter; PSTR pCert = NULL; PVMCA_DB_CERTIFICATE_ENTRY pEntry = NULL; PVMCA_X509_CA pCA = NULL; PVMCA_CERTIFICATE_CONTAINER pCertContainer = NULL; BOOLEAN bLocked = FALSE; VMCA_LOCK_MUTEX_EXCLUSIVE(&gVMCAServerGlobals.svcMutex, bLocked); dwError = VMCASrvValidateCA(); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCASrvGetCA(&pCA); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCASignedRequestPrivate( pCA, (char *)pszPEMEncodedCSRRequest, (char**)&pCert, now, expire); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCARpcAllocateCertificateContainer(pCert, &pCertContainer); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCADecodeCert(pCert, &pEntry); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAInsertCertificate(pEntry); BAIL_ON_VMCA_ERROR(dwError); // TODO : check for errors strcpy((char*)pCertContainer->pCert, pCert); *ppCertContainer = pCertContainer; cleanup : VMCA_LOCK_MUTEX_UNLOCK(&gVMCAServerGlobals.svcMutex, bLocked); VMCAFreeDBEntryFields(pEntry); VMCA_SAFE_FREE_STRINGA(pCert); if (pCA) { VMCAReleaseCA(pCA); } return dwError; error: if (ppCertContainer) { *ppCertContainer = NULL; } if (pCertContainer) { VMCARpcFreeCertificateContainer(pCertContainer); } goto cleanup; }
unsigned int VMCAEnumCertificates( unsigned int dwStartIndex, unsigned int dwNumCertificates, CERTIFICATE_STATUS dwStatus, VMCA_CERTIFICATE_ARRAY** ppCertArray ) { DWORD dwError = 0; PVMCA_DB_CONTEXT pDbContext = NULL; PVMCA_CERTIFICATE_ARRAY pCertArray = NULL; PVMCA_DB_CERTIFICATE_ENTRY pDbCertEntryArray = NULL; DWORD dwDbCertEntryNums = 0; BOOLEAN bLocked = FALSE; VMCA_LOCK_MUTEX_SHARED(&gVMCAServerGlobals.svcMutex, bLocked); dwError = VMCASrvValidateCA(); BAIL_ON_VMCA_ERROR(dwError); dwError = VmcaDbCreateContext(&pDbContext); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCADbEnumCerts( pDbContext, dwStartIndex, dwNumCertificates, dwStatus, &pDbCertEntryArray, &dwDbCertEntryNums); BAIL_ON_VMCA_ERROR(dwError); // convert db struct into rpc struct ... dwError = VMCACloneCertContainerFromDbCertEntryArray( pDbCertEntryArray, dwDbCertEntryNums, &pCertArray); BAIL_ON_VMCA_ERROR(dwError); *ppCertArray = pCertArray; cleanup: VMCA_LOCK_MUTEX_UNLOCK(&gVMCAServerGlobals.svcMutex, bLocked); if (pDbContext) { VmcaDbReleaseContext(pDbContext); } if (pDbCertEntryArray) { VmcaDbFreeCertEntryArray(pDbCertEntryArray, dwDbCertEntryNums); } // if 0 certificate returned, then we need to set memory to NULL to make sure no rpc free being called on grabage pointer. if (pCertArray){ if (pCertArray->dwCount == 0){ pCertArray->certificates = NULL; VMCARpcFreeCertificateArray(pCertArray); pCertArray = NULL; } } return dwError; error: *ppCertArray = NULL; if (pCertArray) { VMCARpcFreeCertificateArray(pCertArray); } goto cleanup; }
unsigned int VMCAGenerateCRL () { DWORD dwCertCount = 0; DWORD dwError = 0; DWORD dwCount = 0; PVMCA_DB_CONTEXT pDbContext = NULL; PVMCA_DB_CERTIFICATE_ENTRY pCertEntryArray = NULL; PSTR pszCrlTempNamePath = NULL; time_t tmNextUpdate = 0; time_t tmLastUpdate = 0; X509_CRL *pCrl = NULL; X509 *pCert = NULL; DWORD dwCrlNum = 0; PVMCA_X509_CA pCA = NULL; BOOLEAN bLocked = FALSE; DWORD x = 0; VMCA_LOCK_MUTEX_SHARED(&gVMCAServerGlobals.svcMutex, bLocked); dwError = VMCASrvValidateCA(); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCASrvGetCA(&pCA); BAIL_ON_VMCA_ERROR(dwError); dwError = VmcaDbCreateContext(&pDbContext); BAIL_ON_VMCA_ERROR(dwError); dwError = VmcaDbGetTotalCertificateCount( pDbContext, &dwCertCount, VMCA_CERTIFICATE_REVOKED); BAIL_ON_VMCA_ERROR(dwError); if (dwCertCount) { dwError = VmcaDbQueryCertificatesPaged( pDbContext, 0, dwCertCount, VMCA_DB_CERTIFICATE_STATUS_REVOKED, &pCertEntryArray, &dwCount); BAIL_ON_VMCA_ERROR(dwError); } // Database operations are done VMCA_LOCK_MUTEX_UNLOCK(&gVMCAServerGlobals.svcMutex, bLocked); dwError = VMCAGetTempCRLNamePath(&pszCrlTempNamePath); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAOpenCRLPrivate(pCA, pszCrlTempNamePath, &pCrl); BAIL_ON_VMCA_ERROR(dwError); for (x = 0; x < dwCount; x++) { dwError = VMCAPEMToX509((PSTR)pCertEntryArray[x].pCertBlob, &pCert); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAddCertToCRL(pCrl, pCert , 1); BAIL_ON_VMCA_ERROR(dwError); X509_free(pCert); pCert = NULL; } dwError = VMCAGetNextCrlNumber(pCrl, &dwCrlNum); BAIL_ON_VMCA_ERROR(dwError); tmLastUpdate = time(NULL); dwError = VMCAGetNextUpdateTime(pCrl, &tmNextUpdate); if (dwError == VMCA_CRL_NULL_TIME ) { tmNextUpdate = tmLastUpdate + ( VMCAGetDefaultValidityPeriod() * 24 * 60 * 60); dwError = 0; } BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAUpdateTimeStamps (pCrl, tmLastUpdate, tmNextUpdate, dwCrlNum); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCASortCRL(pCrl); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCACrlSign(pCrl, pCA); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCACRLToFile(pCrl, pszCrlTempNamePath); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCACopyTempCRLtoCRL(); BAIL_ON_VMCA_ERROR(dwError); error : VMCA_LOCK_MUTEX_UNLOCK(&gVMCAServerGlobals.svcMutex, bLocked); if (pCrl) { VMCACrlFree(pCrl); } if(pCert != NULL) { X509_free(pCert); } VMCA_SAFE_FREE_STRINGA(pszCrlTempNamePath); if (pCertEntryArray) { VmcaDbFreeCertEntryArray(pCertEntryArray, dwCount); } if (pDbContext) { VmcaDbReleaseContext(pDbContext); } if (pCA) { VMCAReleaseCA(pCA); } return dwError; }
unsigned int VMCAGetCRL( unsigned char *pszClientCachedCRLID, unsigned int dwFileOffset, unsigned int dwSize, VMCA_FILE_BUFFER **ppCRLData ) { DWORD dwError = 0; PVMCA_FILE_BUFFER pCRLData = NULL; DWORD dwCount = 0; PSTR pszCRLFile = NULL; unsigned char buff[FILE_CHUNK] = { 0 }; BOOLEAN bLocked = FALSE; VMCA_LOCK_MUTEX_SHARED(&gVMCAServerGlobals.svcMutex, bLocked); dwError = VMCASrvValidateCA(); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetCRLNamePath(&pszCRLFile); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCARpcAllocateMemory( sizeof(VMCA_FILE_BUFFER), (PVOID*)&pCRLData); BAIL_ON_VMCA_ERROR(dwError); memset(pCRLData, 0, sizeof(VMCA_FILE_BUFFER)); dwError = VMCAReadDataFromFile( pszCRLFile, dwFileOffset, dwSize, (char*)&buff, &dwCount); BAIL_ON_VMCA_ERROR(dwError); if (dwCount > 0) { dwError = VMCARpcAllocateMemory(dwCount * sizeof(unsigned char), (PVOID*) &pCRLData->buffer); BAIL_ON_VMCA_ERROR(dwError); memcpy((PVOID) pCRLData->buffer, buff,(size_t) dwCount); } pCRLData->dwCount = dwCount; *ppCRLData = pCRLData; cleanup : VMCA_LOCK_MUTEX_UNLOCK(&gVMCAServerGlobals.svcMutex, bLocked); VMCA_SAFE_FREE_STRINGA(pszCRLFile); return dwError; error: if(pCRLData != NULL) { if(pCRLData->buffer != NULL) { VMCARpcFreeMemory((PVOID) pCRLData->buffer); } VMCARpcFreeMemory((PVOID)pCRLData); } if(ppCRLData) { *ppCRLData = NULL; } goto cleanup; }