aheinecke@137: #ifdef WIN32 aheinecke@137: aheinecke@161: #include aheinecke@161: aheinecke@137: #include "windowsstore.h" aheinecke@161: #include "errorcodes.h" aheinecke@161: #include "listutil.h" aheinecke@161: #include "strhelp.h" aheinecke@137: aheinecke@222: static LPWSTR aheinecke@222: getLastErrorMsg() aheinecke@163: { aheinecke@163: LPWSTR bufPtr = NULL; aheinecke@163: DWORD err = GetLastError(); aheinecke@163: FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | aheinecke@163: FORMAT_MESSAGE_FROM_SYSTEM | aheinecke@163: FORMAT_MESSAGE_IGNORE_INSERTS, aheinecke@163: NULL, err, 0, (LPWSTR) &bufPtr, 0, NULL); aheinecke@163: if (!bufPtr) aheinecke@163: { aheinecke@185: HMODULE hWinhttp = GetModuleHandleW (L"crypt32"); aheinecke@163: if (hWinhttp) aheinecke@163: { aheinecke@163: FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | aheinecke@163: FORMAT_MESSAGE_FROM_HMODULE | aheinecke@163: FORMAT_MESSAGE_IGNORE_INSERTS, aheinecke@163: hWinhttp, HRESULT_CODE (err), 0, aheinecke@163: (LPWSTR) &bufPtr, 0, NULL); aheinecke@137: } aheinecke@137: } aheinecke@163: if (!bufPtr) aheinecke@185: printf ("Error getting last error for code: %lx \n", err); aheinecke@163: return bufPtr; aheinecke@137: } aheinecke@137: aheinecke@222: static PCCERT_CONTEXT aheinecke@222: b64_to_cert_context(char *b64_data, size_t b64_size) aheinecke@222: { aheinecke@222: size_t buf_size = 0; aheinecke@222: char *buf = NULL; aheinecke@222: PCCERT_CONTEXT pCert = NULL; aheinecke@222: int ret = -1; aheinecke@222: aheinecke@222: ret = str_base64_decode (&buf, &buf_size, b64_data, b64_size); aheinecke@222: aheinecke@222: if (ret != 0) aheinecke@222: { aheinecke@222: printf ("decoding certificate failed\n"); aheinecke@222: return NULL; aheinecke@222: } aheinecke@222: aheinecke@222: pCert = CertCreateContext (CERT_STORE_CERTIFICATE_CONTEXT, aheinecke@222: X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, aheinecke@222: (const PBYTE) buf, aheinecke@222: (DWORD) buf_size, aheinecke@222: 0, aheinecke@222: NULL); aheinecke@222: free (buf); /* Windows has a copy */ aheinecke@222: aheinecke@222: if (pCert == NULL) aheinecke@222: { aheinecke@222: LPWSTR error = getLastErrorMsg(); aheinecke@222: if (error) aheinecke@222: { aheinecke@222: printf ("Failed to create cert context: %S \n", error); aheinecke@222: LocalFree (error); aheinecke@222: } aheinecke@222: return NULL; aheinecke@222: } aheinecke@222: return pCert; aheinecke@222: } aheinecke@222: andre@219: void andre@215: do_remove(HCERTSTORE hStore, char **to_remove) aheinecke@137: { andre@215: PCCERT_CONTEXT pCert = NULL; andre@215: unsigned int i = 0; andre@215: andre@215: if (!to_remove) andre@215: { andre@215: return; andre@215: } andre@215: andre@215: for (i=0; to_remove[i]; i++) andre@215: { andre@215: PCCERT_CONTEXT pc_to_remove = NULL; andre@215: aheinecke@222: pc_to_remove = b64_to_cert_context(to_remove[i], aheinecke@222: strnlen(to_remove[i], MAX_LINE_LENGTH)); andre@215: andre@215: if (pc_to_remove == NULL) andre@215: { andre@215: LPWSTR error = getLastErrorMsg(); andre@215: if (error) andre@215: { aheinecke@222: printf ("Failed to create cert context: %S \n", error); andre@215: LocalFree (error); andre@215: } andre@215: continue; andre@215: } andre@215: andre@215: pCert = CertFindCertificateInStore (hStore, andre@218: X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, andre@215: 0, andre@215: CERT_FIND_EXISTING, andre@215: pc_to_remove, andre@215: NULL); andre@215: andre@215: CertFreeCertificateContext (pc_to_remove); andre@215: andre@215: if (pCert == NULL) andre@215: { andre@215: printf ("Did not find certificate\n"); andre@215: continue; andre@215: } andre@215: andre@215: if (!CertDeleteCertificateFromStore (pCert)) andre@215: { andre@215: /* From MSDN: andre@215: The CertDeleteCertificateFromStore function always frees andre@215: pCertContext by calling the CertFreeCertificateContext andre@215: function, even if an error is encountered. */ andre@215: LPWSTR error = getLastErrorMsg(); andre@215: printf ("Error deleting certificate. %S", error); andre@215: LocalFree (error); andre@215: continue; andre@215: } andre@215: } andre@215: return; andre@215: } andre@215: andre@219: void andre@215: do_install(HCERTSTORE hStore, char **to_install) andre@215: { andre@215: int i = 0, andre@215: ret = -1; andre@215: andre@215: if (!to_install) andre@215: { andre@215: return; andre@215: } andre@215: andre@217: for (i = 0; to_install[i]; i++) andre@215: { aheinecke@222: PCCERT_CONTEXT pc_to_add = NULL; aheinecke@222: PCCERT_CONTEXT found_cert = NULL; andre@215: aheinecke@222: pc_to_add = b64_to_cert_context(to_install[i], aheinecke@222: strnlen(to_install[i], MAX_LINE_LENGTH)); andre@215: aheinecke@222: if (pc_to_add == NULL) andre@215: { aheinecke@222: continue; andre@215: } andre@215: aheinecke@222: found_cert = CertFindCertificateInStore (hStore, aheinecke@222: X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, aheinecke@222: 0, aheinecke@222: CERT_FIND_EXISTING, aheinecke@222: pc_to_add, aheinecke@222: NULL); aheinecke@222: if (found_cert != NULL) aheinecke@222: { aheinecke@222: printf ("Certificate already in store\n"); aheinecke@222: CertFreeCertificateContext (found_cert); aheinecke@222: CertFreeCertificateContext (pc_to_add); aheinecke@222: continue; aheinecke@222: } andre@215: aheinecke@222: ret = CertAddCertificateContextToStore (hStore, aheinecke@222: pc_to_add, andre@215: CERT_STORE_ADD_ALWAYS, andre@215: NULL); aheinecke@222: CertFreeCertificateContext (pc_to_add); andre@215: if (!ret) andre@215: { andre@215: LPWSTR error = getLastErrorMsg(); andre@215: if (error) andre@215: { andre@215: printf ("Failed to add certificate: %S \n", error); andre@215: LocalFree (error); andre@215: } andre@215: } andre@215: } andre@215: return; andre@215: } andre@215: andre@215: int andre@215: write_stores_win (char **to_install, char **to_remove, bool user_store) andre@215: { aheinecke@163: HCERTSTORE hStore = NULL; aheinecke@137: andre@215: if (!to_install && !to_remove) andre@215: { andre@215: /* Nothing to do */ andre@215: return 0; andre@215: } andre@215: aheinecke@163: if (user_store) aheinecke@163: { aheinecke@163: hStore = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0, aheinecke@163: 0, CERT_SYSTEM_STORE_CURRENT_USER, L"Root"); aheinecke@163: } aheinecke@163: else aheinecke@163: { aheinecke@163: hStore = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0, aheinecke@163: 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"Root"); aheinecke@137: } aheinecke@137: aheinecke@163: if (!hStore) aheinecke@163: { aheinecke@163: return ERR_STORE_ACCESS_DENIED; aheinecke@137: } aheinecke@137: andre@215: /* Do the actual work */ andre@215: do_install (hStore, to_install); aheinecke@137: andre@215: do_remove (hStore, to_remove); aheinecke@161: aheinecke@163: if (hStore) aheinecke@163: { aheinecke@163: CertCloseStore (hStore, 0); aheinecke@137: } aheinecke@163: return 0; aheinecke@137: } aheinecke@137: #endif // WIN32