bool CertStore::remove( const QSslCertificate &cert ) { if( !d->s ) return false; PCCERT_CONTEXT context = d->certContext( cert ); if( !context ) return false; bool result = false; PCCERT_CONTEXT scontext = 0; while( (scontext = CertEnumCertificatesInStore( d->s, scontext )) ) { if( CertCompareCertificate( X509_ASN_ENCODING, context->pCertInfo, scontext->pCertInfo ) ) result = CertDeleteCertificateFromStore( CertDuplicateCertificateContext( scontext ) ); } CertFreeCertificateContext( context ); return result; }
/** * Removes a certificate, given by file, from a store * * @returns true on success, false on failure (error message written). * @param dwDst The destination, like * CERT_SYSTEM_STORE_LOCAL_MACHINE or * ERT_SYSTEM_STORE_CURRENT_USER. * @param pszStoreNm The store name. * @param pszCertFile The file containing the certificate to add. */ static bool removeCertFromStoreByFile(DWORD dwDst, const char *pszStoreNm, const char *pszCertFile) { /* * Read the certificate file first. */ PCCERT_CONTEXT pSrcCtx = NULL; HCERTSTORE hSrcStore = NULL; if (!readCertFile(pszCertFile, &pSrcCtx, &hSrcStore)) return false; WCHAR wszName[1024]; if (!CertGetNameStringW(pSrcCtx, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0 /*dwFlags*/, NULL /*pvTypePara*/, wszName, sizeof(wszName))) { RTMsgError("CertGetNameStringW(Subject) failed: %s\n", errorToString(GetLastError())); wszName[0] = '\0'; } /* * Open the destination store. */ bool fRc = false; HCERTSTORE hDstStore = openCertStore(dwDst, pszStoreNm); if (hDstStore) { if (pSrcCtx) { fRc = true; unsigned cDeleted = 0; PCCERT_CONTEXT pCurCtx = NULL; while ((pCurCtx = CertEnumCertificatesInStore(hDstStore, pCurCtx)) != NULL) { if (CertCompareCertificate(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, pCurCtx->pCertInfo, pSrcCtx->pCertInfo)) { if (g_cVerbosityLevel > 1) RTMsgInfo("Removing '%ls'...", wszName); PCCERT_CONTEXT pDeleteCtx = CertDuplicateCertificateContext(pCurCtx); if (pDeleteCtx) { if (CertDeleteCertificateFromStore(pDeleteCtx)) cDeleted++; else RTMsgError("CertDeleteFromStore('%ls') failed: %s\n", wszName, errorToString(GetLastError())); } else RTMsgError("CertDuplicateCertificateContext('%ls') failed: %s\n", wszName, errorToString(GetLastError())); } } if (!cDeleted) RTMsgInfo("Found no matching certificates to remove."); } else { RTMsgError("Path not implemented at line %d\n", __LINE__); } CertCloseStore(hDstStore, CERT_CLOSE_STORE_CHECK_FLAG); } if (pSrcCtx) CertFreeCertificateContext(pSrcCtx); if (hSrcStore) CertCloseStore(hSrcStore, CERT_CLOSE_STORE_CHECK_FLAG); return fRc; }
DWORD StoreUserCert (PCCERT_CONTEXT pCertContext, unsigned char KeyUsageBits, CK_BYTE* cardSerialNumber, CK_ULONG cardSerialNumberLen) { unsigned long dwFlags = CERT_STORE_NO_CRYPT_RELEASE_FLAG; PCCERT_CONTEXT pDesiredCert = NULL; PCCERT_CONTEXT pPrevCert = NULL; DWORD dwRet = 0; wchar_t* pContainerName = NULL; size_t pContainerNameCharLen = cardSerialNumberLen+20; CK_CHAR_PTR pcardSerialNrString = NULL; wchar_t* pProviderName = NULL; CK_ULONG counter=0; HCERTSTORE hMyStore = CertOpenSystemStore((HCRYPTPROV_LEGACY)NULL, TEXT("MY")); CRYPT_KEY_PROV_INFO cryptKeyProvInfo; unsigned long dwPropId = CERT_KEY_PROV_INFO_PROP_ID; if (hMyStore == NULL) { dwRet = GetLastError(); printf("StoreUserCerts: Unable to open the system certificate store. Error code: %d.\n",dwRet); return dwRet; } // ---------------------------------------------------- // look if we already have a certificate with the same // subject (contains name and NNR) in the store // If the certificate is not found --> NULL // ---------------------------------------------------- do { if( NULL != (pDesiredCert = CertFindCertificateInStore(hMyStore, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &(pCertContext->pCertInfo->Subject) , pPrevCert))) { // ---------------------------------------------------- // If the certificates are identical and function // succeeds, the return value is nonzero, or TRUE. // ---------------------------------------------------- if(FALSE == CertCompareCertificate(X509_ASN_ENCODING,pCertContext->pCertInfo,pDesiredCert->pCertInfo) || !ProviderNameCorrect(pDesiredCert) ) { // ---------------------------------------------------- // certificates are not identical, but have the same // subject (contains name and NNR), // so we remove the one that was already in the store // ---------------------------------------------------- if(FALSE == CertDeleteCertificateFromStore(pDesiredCert)) { if (E_ACCESSDENIED == GetLastError()) { continue; } } pPrevCert = NULL; continue; } } pPrevCert = pDesiredCert; }while (NULL != pDesiredCert); // ---------------------------------------------------- // look if we already have the certificate in the store // If the certificate is not found --> NULL // ---------------------------------------------------- if( NULL != (pDesiredCert = CertFindCertificateInStore(hMyStore, X509_ASN_ENCODING, 0, CERT_FIND_EXISTING, pCertContext , NULL))) { // ---------------------------------------------------- // certificate is already in the store, then just return // ---------------------------------------------------- CertFreeCertificateContext(pDesiredCert); CertCloseStore (hMyStore, CERT_CLOSE_STORE_FORCE_FLAG); return 0; } pContainerName = (wchar_t*)malloc(sizeof(wchar_t) * (pContainerNameCharLen)); if(pContainerName == NULL) return E_OUTOFMEMORY; pcardSerialNrString = (CK_CHAR_PTR)malloc(cardSerialNumberLen*2 + 1); if(pcardSerialNrString == NULL) return E_OUTOFMEMORY; if(-1 == ByteArrayToString( &pcardSerialNrString, cardSerialNumberLen*2 + 1,cardSerialNumber ,cardSerialNumberLen)) return -1; if(pContainerName == NULL) { CertFreeCertificateContext(pDesiredCert); CertCloseStore (hMyStore, CERT_CLOSE_STORE_FORCE_FLAG); return -1; } if (UseMinidriver()) { if (KeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE) { swprintf_s(pContainerName,pContainerNameCharLen,L"NR_%hS",pcardSerialNrString); } else { swprintf_s(pContainerName,pContainerNameCharLen,L"DS_%hS",pcardSerialNrString); } cryptKeyProvInfo.pwszProvName = L"Microsoft Base Smart Card Crypto Provider"; cryptKeyProvInfo.dwKeySpec = AT_SIGNATURE; } else { if (KeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE) { swprintf_s(pContainerName,pContainerNameCharLen,L"Signature(%hS)",pcardSerialNrString); } else { swprintf_s(pContainerName,pContainerNameCharLen,L"Authentication(%hS)",pcardSerialNrString); } cryptKeyProvInfo.pwszProvName = L"Belgium Identity Card CSP"; cryptKeyProvInfo.dwKeySpec = AT_KEYEXCHANGE; } cryptKeyProvInfo.pwszContainerName = pContainerName; cryptKeyProvInfo.dwProvType = PROV_RSA_FULL; cryptKeyProvInfo.dwFlags = 0; cryptKeyProvInfo.cProvParam = 0; cryptKeyProvInfo.rgProvParam = NULL; /* // Set friendly names for the certificates DWORD dwsize = 0; dwsize = CertGetNameStringW(pCertContext, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, NULL, dwsize); auto_vec<WCHAR> pname(new WCHAR[dwsize]); dwsize = CertGetNameStringW(pCertContext, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, pname.get(), dwsize); CRYPT_DATA_BLOB tpFriendlyName = {0, 0}; tpFriendlyName.pbData = (BYTE *)pname.get(); tpFriendlyName.cbData = dwsize * sizeof(WCHAR); if (CertSetCertificateContextProperty( pCertContext, // A pointer to the certificate // where the propertiy will be set. CERT_FRIENDLY_NAME_PROP_ID, // An identifier of the property to be set. // In this case, CERT_KEY_PROV_INFO_PROP_ID // is to be set to provide a pointer with the // certificate to its associated private key // container. dwFlags, // The flag used in this case is // CERT_STORE_NO_CRYPT_RELEASE_FLAG // indicating that the cryptographic // context aquired should not // be released when the function finishes. &tpFriendlyName // A pointer to a data structure that holds // infomation on the private key container to // be associated with this certificate. )) */ // Set the property. if (CertSetCertificateContextProperty( pCertContext, // A pointer to the certificate where the property will be set. dwPropId, // An identifier of the property to be set. // In this case, CERT_KEY_PROV_INFO_PROP_ID is to be set to provide a pointer with the certificate to its associated private key container. dwFlags, // The flag used in this case is // CERT_STORE_NO_CRYPT_RELEASE_FLAG indicating that the cryptographic context acquired should not be released when the function finishes. &cryptKeyProvInfo // A pointer to a data structure that holds infomation on the private key container to be associated with this certificate. )) { if (KeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE) { CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_EMAIL_PROTECTION); } else { CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_EMAIL_PROTECTION); CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_CLIENT_AUTH); } if (CertAddCertificateContextToStore(hMyStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) { printf("StoreUserCerts: Certificate context added to store."); dwRet = 0; } else { dwRet = GetLastError(); printf("StoreUserCerts: Unable to add certificate context to store. Error code: %d.",dwRet); } CertCloseStore (hMyStore, CERT_CLOSE_STORE_FORCE_FLAG); hMyStore = NULL; } if(pContainerName != NULL) free (pContainerName); return dwRet; }