changeset 4:9849250f50f2

Start implementation of certificatelist parser
author Andre Heinecke <aheinecke@intevation.de>
date Tue, 11 Feb 2014 16:46:02 +0000
parents b684e25adbbb
children 43a07ffa5887
files CMakeLists.txt build.sh ui/certificatelist.cpp ui/certificatelist.h ui/listutil.c ui/listutil.h
diffstat 6 files changed, 230 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Mon Feb 10 16:25:39 2014 +0000
+++ b/CMakeLists.txt	Tue Feb 11 16:46:02 2014 +0000
@@ -15,6 +15,7 @@
 set(M13UI_SOURCES
     ui/main.cpp
     ui/mainwindow.cpp
+    ui/listutil.c
 )
 
 set(M13UI_RESOURCES
@@ -28,9 +29,7 @@
 set(HARDENING_FLAGS " -Werror -fstack-protector-all")
 set(HARDENING_FLAGS " ${HARDENING_FLAGS} -Wstack-protector")
 set(HARDENING_FLAGS " ${HARDENING_FLAGS} --param ssp-buffer-size=4")
-set(HARDENING_FLAGS " ${HARDENING_FLAGS} -pie -fPIE -ftrapv")
 set(HARDENING_FLAGS " ${HARDENING_FLAGS} -D_FORTIFY_SOURCE=2 -O2")
-set(HARDENING_FLAGS " ${HARDENING_FLAGS} -Wl,-z,relro,-z,now")
 
 if(UNIX)
    # See: https://bugreports.qt-project.org/browse/QTBUG-35918
@@ -48,6 +47,9 @@
 
    set(EXTRA_STATIC_LIBS -lz -lpthread -ldl -lpng -ljpeg
       Qt5::QXcbIntegrationPlugin ${XCB_EXTRA_LIBS})
+
+   set(HARDENING_FLAGS " ${HARDENING_FLAGS} -pie -fPIE -ftrapv")
+   set(HARDENING_FLAGS " ${HARDENING_FLAGS} -Wl,-z,relro,-z,now")
 elseif(WIN32)
    get_target_property(_loc Qt5::Widgets LOCATION)
    get_filename_component(_qtpath ${_loc} PATH)
@@ -59,13 +61,14 @@
         -ladvapi32 -lshell32 -luser32 -lkernel32 -lz -lsicuin -lsicuuc -lsicudt -lpcre16)
    set(EXTRA_STATIC_LIBS Qt5::QWindowsIntegrationPlugin ${WINDOWS_EXTRA_LIBS})
 
-   set(HARDENING_FLAGS " ${HARDENING_FLAGS} -Wl,dynamicbase -Wl,nxcompat")
+   set(HARDENING_FLAGS " ${HARDENING_FLAGS} -Wl,--dynamicbase -Wl,--nxcompat")
 endif()
 
 qt5_add_resources(M13UI_SOURCES ${M13UI_RESOURCES})
 
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${HARDENING_FLAGS}")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_WARN_FLAGS} ${HARDENING_FLAGS}")
 
 add_executable(m13ui ${M13UI_SOURCES})
 
--- a/build.sh	Mon Feb 10 16:25:39 2014 +0000
+++ b/build.sh	Tue Feb 11 16:46:02 2014 +0000
@@ -15,7 +15,8 @@
 mkdir -p build-windows
 cd build-windows
 cmake .. -DCMAKE_PREFIX_PATH=~/wheezy/src/mxe/usr/i686-w64-mingw32/qt5 \
-    -DCMAKE_TOOLCHAIN_FILE='~/wheezy/src/mxe/usr/i686-w64-mingw32/share/cmake/mxe-conf.cmake'
+    -DCMAKE_TOOLCHAIN_FILE='~/wheezy/src/mxe/usr/i686-w64-mingw32/share/cmake/mxe-conf.cmake' \
+    -DCMAKE_VERBOSE_MAKEFILE=True
 nice make -j8
 cd ..
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/certificatelist.cpp	Tue Feb 11 16:46:02 2014 +0000
@@ -0,0 +1,12 @@
+#include "certificatelist.h"
+
+CertificateList::CertificateList(char *fileName)
+{
+    void *data = NULL;
+    list_status_t status = Unknown;
+    int size = 0;
+
+    status = readAndVerifyList(fileName, data, &size);
+
+    qDebug() << "Read and verify list finished. Status is: " << status;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/certificatelist.h	Tue Feb 11 16:46:02 2014 +0000
@@ -0,0 +1,38 @@
+
+
+/**
+ * This class handles a certificate list file.
+ * It checks for the validity of that certificate
+ * list file and provides an API for working with that
+ * file.
+ *
+ * The List is parsed on Initialization. You should
+ * check the Status afterwards to see if the file
+ * could be parsed.
+ *
+ * The certificate list will be kept in memory until
+ * this object is destroyed.
+ *
+ */
+
+class QByteArray;
+
+#include <QString>
+#include <QDate>
+
+class CertificateList
+{
+    Q_OBJECT
+
+public:
+    CertificateList(wchar_t* fileName);
+
+    list_status_t getStatus();
+
+private:
+    QString mFileName;
+    QByteArray *mFileContent;
+    ListStatus mStatus;
+    QDate mDate;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/listutil.c	Tue Feb 11 16:46:02 2014 +0000
@@ -0,0 +1,133 @@
+#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>
+
+#define MAX_FILESIZE_KB 1024
+
+void handle_errno()
+{
+    printf("Error: %s \n", strerror(errno));
+}
+
+list_status_t readList(char *fileName, void *data, size_t *size)
+{
+    int fd = -1;
+    struct stat fileStat;
+    int rc = 0;
+    ssize_t bRead = 0;
+    list_status_t retval = UnknownError;
+
+    fd = open(fileName, O_RDONLY);
+    if (fd == -1) {
+        handle_errno();
+        retval = StatFailed;
+        goto failure;
+    }
+
+    rc = fstat(fd, &fileStat);
+    if (rc < 0) {
+        printf ("Stat failed with rc: %i\n", rc);
+        retval = StatFailed;
+        goto failure;
+    }
+
+    // Check the size of the file
+    if (fileStat.st_size) {
+        printf("Size zero\n");
+        retval = StatFailed;
+        goto failure;
+    }
+
+    if (fileStat.st_size / 1024 > MAX_FILESIZE_KB ||
+            fileStat.st_size >= (size_t)-1) {
+        printf("File too large\n");
+        retval = TooLarge;
+        goto failure;
+    }
+
+    // We can cast here as we already checked
+    // that this size is not too large for size_t
+    *size = (size_t) fileStat.st_size;
+
+    data = malloc(*size);
+
+    if (data == NULL) {
+        printf("Malloc failed\n");
+        retval = UnknownError;
+        goto failure;
+    }
+
+    bRead = read(fd, data, *size);
+
+    if (bRead != *size) {
+        printf("Read failed");
+        if (bRead == -1) {
+            handle_errno();
+        }
+        retval = UnknownError;
+        *size = 0;
+        if (data) {
+            free(data);
+            data = NULL;
+        }
+        goto failure;
+    }
+
+    retval = Unknown;
+failure:
+
+    if (fd && fd != -1) {
+        close(fd);
+        fd = -1;
+    }
+
+    return retval;
+}
+
+list_status_t readAndVerifyList(char *fileName, void *data, size_t *size)
+{
+    int validSig = 0;
+    char * firstChar = NULL;
+    int i = 0;
+
+    list_status_t retval = UnknownError;
+    data = NULL;
+    size = NULL;
+
+    retval = readList(fileName, data, size);
+
+    if (retval != Unknown) {
+        return retval;
+    }
+
+    if (!data || !size) {
+        // should not have happend if readList works as specified
+        return UnknownError;
+    }
+
+    firstChar = (char*) data;
+
+    if (*firstChar != 'S') {
+        printf("Does not start with S\n");
+        retval = InvalidFormat;
+    }
+
+    for (i=0; i < *size; i++) {
+        printf("%c", firstChar + i);
+    }
+
+failure:
+    if (retval != Valid && data) {
+        free(data);
+        data = NULL;
+        *size = 0;
+    }
+    return retval;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/listutil.h	Tue Feb 11 16:46:02 2014 +0000
@@ -0,0 +1,39 @@
+
+#include <stddef.h>
+
+/**
+ * @file listutil.h
+ * @brief Functions to work with the certificate list.
+ *
+ * This file definies the function 
+ */
+
+/* Status of the List Operations */
+typedef enum {
+    Unknown = 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(char* fileName, void *data, size_t *size);
+

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