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@163: static LPWSTR 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: andre@215: static 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: char *asn1_data = NULL; andre@215: size_t asn1_size = 0; andre@215: int ret = -1; andre@215: PCCERT_CONTEXT pc_to_remove = NULL; andre@215: andre@215: ret = str_base64_decode (&asn1_data, &asn1_size, to_remove[i], andre@215: strnlen(to_remove[i], MAX_LINE_LENGTH)); andre@215: /* Decoding / parsing errors in here should not happen at all. andre@215: The only errors which are not a bug would be out of memory or andre@215: if the signed certificate list contained an invalid certificate. */ andre@215: if (ret != 0) andre@215: { andre@215: printf ("Error base64 certificate.\n"); andre@215: continue; andre@215: } andre@215: andre@215: pc_to_remove = CertCreateContext (CERT_STORE_CERTIFICATE_CONTEXT, andre@218: X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, andre@215: (const PBYTE) asn1_data, andre@215: (DWORD) asn1_size, andre@215: 0, andre@215: NULL); andre@215: free (asn1_data); /* Windows has a copy */ andre@215: if (pc_to_remove == NULL) 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: 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@215: static 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: { andre@215: size_t cert_len = strnlen (to_install[i], MAX_LINE_LENGTH), andre@215: buf_size = 0; andre@215: char *buf = NULL; andre@215: andre@215: ret = str_base64_decode (&buf, &buf_size, to_install[i], cert_len); andre@215: andre@215: if (ret != 0) andre@215: { andre@215: printf ("decoding certificate failed\n"); andre@215: return; andre@215: } andre@215: andre@215: printf ("Adding cert %s\n", to_install[i]); andre@215: andre@215: ret = CertAddEncodedCertificateToStore (hStore, andre@218: X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, andre@215: (PBYTE) buf, andre@215: buf_size, andre@215: CERT_STORE_ADD_ALWAYS, andre@215: NULL); andre@215: 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: free (buf); 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