changeset 18:f4f957c58e0a

Move listuitol and add cert pinning with a test certificate
author Andre Heinecke <aheinecke@intevation.de>
date Wed, 19 Feb 2014 15:41:14 +0000
parents c12825a651ed
children 9af6198deb8e
files CMakeLists.txt cinst/listutil.c cinst/listutil.h tests/CMakeLists.txt ui/certificatelist.h ui/certificates/kolab.org.der ui/certs.qrc ui/downloader.cpp ui/downloader_win.cpp ui/listutil.c ui/listutil.h
diffstat 11 files changed, 205 insertions(+), 196 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Wed Feb 19 14:22:26 2014 +0000
+++ b/CMakeLists.txt	Wed Feb 19 15:41:14 2014 +0000
@@ -23,14 +23,16 @@
     ${CMAKE_SOURCE_DIR}/ui/downloader.cpp
     ${CMAKE_SOURCE_DIR}/ui/downloader_win.cpp
     ${CMAKE_SOURCE_DIR}/ui/downloader_linux.cpp
-    ${CMAKE_SOURCE_DIR}/ui/listutil.c
+    ${CMAKE_SOURCE_DIR}/cinst/listutil.c
+    ${CMAKE_SOURCE_DIR}/ui/main.cpp
 )
 
 # Seperated to make it easier to include the sources in tests
-set(M13UI_MAIN ui/main.cpp)
+set(M13UI_MAIN )
 
 set(M13UI_RESOURCES
-    ui/icons.qrc
+   ${CMAKE_SOURCE_DIR}/ui/icons.qrc
+   ${CMAKE_SOURCE_DIR}/ui/certs.qrc
 )
 
 # Warn level to be used for privileged parts
@@ -98,6 +100,7 @@
 if (FLAWFINDER_PATH)
     add_custom_target(flawfinder COMMENT "FlawFinder" VERBATIM COMMAND ${FLAWFINDER_PATH}
        ${CMAKE_SOURCE_DIR}/ui
+       ${CMAKE_SOURCE_DIR}/cinst
     )
     add_dependencies(static_check flawfinder)
 endif (FLAWFINDER_PATH)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cinst/listutil.c	Wed Feb 19 15:41:14 2014 +0000
@@ -0,0 +1,138 @@
+#include "listutil.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#define MAX_FILESIZE_KB 1024
+
+void handle_errno()
+{
+    printf("Error: %s \n", strerror(errno));
+}
+
+list_status_t readList(const char *fileName, char **data, size_t *size)
+{
+    int fd = -1;
+    struct stat fileStat;
+    int rc = 0;
+    ssize_t bRead = 0;
+
+    memset(&fileStat, 0, sizeof(fileStat));
+
+    list_status_t retval = UnknownError;
+
+    fd = open(fileName, O_RDONLY);
+    if (fd == -1) {
+        handle_errno();
+        retval = StatFailed;
+        goto cleanup;
+    }
+
+    rc = fstat(fd, &fileStat);
+    if (rc < 0) {
+        printf ("Stat failed with rc: %i\n", rc);
+        retval = StatFailed;
+        goto cleanup;
+    }
+
+    // Check the size of the file
+    if (!fileStat.st_size) {
+        printf("Size zero\n");
+        retval = StatFailed;
+        goto cleanup;
+    }
+
+    if (fileStat.st_size / 1024 > MAX_FILESIZE_KB &&
+            fileStat.st_size > 0) {
+        printf("File too large\n");
+        retval = TooLarge;
+        goto cleanup;
+    }
+
+    *size = (size_t) fileStat.st_size;
+
+    *data = (char*) malloc(*size);
+
+    if (*data == NULL) {
+        printf("Malloc failed\n");
+        retval = UnknownError;
+        goto cleanup;
+    }
+
+    bRead = read(fd, *data, *size);
+
+    if (bRead < 0 || (size_t) bRead != *size) {
+        printf("Read failed\n");
+        if (bRead == -1) {
+            handle_errno();
+        }
+        retval = UnknownError;
+        *size = 0;
+        if (*data) {
+            free(*data);
+            printf("Nulling data\n");
+            *data = NULL;
+        }
+        goto cleanup;
+    }
+
+    retval = UnknownValidity;
+cleanup:
+
+    if (fd && fd != -1) {
+        close(fd);
+        fd = -1;
+    }
+
+    return retval;
+}
+
+list_status_t readAndVerifyList(const char *fileName, char **data, size_t *size)
+{
+//    int validSig = 0;
+    char * signature = NULL;
+
+    list_status_t retval = UnknownError;
+    *data = NULL;
+    *size = 0;
+
+    retval = readList(fileName, data, size);
+
+    if (retval != UnknownValidity) {
+        printf ("Readlist failed\n");
+        return retval;
+    }
+
+    if (!data || !*size) {
+        // should not have happend if readList works as specified
+        return UnknownError;
+    }
+
+    signature = *data;
+
+    if (*signature != 'S') {
+        printf("Does not start with S\n");
+        retval = InvalidFormat;
+        goto cleanup;
+    }
+
+// TODO VERIFIY
+retval = Valid;
+
+// Maybe check if all bytes are < 127 and > 0
+
+cleanup:
+    if (retval != Valid && *data) {
+        free(*data);
+        *data = NULL;
+        *size = 0;
+    }
+    return retval;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cinst/listutil.h	Wed Feb 19 15:41:14 2014 +0000
@@ -0,0 +1,48 @@
+#ifndef LISTUTIL_H
+#define LISTUTIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+
+/**
+ * @file listutil.h
+ * @brief Functions to work with the certificate list.
+ */
+
+/**
+ * @brief Status of the List Operations
+ */
+typedef enum {
+    UnknownValidity = 0, // Not yet parsed
+    UnknownError = 1, // The expected unexpected
+    TooLarge = 2, // Failed because the file exeeds the limit
+    InvalidFormat = 3, // File does not appear to be in list format
+    InvalidSignature = 4, // Signature was invalid
+    StatFailed = 5, // Could not stat the file
+    ReadFailed = 6, // Could not read the file
+    IncompatibleVersion = 7, // The Format Version does not match
+    Valid = 8 // List is valid
+} list_status_t;
+
+/**
+ * @brief Obtain the complete and verified Certificate list.
+ *
+ * This checks if the file fileName is a valid certificate
+ * list signed by the key specified in pubkey.h
+ *
+ * The caller has to free data.
+ *
+ * @param[in] fileName Name of the file (UTF-8 encoded).
+ * @param[out] data Newly allocated pointer to the file content.
+ * @param[out] size Size in Bytes of the file content.
+ *
+ * @return status of the operation.
+ */
+list_status_t readAndVerifyList(const char *fileName, char **data, size_t *size);
+#ifdef __cplusplus
+}
+#endif
+#endif
--- a/tests/CMakeLists.txt	Wed Feb 19 14:22:26 2014 +0000
+++ b/tests/CMakeLists.txt	Wed Feb 19 15:41:14 2014 +0000
@@ -4,10 +4,10 @@
 
 find_package(Qt5Test)
 
-macro(add_m13_test _source)
+macro(add_m13_test _source _additional_sources)
   set(_test ${_source})
   get_filename_component(_name ${_source} NAME_WE)
-  add_executable(${_name} ${_test} ${M13UI_SOURCES})
+  add_executable(${_name} ${_test} ${_additional_sources})
   add_test(m13-${_name} ${_name})
   target_link_libraries(${_name} Qt5::Test Qt5::Widgets ${EXTRA_STATIC_LIBS})
 endmacro()
@@ -15,5 +15,5 @@
 # Add the current source dir to the definition
 # so that it can be used in file names in the tests.
 add_definitions(-DSOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
-add_m13_test(certlistparsertest.cpp)
+add_m13_test(certlistparsertest.cpp "${CMAKE_SOURCE_DIR}/cinst/listutil.c;${CMAKE_SOURCE_DIR}/ui/certificatelist.cpp")
 
--- a/ui/certificatelist.h	Wed Feb 19 14:22:26 2014 +0000
+++ b/ui/certificatelist.h	Wed Feb 19 15:41:14 2014 +0000
@@ -18,7 +18,7 @@
 #include <QDateTime>
 #include <QObject>
 
-#include "listutil.h"
+#include "../cinst/listutil.h"
 
 class CertificateList : public QObject
 {
Binary file ui/certificates/kolab.org.der has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/certs.qrc	Wed Feb 19 15:41:14 2014 +0000
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/certs">
+    <file alias="kolab.org">certificates/kolab.org.der</file>
+</qresource>
+</RCC>
--- a/ui/downloader.cpp	Wed Feb 19 14:22:26 2014 +0000
+++ b/ui/downloader.cpp	Wed Feb 19 15:41:14 2014 +0000
@@ -22,7 +22,7 @@
     mLastModList(newestList)
 {
     if (certificate.isEmpty()) {
-        QFile certResource(":certificates/https");
+        QFile certResource(":certs/kolab.org");
         certResource.open(QFile::ReadOnly);
         mCert = certResource.readAll();
         certResource.close();
--- a/ui/downloader_win.cpp	Wed Feb 19 14:22:26 2014 +0000
+++ b/ui/downloader_win.cpp	Wed Feb 19 15:41:14 2014 +0000
@@ -214,6 +214,7 @@
     if (!retval) {
         DEBUG << "Certificate is not the same as the pinned one!"
               << "Base64 cert: " << serverCert.toBase64();
+        emit error("Invalid certificate", InvalidCertificate);
     }
 
     CertFreeCertificateContext(certContext);
@@ -258,7 +259,7 @@
 
     if (!verifyCertificate(hRequest)) {
         DEBUG << "Certificate verification failed";
-        // TODO error out
+        goto cleanup;
     }
 
     if (!(WinHttpQueryHeaders(hRequest,
@@ -327,7 +328,7 @@
 
     if (!verifyCertificate(hRequest)) {
         DEBUG << "Certificate verification failed";
-        // TODO error out
+        goto cleanup;
     }
 
 
--- a/ui/listutil.c	Wed Feb 19 14:22:26 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-#include "listutil.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-
-#define MAX_FILESIZE_KB 1024
-
-void handle_errno()
-{
-    printf("Error: %s \n", strerror(errno));
-}
-
-list_status_t readList(const char *fileName, char **data, size_t *size)
-{
-    int fd = -1;
-    struct stat fileStat;
-    int rc = 0;
-    ssize_t bRead = 0;
-
-    memset(&fileStat, 0, sizeof(fileStat));
-
-    list_status_t retval = UnknownError;
-
-    fd = open(fileName, O_RDONLY);
-    if (fd == -1) {
-        handle_errno();
-        retval = StatFailed;
-        goto cleanup;
-    }
-
-    rc = fstat(fd, &fileStat);
-    if (rc < 0) {
-        printf ("Stat failed with rc: %i\n", rc);
-        retval = StatFailed;
-        goto cleanup;
-    }
-
-    // Check the size of the file
-    if (!fileStat.st_size) {
-        printf("Size zero\n");
-        retval = StatFailed;
-        goto cleanup;
-    }
-
-    if (fileStat.st_size / 1024 > MAX_FILESIZE_KB &&
-            fileStat.st_size > 0) {
-        printf("File too large\n");
-        retval = TooLarge;
-        goto cleanup;
-    }
-
-    *size = (size_t) fileStat.st_size;
-
-    *data = (char*) malloc(*size);
-
-    if (*data == NULL) {
-        printf("Malloc failed\n");
-        retval = UnknownError;
-        goto cleanup;
-    }
-
-    bRead = read(fd, *data, *size);
-
-    if (bRead < 0 || (size_t) bRead != *size) {
-        printf("Read failed\n");
-        if (bRead == -1) {
-            handle_errno();
-        }
-        retval = UnknownError;
-        *size = 0;
-        if (*data) {
-            free(*data);
-            printf("Nulling data\n");
-            *data = NULL;
-        }
-        goto cleanup;
-    }
-
-    retval = UnknownValidity;
-cleanup:
-
-    if (fd && fd != -1) {
-        close(fd);
-        fd = -1;
-    }
-
-    return retval;
-}
-
-list_status_t readAndVerifyList(const char *fileName, char **data, size_t *size)
-{
-//    int validSig = 0;
-    char * signature = NULL;
-
-    list_status_t retval = UnknownError;
-    *data = NULL;
-    *size = 0;
-
-    retval = readList(fileName, data, size);
-
-    if (retval != UnknownValidity) {
-        printf ("Readlist failed\n");
-        return retval;
-    }
-
-    if (!data || !*size) {
-        // should not have happend if readList works as specified
-        return UnknownError;
-    }
-
-    signature = *data;
-
-    if (*signature != 'S') {
-        printf("Does not start with S\n");
-        retval = InvalidFormat;
-        goto cleanup;
-    }
-
-// TODO VERIFIY
-retval = Valid;
-
-// Maybe check if all bytes are < 127 and > 0
-
-cleanup:
-    if (retval != Valid && *data) {
-        free(*data);
-        *data = NULL;
-        *size = 0;
-    }
-    return retval;
-}
-
--- a/ui/listutil.h	Wed Feb 19 14:22:26 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-#ifndef LISTUTIL_H
-#define LISTUTIL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stddef.h>
-
-/**
- * @file listutil.h
- * @brief Functions to work with the certificate list.
- */
-
-/**
- * @brief Status of the List Operations
- */
-typedef enum {
-    UnknownValidity = 0, // Not yet parsed
-    UnknownError = 1, // The expected unexpected
-    TooLarge = 2, // Failed because the file exeeds the limit
-    InvalidFormat = 3, // File does not appear to be in list format
-    InvalidSignature = 4, // Signature was invalid
-    StatFailed = 5, // Could not stat the file
-    ReadFailed = 6, // Could not read the file
-    IncompatibleVersion = 7, // The Format Version does not match
-    Valid = 8 // List is valid
-} list_status_t;
-
-/**
- * @brief Obtain the complete and verified Certificate list.
- *
- * This checks if the file fileName is a valid certificate
- * list signed by the key specified in pubkey.h
- *
- * The caller has to free data.
- *
- * @param[in] fileName Name of the file (UTF-8 encoded).
- * @param[out] data Newly allocated pointer to the file content.
- * @param[out] size Size in Bytes of the file content.
- *
- * @return status of the operation.
- */
-list_status_t readAndVerifyList(const char *fileName, char **data, size_t *size);
-#ifdef __cplusplus
-}
-#endif
-#endif

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