Mercurial > trustbridge
view cinst/windowsstore.c @ 217:83a015f2e078
Remove leftover incrementation of i from former loop style. Fixes a crash when adding only one
certificate.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Wed, 26 Mar 2014 20:14:22 +0100 |
parents | 292e2cb60ef0 |
children | 8fb12af98960 |
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 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++) { char *asn1_data = NULL; size_t asn1_size = 0; int ret = -1; PCCERT_CONTEXT pc_to_remove = NULL; ret = str_base64_decode (&asn1_data, &asn1_size, to_remove[i], strnlen(to_remove[i], MAX_LINE_LENGTH)); /* Decoding / parsing errors in here should not happen at all. The only errors which are not a bug would be out of memory or if the signed certificate list contained an invalid certificate. */ if (ret != 0) { printf ("Error base64 certificate.\n"); continue; } pc_to_remove = CertCreateContext (CERT_STORE_CERTIFICATE_CONTEXT, X509_ASN_ENCODING, (const PBYTE) asn1_data, (DWORD) asn1_size, 0, NULL); free (asn1_data); /* Windows has a copy */ if (pc_to_remove == NULL) { LPWSTR error = getLastErrorMsg(); if (error) { printf ("Failed to add certificate: %S \n", error); LocalFree (error); } continue; } pCert = CertFindCertificateInStore (hStore, X509_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; } static void do_install(HCERTSTORE hStore, char **to_install) { int i = 0, ret = -1; if (!to_install) { return; } for (i = 0; to_install[i]; i++) { size_t cert_len = strnlen (to_install[i], MAX_LINE_LENGTH), buf_size = 0; char *buf = NULL; ret = str_base64_decode (&buf, &buf_size, to_install[i], cert_len); if (ret != 0) { printf ("decoding certificate failed\n"); return; } printf ("Adding cert %s\n", to_install[i]); ret = CertAddEncodedCertificateToStore (hStore, X509_ASN_ENCODING, (PBYTE) buf, buf_size, CERT_STORE_ADD_ALWAYS, NULL); if (!ret) { LPWSTR error = getLastErrorMsg(); if (error) { printf ("Failed to add certificate: %S \n", error); LocalFree (error); } } free (buf); } return; } int write_stores_win (char **to_install, char **to_remove, bool user_store) { HCERTSTORE hStore = NULL; if (!to_install && !to_remove) { /* Nothing to do */ return 0; } if (user_store) { 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