# HG changeset patch # User Andre Heinecke # Date 1395167295 0 # Node ID 8ffbb48528aec88a6ff6fb89c456a35e34a5df13 # Parent 1bf41957418fb26e1b298775f2825ca4635dd3a7 Add certificate installation for windows diff -r 1bf41957418f -r 8ffbb48528ae cinst/CMakeLists.txt --- a/cinst/CMakeLists.txt Tue Mar 18 18:26:14 2014 +0000 +++ b/cinst/CMakeLists.txt Tue Mar 18 18:28:15 2014 +0000 @@ -14,7 +14,12 @@ ) add_executable(cinst ${CINST_SOURCES}) +if (WIN32) + set(WIN_EXTRA_LIBS -lcrypt32) +endif(WIN32) target_link_libraries(cinst ${PROFILING_LIBS} - ${POLARSSL_LIBRARIES}) + ${POLARSSL_LIBRARIES} + ${WIN_EXTRA_LIBS}) + diff -r 1bf41957418f -r 8ffbb48528ae cinst/main.c --- a/cinst/main.c Tue Mar 18 18:26:14 2014 +0000 +++ b/cinst/main.c Tue Mar 18 18:28:15 2014 +0000 @@ -24,19 +24,26 @@ * are part of the list to be removed. * **/ -#define MAX_LINE_LENGTH 1000 -#define MAX_LINES 1000 -#define MAX_INPUT_SIZE 2000000 /* MAX_LINE_LENGTH * (MAX_LINES *2) */ - #include #include #include #include +#include + #include "strhelp.h" #include "listutil.h" #include "errorcodes.h" +#ifdef WIN32 +#include +#include +#endif + +/* The certificate list + instructions may only be so long as + * twice the accepted certificatelist size */ +#define MAX_INPUT_SIZE MAX_LINE_LENGTH * MAX_LINES * 2 + /* @brief Read stdin into data structures. * * Reads from stdin and sorts the input into the respective @@ -74,14 +81,17 @@ continue; } if (*buf == 'I') { - array_append_str(to_install, buf+2, len - 2); + /* Remove leading I: and trailing \r\n */ + array_append_str(to_install, buf+2, len - 4); continue; } if (*buf == 'R') { - array_append_str(to_remove, buf+2, len - 2); + /* Remove leading R: and trailing \r\n */ + array_append_str(to_remove, buf+2, len - 4); continue; } if (strcmp("UNINSTALL", buf) == 0) { + /* Remove trailing \r\n */ array_append_str(to_remove, buf, len - 2); } } @@ -103,13 +113,88 @@ return 0; } */ + +#ifdef WIN32 +/** @brief Install certificates into Windows store + * + * @param [in] to_install NULL terminated array of base64 encoded certificates. + * @param [in] user_store set to True if the certificates shoudl be installed + * only for the current user. O for system wide installation. + * @returns 0 on success an errorcode otherwise. + */ +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 = CertAddEncodedCTLToStore (hStore, + X509_ASN_ENCODING, + (PBYTE)buf, + needed_len, + CERT_STORE_ADD_ALWAYS, + NULL); + + if (ret != 0) { + printf("Failed to add certificate\n"); + free(buf); + return ret; + } + free(buf); + } + if(hStore) { + CertCloseStore(hStore, 0); + } + return 0; +} +#endif + int main() { char **to_install = NULL; char **to_remove = NULL; char *certificate_list = NULL; size_t list_len = 0; int ret = -1; - + /* + i = 0 , + uninstall = 0; + */ ret = readInput(&certificate_list, &to_install, &to_remove); if (ret != 0) { @@ -132,18 +217,37 @@ return ERR_NO_INSTRUCTIONS; } - /* Check that the instructions are ok to execute + + /* Check that the instructions are ok to execute ret = validate_instructions(certificate_list, list_len, to_install, to_remove); - if (ret != 0) { return ERR_INVALID_INSTRUCTIONS; } - */ + + if (to_remove) { + for (i=0; to_remove[i]; i++) { + if (strncmp("UNINSTALL", to_remove[i], MAX_LINE_LENGTH)) { + uninstall = 1; + break; + } + } + } + + if (uninstall) { + + } +*/ + +#ifdef WIN32 + install_certificates_win((const char**) to_install, 1); + //remove_certificates_win((const char**) to_remove, 1); +#endif + /* Make valgrind happy */ - strfreev (to_install); - strfreev (to_remove); - free (certificate_list); + strfreev(to_install); + strfreev(to_remove); + free(certificate_list); return 0; } diff -r 1bf41957418f -r 8ffbb48528ae common/errorcodes.h --- a/common/errorcodes.h Tue Mar 18 18:26:14 2014 +0000 +++ b/common/errorcodes.h Tue Mar 18 18:28:15 2014 +0000 @@ -11,5 +11,9 @@ #define ERR_NO_INSTRUCTIONS 5 /* Instructions not valid (certs not part of certificate list) */ #define ERR_INVALID_INSTRUCTIONS 6 +/* Failed to access specified store */ +#define ERR_STORE_ACCESS_DENIED 7 +/* Failed to add certificate to store */ +#define ERR_STORE_ADD_FAILURE 7 #endif diff -r 1bf41957418f -r 8ffbb48528ae common/listutil.c --- a/common/listutil.c Tue Mar 18 18:26:14 2014 +0000 +++ b/common/listutil.c Tue Mar 18 18:28:15 2014 +0000 @@ -22,7 +22,7 @@ #include #pragma GCC diagnostic pop -#define MAX_FILESIZE 1048576 /* 1024*1024 */ +#define MAX_FILESIZE MAX_LINE_LENGTH * MAX_LINES /** * @brief Read a file into memory. @@ -89,7 +89,7 @@ return 0; } -int verify_list(char *data, size_t size) +int verify_list(const char *data, const size_t size) { int ret = -1; pk_context pub_key_ctx; @@ -221,3 +221,22 @@ return retval; } +char **get_certs_to_remove(const char *data, const size_t size) { + + /* TODO */ + if (!data || !size) { + printf ("Invalid call to get_certs_to_remove \n"); + return NULL; + } + return NULL; +} + +char **get_certs_to_install(const char *data, const size_t size) { + + /* TODO */ + if (!data || !size) { + printf ("Invalid call to get_certs_to_install \n"); + return NULL; + } + return NULL; +} diff -r 1bf41957418f -r 8ffbb48528ae common/listutil.h --- a/common/listutil.h Tue Mar 18 18:26:14 2014 +0000 +++ b/common/listutil.h Tue Mar 18 18:28:15 2014 +0000 @@ -26,6 +26,10 @@ IncompatibleVersion = 7 // The Format Version does not match } list_status_t; +/* Definitions based on the format */ +#define MAX_LINE_LENGTH 1000 +#define MAX_LINES 1000 + /** * @brief Obtain the complete and verified Certificate list. * @@ -52,7 +56,39 @@ * * @returns 0 if the list is valid a polarssl error or -1 otherwise */ -int verify_list(char *data, size_t size); +int verify_list(const char *data, const size_t size); + +/** @brief get a list of the certificates marked with I: + * + * Get a list of certificates that should be installed by the + * certificatelist pointed to by data. + * On Success this function makes a copy of the certificates + * and the certificates need to be freed by the caller. + * + * @param [in] data the certificatelist to parse + * @param [in] size the size of the certificatelist + * + * @returns a newly allocated array of strings containing the encoded + * certificates or NULL on error. + * */ +char **get_certs_to_install(const char *data, const size_t size); + +/** @brief get a list of the certificates marked with R: + * + * Get a list of certificates that should be removed by the + * certificatelist pointed to by data. + * On Success this function makes a copy of the certificates + * and the certificates need to be freed by the caller. + * + * @param [in] data the certificatelist to parse + * @param [in] size the size of the certificatelist + * + * @returns a newly allocated array of strings containing the encoded + * certificates or NULL on error. + * */ +char **get_certs_to_remove(const char *data, const size_t size); + + #ifdef __cplusplus } #endif diff -r 1bf41957418f -r 8ffbb48528ae ui/CMakeLists.txt --- a/ui/CMakeLists.txt Tue Mar 18 18:26:14 2014 +0000 +++ b/ui/CMakeLists.txt Tue Mar 18 18:28:15 2014 +0000 @@ -14,8 +14,6 @@ set(DOWNLOADER_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/downloader.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/downloader_win.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/downloader_linux.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sslconnection.cpp ) @@ -74,9 +72,9 @@ add_executable(m13ui ${M13UI_SOURCES_WITH_RESOURCES}) target_link_libraries(m13ui Qt5::Widgets + ${POLARSSL_LIBRARIES} ${EXTRA_STATIC_LIBS} - ${PROFILING_LIBS} - ${POLARSSL_LIBRARIES}) + ${PROFILING_LIBS}) # Tests add_subdirectory(tests) diff -r 1bf41957418f -r 8ffbb48528ae ui/tests/CMakeLists.txt --- a/ui/tests/CMakeLists.txt Tue Mar 18 18:26:14 2014 +0000 +++ b/ui/tests/CMakeLists.txt Tue Mar 18 18:28:15 2014 +0000 @@ -17,8 +17,8 @@ add_executable(${_name} ${_test} ${_additional_sources}) add_test(m13-${_name} ${_name}) target_link_libraries(${_name} Qt5::Test Qt5::Widgets - ${EXTRA_STATIC_LIBS} - ${POLARSSL_LIBRARIES}) + ${POLARSSL_LIBRARIES} + ${EXTRA_STATIC_LIBS}) endmacro() # Add the current source dir to the definition