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@253: #include "logging.h" 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@253: char *error = getLastErrorMsg(); aheinecke@222: if (error) aheinecke@222: { aheinecke@253: printf ("Failed to create cert context: %s \n", error); aheinecke@253: free (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: { aheinecke@253: char *error = getLastErrorMsg(); andre@215: if (error) andre@215: { aheinecke@253: printf ("Failed to create cert context: %s \n", error); aheinecke@253: free (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. */ aheinecke@253: char *error = getLastErrorMsg(); aheinecke@253: printf ("Error deleting certificate. %s", error); aheinecke@253: free (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: { aheinecke@253: char *error = getLastErrorMsg(); andre@215: if (error) andre@215: { aheinecke@253: printf ("Failed to add certificate: %s \n", error); aheinecke@253: free (error); andre@215: } andre@215: } andre@215: } andre@215: return; andre@215: } andre@215: aheinecke@247: static bool is_elevated() { aheinecke@247: HANDLE hToken = NULL; aheinecke@247: bool ret = false; aheinecke@247: if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken)) aheinecke@247: { aheinecke@247: TOKEN_ELEVATION elevation; aheinecke@247: DWORD cbSize = sizeof (TOKEN_ELEVATION); aheinecke@247: if (GetTokenInformation (hToken, TokenElevation, &elevation, aheinecke@247: sizeof (TokenElevation), &cbSize)) aheinecke@247: { aheinecke@247: ret = elevation.TokenIsElevated; aheinecke@247: } aheinecke@247: } aheinecke@247: if (hToken) aheinecke@247: CloseHandle (hToken); aheinecke@247: aheinecke@247: return ret; aheinecke@247: } aheinecke@247: andre@215: int aheinecke@247: write_stores_win (char **to_install, char **to_remove) 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@247: if (!is_elevated()) 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