Mercurial > trustbridge
view cinst/windowsstore.c @ 248:9f0865dc8b14
Add accessor to check if the certificate should be installed
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Mon, 31 Mar 2014 08:03:20 +0000 |
parents | 4de97f74d038 |
children | 3595ea4fd3fb |
line wrap: on
line source
#ifdef WIN32 #include <stdio.h> #include "windowsstore.h" #include "errorcodes.h" #include "listutil.h" #include "strhelp.h" static LPWSTR getLastErrorMsg() { LPWSTR bufPtr = NULL; DWORD err = GetLastError(); FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, (LPWSTR) &bufPtr, 0, NULL); if (!bufPtr) { HMODULE hWinhttp = GetModuleHandleW (L"crypt32"); if (hWinhttp) { FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, hWinhttp, HRESULT_CODE (err), 0, (LPWSTR) &bufPtr, 0, NULL); } } if (!bufPtr) printf ("Error getting last error for code: %lx \n", err); return bufPtr; } static PCCERT_CONTEXT b64_to_cert_context(char *b64_data, size_t b64_size) { size_t buf_size = 0; char *buf = NULL; PCCERT_CONTEXT pCert = NULL; int ret = -1; ret = str_base64_decode (&buf, &buf_size, b64_data, b64_size); if (ret != 0) { printf ("decoding certificate failed\n"); return NULL; } pCert = CertCreateContext (CERT_STORE_CERTIFICATE_CONTEXT, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (const PBYTE) buf, (DWORD) buf_size, 0, NULL); free (buf); /* Windows has a copy */ if (pCert == NULL) { LPWSTR error = getLastErrorMsg(); if (error) { printf ("Failed to create cert context: %S \n", error); LocalFree (error); } return NULL; } return pCert; } void do_remove(HCERTSTORE hStore, char **to_remove) { PCCERT_CONTEXT pCert = NULL; unsigned int i = 0; if (!to_remove) { return; } for (i=0; to_remove[i]; i++) { PCCERT_CONTEXT pc_to_remove = NULL; pc_to_remove = b64_to_cert_context(to_remove[i], strnlen(to_remove[i], MAX_LINE_LENGTH)); if (pc_to_remove == NULL) { LPWSTR error = getLastErrorMsg(); if (error) { printf ("Failed to create cert context: %S \n", error); LocalFree (error); } continue; } pCert = CertFindCertificateInStore (hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_EXISTING, pc_to_remove, NULL); CertFreeCertificateContext (pc_to_remove); if (pCert == NULL) { printf ("Did not find certificate\n"); continue; } if (!CertDeleteCertificateFromStore (pCert)) { /* From MSDN: The CertDeleteCertificateFromStore function always frees pCertContext by calling the CertFreeCertificateContext function, even if an error is encountered. */ LPWSTR error = getLastErrorMsg(); printf ("Error deleting certificate. %S", error); LocalFree (error); continue; } } return; } void do_install(HCERTSTORE hStore, char **to_install) { int i = 0, ret = -1; if (!to_install) { return; } for (i = 0; to_install[i]; i++) { PCCERT_CONTEXT pc_to_add = NULL; PCCERT_CONTEXT found_cert = NULL; pc_to_add = b64_to_cert_context(to_install[i], strnlen(to_install[i], MAX_LINE_LENGTH)); if (pc_to_add == NULL) { continue; } found_cert = CertFindCertificateInStore (hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_EXISTING, pc_to_add, NULL); if (found_cert != NULL) { printf ("Certificate already in store\n"); CertFreeCertificateContext (found_cert); CertFreeCertificateContext (pc_to_add); continue; } ret = CertAddCertificateContextToStore (hStore, pc_to_add, CERT_STORE_ADD_ALWAYS, NULL); CertFreeCertificateContext (pc_to_add); if (!ret) { LPWSTR error = getLastErrorMsg(); if (error) { printf ("Failed to add certificate: %S \n", error); LocalFree (error); } } } return; } static bool is_elevated() { HANDLE hToken = NULL; bool ret = false; if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken)) { TOKEN_ELEVATION elevation; DWORD cbSize = sizeof (TOKEN_ELEVATION); if (GetTokenInformation (hToken, TokenElevation, &elevation, sizeof (TokenElevation), &cbSize)) { ret = elevation.TokenIsElevated; } } if (hToken) CloseHandle (hToken); return ret; } int write_stores_win (char **to_install, char **to_remove) { HCERTSTORE hStore = NULL; if (!to_install && !to_remove) { /* Nothing to do */ return 0; } if (!is_elevated()) { hStore = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, L"Root"); } else { hStore = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"Root"); } if (!hStore) { return ERR_STORE_ACCESS_DENIED; } /* Do the actual work */ do_install (hStore, to_install); do_remove (hStore, to_remove); if (hStore) { CertCloseStore (hStore, 0); } return 0; } #endif // WIN32