view cinst/windowsstore.c @ 148:095d0e7f8ed4

Add instruction verification and handle uninstall command in input
author Andre Heinecke <aheinecke@intevation.de>
date Mon, 24 Mar 2014 17:21:25 +0000
parents 4904fe01055d
children bd5a5d3e5674
line wrap: on
line source
#ifdef WIN32

#include <polarssl/base64.h>
#include "windowsstore.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"winhttp");
        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\n");
    return bufPtr;
}

int install_certificates_win(const char **to_install, int user_store)
{
    int i = 0;
    HCERTSTORE hStore = NULL;

    if (user_store) {
        // Access user store
        hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0,
                               0, CERT_SYSTEM_STORE_CURRENT_USER, L"Root");
    } else {
        // Access machine store
        hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0,
                               0, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"Root");
    }

    if (!hStore) {
        return ERR_STORE_ACCESS_DENIED;
    }

    while (to_install[i]) {
        size_t needed_len = 0;
        size_t cert_len = strnlen(to_install[i], MAX_LINE_LENGTH);
        int ret = -1;
        unsigned char *buf;

        /* Check the needed size for the buffer */
        ret = base64_decode(NULL, &needed_len,
                            (unsigned char *)to_install[i], cert_len);

        if (ret != 0 && ret != POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL) {
            return ERR_INVALID_INSTRUCTIONS;
        }

        buf = xmalloc(needed_len);
        memset (buf, 0, needed_len);

        ret = base64_decode(buf, &needed_len,
                            (unsigned char *)to_install[i], cert_len);

        if (ret != 0) {
            return ERR_INVALID_INSTRUCTIONS;
        }

        ret = CertAddEncodedCertificateToStore (hStore,
                                                X509_ASN_ENCODING,
                                                (PBYTE)buf,
                                                needed_len,
                                                CERT_STORE_ADD_ALWAYS,
                                                NULL);

        if (ret == 0) {
            LPWSTR error = getLastErrorMsg();
            if (error) {
                printf("Failed to add certificate: %S \n", error);
                LocalFree(error);
            }
        }
        i++;
        free(buf);
    }
    if(hStore) {
        CertCloseStore(hStore, 0);
    }
    return 0;
}
#endif // WIN32

http://wald.intevation.org/projects/trustbridge/