Index: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/src/crl.c
===================================================================
--- azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/crl.c	(revision 457)
+++ azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/src/crl.c	(revision 464)
@@ -35,5 +35,7 @@
 #include <wolfssl/error-ssl.h>
 
-#include <string.h>
+#ifndef WOLFSSL_LINUXKM
+    #include <string.h>
+#endif
 
 #ifdef HAVE_CRL_MONITOR
@@ -491,25 +493,254 @@
 
 #if defined(OPENSSL_EXTRA) && defined(HAVE_CRL)
+/* helper function to create a new dynamic WOLFSSL_X509_CRL structure */
+static WOLFSSL_X509_CRL* wolfSSL_X509_crl_new(WOLFSSL_CERT_MANAGER* cm)
+{
+    WOLFSSL_X509_CRL* ret;
+
+    ret = (WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), cm->heap,
+                DYNAMIC_TYPE_CRL);
+    if (ret != NULL) {
+        if (InitCRL(ret, cm) < 0) {
+            WOLFSSL_MSG("Unable to initialize new CRL structure");
+            XFREE(ret, cm->heap, DYNAMIC_TYPE_CRL);
+            ret = NULL;
+        }
+    }
+    return ret;
+}
+
+
+/* returns head of copied list that was alloc'd */
+static RevokedCert *DupRevokedCertList(RevokedCert* in, void* heap)
+{
+    RevokedCert* head = NULL;
+    RevokedCert* current = in;
+    RevokedCert* prev = NULL;
+    while (current) {
+        RevokedCert* tmp = (RevokedCert*)XMALLOC(sizeof(RevokedCert), heap,
+                DYNAMIC_TYPE_REVOKED);
+        if (tmp != NULL) {
+            XMEMCPY(tmp->serialNumber, current->serialNumber,
+                    EXTERNAL_SERIAL_SIZE);
+            tmp->serialSz = current->serialSz;
+            tmp->next = NULL;
+            if (prev != NULL)
+                prev->next = tmp;
+            if (head == NULL)
+                head = tmp;
+            prev = tmp;
+        }
+        else {
+            WOLFSSL_MSG("Failed to allocate new RevokedCert structure");
+            /* free up any existing list */
+            while (head != NULL) {
+                current = head;
+                head = head->next;
+                XFREE(current, heap, DYNAMIC_TYPE_REVOKED);
+            }
+            return NULL;
+        }
+        current = current->next;
+    }
+
+    (void)heap;
+    return head;
+}
+
+
+/* returns a deep copy of ent on success and null on fail */
+static CRL_Entry* DupCRL_Entry(const CRL_Entry* ent, void* heap)
+{
+    CRL_Entry *dupl;
+
+    dupl = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), heap, DYNAMIC_TYPE_CRL_ENTRY);
+    if (dupl == NULL) {
+        WOLFSSL_MSG("alloc CRL Entry failed");
+        return NULL;
+    }
+    XMEMSET(dupl, 0, sizeof(CRL_Entry));
+
+    XMEMCPY(dupl->issuerHash, ent->issuerHash, CRL_DIGEST_SIZE);
+    XMEMCPY(dupl->lastDate, ent->lastDate, MAX_DATE_SIZE);
+    XMEMCPY(dupl->nextDate, ent->nextDate, MAX_DATE_SIZE);
+    dupl->lastDateFormat = ent->lastDateFormat;
+    dupl->nextDateFormat = ent->nextDateFormat;
+    dupl->certs = DupRevokedCertList(ent->certs, heap);
+
+    dupl->totalCerts = ent->totalCerts;
+    dupl->verified = ent->verified;
+
+    if (!ent->verified) {
+        dupl->tbsSz = ent->tbsSz;
+        dupl->signatureSz = ent->signatureSz;
+        dupl->signatureOID = ent->signatureOID;
+        dupl->toBeSigned = (byte*)XMALLOC(dupl->tbsSz, heap,
+                                          DYNAMIC_TYPE_CRL_ENTRY);
+        if (dupl->toBeSigned == NULL) {
+            FreeCRL_Entry(dupl, heap);
+            XFREE(dupl, heap, DYNAMIC_TYPE_CRL_ENTRY);
+            return NULL;
+        }
+
+        dupl->signature = (byte*)XMALLOC(dupl->signatureSz, heap,
+                                         DYNAMIC_TYPE_CRL_ENTRY);
+        if (dupl->signature == NULL) {
+            FreeCRL_Entry(dupl, heap);
+            XFREE(dupl, heap, DYNAMIC_TYPE_CRL_ENTRY);
+            return NULL;
+        }
+        XMEMCPY(dupl->toBeSigned, ent->toBeSigned, dupl->tbsSz);
+        XMEMCPY(dupl->signature, ent->signature, dupl->signatureSz);
+    #ifndef NO_SKID
+        dupl->extAuthKeyIdSet = ent->extAuthKeyIdSet;
+        if (dupl->extAuthKeyIdSet)
+            XMEMCPY(dupl->extAuthKeyId, ent->extAuthKeyId, KEYID_SIZE);
+    #endif
+    }
+    else {
+        dupl->toBeSigned = NULL;
+        dupl->tbsSz = 0;
+        dupl->signature = NULL;
+        dupl->signatureSz = 0;
+    }
+
+    return dupl;
+}
+
+
+/* returns the head of a deep copy of the list on success and null on fail */
+static CRL_Entry* DupCRL_list(CRL_Entry* crl, void* heap)
+{
+    CRL_Entry* current;
+    CRL_Entry* head = NULL;
+    CRL_Entry* prev = NULL;
+
+    current = crl;
+    while (current != NULL) {
+        CRL_Entry* tmp = DupCRL_Entry(current, heap);
+        if (tmp != NULL) {
+            tmp->next = NULL;
+            if (head == NULL)
+                head = tmp;
+            if (prev != NULL)
+                prev->next = tmp;
+            prev = tmp;
+        }
+        else {
+            WOLFSSL_MSG("Failed to allocate new CRL_Entry structure");
+            /* free up any existing list */
+            while (head != NULL) {
+                current = head;
+                head = head->next;
+                FreeCRL_Entry(current, heap);
+            }
+
+            return NULL;
+        }
+        current = current->next;
+    }
+    return head;
+}
+
+
+/* Duplicates everything except the parent cm pointed to.
+ * Expects that Init has already been done to 'dupl'
+ * return 0 on success */
+static int DupX509_CRL(WOLFSSL_X509_CRL *dupl, const WOLFSSL_X509_CRL* crl)
+{
+    if (dupl == NULL || crl == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    if (crl->monitors[0].path) {
+        int pathSz = (int)XSTRLEN(crl->monitors[0].path) + 1;
+        dupl->monitors[0].path = (char*)XMALLOC(pathSz, dupl->heap,
+                DYNAMIC_TYPE_CRL_MONITOR);
+        if (dupl->monitors[0].path != NULL) {
+            XSTRNCPY(dupl->monitors[0].path, crl->monitors[0].path, pathSz);
+        }
+        else {
+            return MEMORY_E;
+        }
+    }
+
+    if (crl->monitors[1].path) {
+        int pathSz = (int)XSTRLEN(crl->monitors[1].path) + 1;
+        dupl->monitors[1].path = (char*)XMALLOC(pathSz, dupl->heap,
+                DYNAMIC_TYPE_CRL_MONITOR);
+        if (dupl->monitors[1].path != NULL) {
+            XSTRNCPY(dupl->monitors[1].path, crl->monitors[1].path, pathSz);
+        }
+        else {
+            if (dupl->monitors[0].path != NULL) {
+                XFREE(dupl->monitors[0].path, dupl->heap,
+                        DYNAMIC_TYPE_CRL_MONITOR);
+            }
+            return MEMORY_E;
+        }
+    }
+
+    dupl->crlList = DupCRL_list(crl->crlList, dupl->heap);
+#ifdef HAVE_CRL_IO
+    dupl->crlIOCb = crl->crlIOCb;
+#endif
+
+    return 0;
+}
+
+/* returns WOLFSSL_SUCCESS on success. Does not take ownership of newcrl */
 int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *store, WOLFSSL_X509_CRL *newcrl)
 {
     CRL_Entry   *crle;
-    WOLFSSL_CRL *crl;
+    WOLFSSL_X509_CRL *crl;
 
     WOLFSSL_ENTER("wolfSSL_X509_STORE_add_crl");
-    if (store == NULL || newcrl == NULL)
+    if (store == NULL || newcrl == NULL || store->cm == NULL)
         return BAD_FUNC_ARG;
 
-    crl = store->crl;
-    crle = newcrl->crlList;
-
-    if (wc_LockMutex(&crl->crlLock) != 0)
-    {
-        WOLFSSL_MSG("wc_LockMutex failed");
-        return BAD_MUTEX_E;
-    }
-    crle->next = crl->crlList;
-    crl->crlList = crle;
-    newcrl->crlList = NULL;
-    wc_UnLockMutex(&crl->crlLock);
+    if (store->cm->crl == NULL) {
+        crl = wolfSSL_X509_crl_new(store->cm);
+        if (DupX509_CRL(crl, newcrl) != 0) {
+            FreeCRL(crl, 1);
+            return WOLFSSL_FAILURE;
+        }
+        store->crl = store->cm->crl = crl;
+        if (wolfSSL_CertManagerEnableCRL(store->cm, WOLFSSL_CRL_CHECKALL)
+                != WOLFSSL_SUCCESS) {
+            WOLFSSL_MSG("wolfSSL_CertManagerEnableCRL error");
+            return WOLFSSL_FAILURE;
+        }
+        return WOLFSSL_SUCCESS;
+    }
+
+    /* find tail of current list and add new list */
+    crl  = store->cm->crl;
+    crle = crl->crlList;
+    if (newcrl->crlList != NULL) {
+        CRL_Entry *tail = crle;
+        CRL_Entry *toAdd;
+
+        if (wc_LockMutex(&crl->crlLock) != 0)
+        {
+            WOLFSSL_MSG("wc_LockMutex failed");
+            return BAD_MUTEX_E;
+        }
+
+        toAdd = DupCRL_list(newcrl->crlList, crl->heap);
+        if (tail == NULL) {
+            crl->crlList = toAdd;
+        }
+        else {
+            while (tail->next != NULL) tail = tail->next;
+            tail->next = toAdd;
+        }
+        wc_UnLockMutex(&crl->crlLock);
+    }
+
+    if (wolfSSL_CertManagerEnableCRL(store->cm, WOLFSSL_CRL_CHECKALL)
+            != WOLFSSL_SUCCESS) {
+        WOLFSSL_MSG("wolfSSL_CertManagerEnableCRL error");
+        return WOLFSSL_FAILURE;
+    }
 
     WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_crl", WOLFSSL_SUCCESS);
@@ -882,5 +1113,15 @@
 
         if (FD_ISSET(crl->mfd, &readfds)) {
+            word64 r64;
+            int    rlen;
+
             WOLFSSL_MSG("got custom shutdown event, breaking out");
+
+            /* read out the bytes written to the event to clean up */
+            rlen = (int) read(crl->mfd, &r64, sizeof(r64));
+            if (rlen < 0) {
+                WOLFSSL_MSG("read custom event failure");
+            }
+
             break;
         }
@@ -961,5 +1202,5 @@
 #else /* HAVE_CRL_MONITOR */
 
-#ifndef NO_FILESYSTEM
+#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
 
 static int StartMonitorCRL(WOLFSSL_CRL* crl)
@@ -973,5 +1214,5 @@
 }
 
-#endif /* NO_FILESYSTEM */
+#endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
 
 #endif  /* HAVE_CRL_MONITOR */
