Bläddra i källkod

Merge pull request #1319 from JacobBarthelmeh/Compatibility-Layer-Part5

Compatibility layer part4
toddouska 6 år sedan
förälder
incheckning
2efe7f6d96

+ 2 - 1
configure.ac

@@ -460,7 +460,8 @@ fi
 
 if test "$ENABLED_OPENSSLEXTRA" = "yes" && test "x$ENABLED_OPENSSLCOEXIST" = "xno"
 then
-  AM_CFLAGS="-DOPENSSL_EXTRA $AM_CFLAGS"
+  AM_CFLAGS="-DOPENSSL_EXTRA -DWOLFSSL_ALWAYS_VERIFY_CB $AM_CFLAGS"
+  AM_CFLAGS="-DWOLFSSL_VERIFY_CB_ALL_CERTS $AM_CFLAGS"
 fi
 
 if test "$ENABLED_OPENSSLEXTRA" = "yes" && test "$ENABLED_SMALL" = "yes"

+ 0 - 2
examples/client/client.c

@@ -812,9 +812,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
     int    disableCRL    = 0;
     int    externalTest  = 0;
     int    ret;
-#ifndef WOLFSSL_CALLBACKS
     int    err           = 0;
-#endif
     int    scr           = 0;    /* allow secure renegotiation */
     int    forceScr      = 0;    /* force client initiaed scr */
     int    useClientCert = 1;

+ 502 - 5
src/bio.c

@@ -23,6 +23,480 @@
     #warning bio.c does not need to be compiled seperatly from ssl.c
 #else
 
+
+/* Helper function to decode a base64 input
+ *
+ * returns size of resulting buffer on success
+ */
+static int wolfSSL_BIO_BASE64_read(WOLFSSL_BIO* bio, void* buf, int len)
+{
+    word32 frmtSz = len;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_BASE64_read");
+
+    if (Base64_Decode((const byte*)buf, (word32)len, (byte*)buf, &frmtSz) !=0) {
+        WOLFSSL_MSG("Err doing base64 decode");
+        return SSL_FATAL_ERROR;
+    }
+
+    (void)bio;
+    return (int)frmtSz;
+}
+
+
+/* Helper function to read from WOLFSSL_BIO_BIO type
+ *
+ * returns amount in bytes read on success
+ */
+static int wolfSSL_BIO_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
+{
+    int   sz;
+    char* pt;
+
+    sz = wolfSSL_BIO_nread(bio, &pt, len);
+
+    if (sz > 0) {
+        XMEMCPY(buf, pt, sz);
+    }
+
+    return sz;
+}
+
+
+/* Handles reading from a memory type BIO and advancing the state.
+ *
+ * bio  WOLFSSL_BIO to read from
+ * buf  buffer to put data from bio in
+ * len  amount of data to be read
+ *
+ * returns size read on success
+ */
+static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len)
+{
+    int   sz;
+
+    sz = wolfSSL_BIO_pending(bio);
+    if (sz > 0) {
+        const unsigned char* pt = NULL;
+        int memSz;
+
+        if (sz > len) {
+            sz = len;
+        }
+        memSz = wolfSSL_BIO_get_mem_data(bio, (void*)&pt);
+        if (memSz >= sz && pt != NULL) {
+            byte* tmp;
+
+            XMEMCPY(buf, (void*)pt, sz);
+            if (memSz - sz > 0) {
+                tmp = (byte*)XMALLOC(memSz-sz, bio->heap, DYNAMIC_TYPE_OPENSSL);
+                if (tmp == NULL) {
+                    WOLFSSL_MSG("Memory error");
+                    return WOLFSSL_BIO_ERROR;
+                }
+                XMEMCPY(tmp, (void*)(pt + sz), memSz - sz);
+
+                /* reset internal bio->mem */
+                XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
+                bio->mem    = tmp;
+                bio->memLen = memSz-sz;
+                if (bio->mem_buf != NULL) {
+                    bio->mem_buf->data = (char*)bio->mem;
+                    bio->mem_buf->length = bio->memLen;
+                }
+            }
+            bio->wrSz  -= sz;
+        }
+        else {
+            WOLFSSL_MSG("Issue with getting bio mem pointer");
+            return 0;
+        }
+    }
+    else {
+        return WOLFSSL_BIO_ERROR;
+    }
+
+    return sz;
+}
+
+
+/* Helper function to read from WOLFSSL_BIO_SSL type
+ *
+ * returns the number of bytes read on success
+ */
+static int wolfSSL_BIO_SSL_read(WOLFSSL_BIO* bio, void* buf,
+        int len, WOLFSSL_BIO* front)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_SSL_write");
+
+    /* already got eof, again is error */
+    if (bio && front->eof)
+        return WOLFSSL_FATAL_ERROR;
+
+    ret = wolfSSL_read(bio->ssl, buf, len);
+    if (ret == 0)
+        front->eof = 1;
+    else if (ret < 0) {
+        int err = wolfSSL_get_error(bio->ssl, 0);
+        if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
+            front->eof = 1;
+    }
+
+    return ret;
+}
+
+
+
+/* Used to read data from a WOLFSSL_BIO structure
+ *
+ * bio  structure to read data from
+ * buf  buffer to hold the result
+ * len  length of buf buffer
+ *
+ * returns the number of bytes read on success
+ */
+int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
+{
+    int  ret = 0;
+    WOLFSSL_BIO* front = bio;
+    int  sz  = 0;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_read");
+
+    /* start at end of list and work backwards */
+    while (bio->next != NULL) {
+        bio = bio->next;
+    }
+
+    while (bio != NULL && ret >= 0) {
+        /* formating data */
+        if (bio->type == WOLFSSL_BIO_BASE64 && ret > 0 && sz > 0) {
+            ret = wolfSSL_BIO_BASE64_read(bio, buf, sz);
+        }
+
+        /* write BIOs */
+        if (bio && bio->type == WOLFSSL_BIO_BIO) {
+            ret = wolfSSL_BIO_BIO_read(bio, buf, len);
+        }
+
+        if (bio && bio->type == WOLFSSL_BIO_MEMORY) {
+            ret = wolfSSL_BIO_MEMORY_read(bio, buf, len);
+        }
+
+    #ifndef NO_FILESYSTEM
+        if (bio && bio->type == WOLFSSL_BIO_FILE) {
+            ret = (int)XFREAD(buf, 1, len, bio->file);
+        }
+    #endif
+
+        if (bio && bio->type == WOLFSSL_BIO_SSL) {
+            ret = wolfSSL_BIO_SSL_read(bio, buf, len, front);
+        }
+
+        /* case where front of list is done */
+        if (bio == front) {
+            break; /* at front of list so be done */
+        }
+
+        if (ret > 0) {
+            sz = ret; /* adjust size for formating */
+        }
+
+        /* previous WOLFSSL_BIO in list working towards head of list */
+        bio = bio->prev;
+    }
+
+    return ret;
+}
+
+
+/* Converts data into base64 output
+ *
+ * returns the resulting buffer size on success.
+ */
+static int wolfSSL_BIO_BASE64_write(WOLFSSL_BIO* bio, const void* data,
+        word32 inLen, byte* out, word32* outLen)
+{
+    byte* tmp = NULL;
+    int ret   = 0;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_BASE64_write");
+
+    if (bio == NULL || data == NULL || out == NULL || outLen == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+#if defined(WOLFSSL_BASE64_ENCODE)
+    tmp = (byte*)XMALLOC(*outLen, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    if (tmp == NULL) {
+        return WOLFSSL_FATAL_ERROR;
+    }
+
+    if ((bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) ==
+            WOLFSSL_BIO_FLAG_BASE64_NO_NL) {
+        if (Base64_Encode_NoNl((const byte*)data, inLen,
+                tmp, outLen) < 0) {
+            ret = WOLFSSL_FATAL_ERROR;
+        }
+    }
+    else {
+        if (Base64_Encode((const byte*)data, inLen,
+                tmp, outLen) < 0) {
+            ret = WOLFSSL_FATAL_ERROR;
+        }
+    }
+
+    if (ret != WOLFSSL_FATAL_ERROR) {
+        ret = (int)*outLen;
+        XMEMCPY(out, tmp, *outLen);
+
+    }
+    XFREE(tmp, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
+#else
+    (void)bio;
+    (void)data;
+    (void)inLen;
+    (void)out;
+    (void)outLen;
+    (void)tmp;
+    WOLFSSL_MSG("BASE64 encoding not compiled in");
+#endif
+    return ret;
+}
+
+
+/* Helper function for writing to a WOLFSSL_BIO_SSL type
+ *
+ * returns the amount written in bytes on success
+ */
+static int wolfSSL_BIO_SSL_write(WOLFSSL_BIO* bio, const void* data,
+        int len, WOLFSSL_BIO* front)
+{
+    int ret;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_SSL_write");
+
+    if (bio->ssl == 0) return BAD_FUNC_ARG;
+
+    ret = wolfSSL_write(bio->ssl, data, len);
+    if (ret == 0)
+        front->eof = 1;
+    else if (ret < 0) {
+        int err = wolfSSL_get_error(bio->ssl, 0);
+        if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
+            front->eof = 1;
+    }
+    return ret;
+}
+
+
+/* Writes to a WOLFSSL_BIO_BIO type.
+ *
+ * returns the amount written on success
+ */
+static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data,
+        int len)
+{
+    int   sz;
+    char* buf;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_BIO_write");
+
+    /*adding in sanity checks for static analysis tools */
+    if (bio == NULL || data == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    sz = wolfSSL_BIO_nwrite(bio, &buf, len);
+
+    /* test space for write */
+    if (sz <= 0) {
+        WOLFSSL_MSG("No room left to write");
+        return sz;
+    }
+
+    XMEMCPY(buf, data, sz);
+
+    return sz;
+}
+
+
+/* for complete compatibility a bio memory write allocs its own memory
+ * until the application runs out ....
+ *
+ * bio  structure to hold incoming data
+ * data buffer holding the data to be written
+ * len  length of data buffer
+ *
+ * returns the amount of data written on success and WOLFSSL_FAILURE or
+ *         WOLFSSL_BIO_ERROR for failure cases.
+ */
+static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data,
+        int len)
+{
+    int   sz;
+    const unsigned char* buf;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_MEMORY_write");
+
+    if (bio == NULL || data == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    sz = wolfSSL_BIO_pending(bio);
+    if (sz < 0) {
+        WOLFSSL_MSG("Error getting memory data");
+        return sz;
+    }
+
+    if (bio->mem == NULL) {
+        bio->mem = (byte*)XMALLOC(len, bio->heap, DYNAMIC_TYPE_OPENSSL);
+        if (bio->mem == NULL) {
+            WOLFSSL_MSG("Error on malloc");
+            return WOLFSSL_FAILURE;
+        }
+        bio->memLen = len;
+        if (bio->mem_buf != NULL) {
+            bio->mem_buf->data = (char*)bio->mem;
+            bio->mem_buf->length = bio->memLen;
+        }
+    }
+
+    /* check if will fit in current buffer size */
+    if (wolfSSL_BIO_get_mem_data(bio, (void*)&buf) < 0) {
+        return WOLFSSL_BIO_ERROR;
+    }
+    if (bio->memLen < sz + len) {
+        bio->mem = (byte*)XREALLOC(bio->mem, sz + len, bio->heap,
+            DYNAMIC_TYPE_OPENSSL);
+        if (bio->mem == NULL) {
+            WOLFSSL_MSG("Error on realloc");
+            return WOLFSSL_FAILURE;
+        }
+        bio->memLen = sz + len;
+        if (bio->mem_buf != NULL) {
+            bio->mem_buf->data = (char*)bio->mem;
+            bio->mem_buf->length = bio->memLen;
+        }
+    }
+
+    XMEMCPY(bio->mem + sz, data, len);
+    bio->wrSz += len;
+
+    return len;
+}
+
+
+/* Writes data to a WOLFSSL_BIO structure
+ *
+ * bio  structure to write to
+ * data holds the data to be written
+ * len  length of data buffer
+ *
+ * returns the amount written in bytes on success
+ */
+int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
+{
+    int  ret = 0;
+    WOLFSSL_BIO* front = bio;
+    void*  frmt   = NULL;
+    word32 frmtSz = 0;
+
+    WOLFSSL_ENTER("wolfSSL_BIO_write");
+
+    while (bio != NULL && ret >= 0) {
+        /* check for formating */
+        if (bio && bio->type == WOLFSSL_BIO_BASE64) {
+#if defined(WOLFSSL_BASE64_ENCODE)
+            word32 sz = 0;
+
+            if (bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) {
+                if (Base64_Encode_NoNl((const byte*)data, len, NULL,
+                            &sz) != LENGTH_ONLY_E) {
+                    WOLFSSL_MSG("Error with base 64 get length");
+                    ret = SSL_FATAL_ERROR;
+                }
+            }
+            else {
+                if (Base64_Encode((const byte*)data, len, NULL, &sz) !=
+                    LENGTH_ONLY_E) {
+                    WOLFSSL_MSG("Error with base 64 get length");
+                    ret = SSL_FATAL_ERROR;
+                }
+            }
+
+            if (frmt == NULL && sz > 0 && ret != SSL_FATAL_ERROR) {
+                frmt = (void*)XMALLOC(sz, front->heap,
+                        DYNAMIC_TYPE_TMP_BUFFER);
+                if (frmt == NULL) {
+                    WOLFSSL_MSG("Memory error");
+                    ret = SSL_FATAL_ERROR;
+                }
+                frmtSz = sz;
+            }
+            else if (sz > frmtSz) {
+                frmt = (void*)XREALLOC(frmt, sz, front->heap,
+                        DYNAMIC_TYPE_TMP_BUFFER);
+                if (frmt == NULL) {
+                    WOLFSSL_MSG("Memory error");
+                    ret = SSL_FATAL_ERROR;
+                }
+                /* since frmt already existed then data should point to knew
+                   formated buffer */
+                data = frmt;
+                len  = frmtSz;
+                frmtSz = sz;
+            }
+#endif /* defined(WOLFSSL_BASE64_ENCODE) */
+
+            if (ret >= 0) {
+                /* change so that data is formated buffer */
+                ret = wolfSSL_BIO_BASE64_write(bio, data, (word32)len,
+                        (byte*)frmt, &frmtSz);
+                data = frmt;
+                len  = frmtSz;
+            }
+        }
+
+        /* write bios */
+        if (bio && bio->type == WOLFSSL_BIO_BIO) {
+            ret = wolfSSL_BIO_BIO_write(bio, data, len);
+        }
+
+        if (bio && bio->type == WOLFSSL_BIO_MEMORY) {
+            ret = wolfSSL_BIO_MEMORY_write(bio, data, len);
+        }
+
+    #ifndef NO_FILESYSTEM
+        if (bio && bio->type == WOLFSSL_BIO_FILE) {
+            ret = (int)XFWRITE(data, 1, len, bio->file);
+        }
+    #endif
+
+        if (bio && bio->type == WOLFSSL_BIO_SSL) {
+            /* already got eof, again is error */
+            if (bio && front->eof) {
+                ret = SSL_FATAL_ERROR;
+            }
+            else {
+                ret = wolfSSL_BIO_SSL_write(bio, data, len, front);
+            }
+        }
+
+        /* advance to the next bio in list */
+        bio = bio->next;
+    }
+
+    if (frmt != NULL) {
+        XFREE(frmt, front->heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+
+    return ret;
+}
+
+
 /*** TBD ***/
 WOLFSSL_API long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *parg)
 {
@@ -71,7 +545,7 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz)
     WOLFSSL_ENTER("wolfSSL_BIO_gets");
 
     if (bio == NULL || buf == NULL) {
-        return SSL_FAILURE;
+        return WOLFSSL_FAILURE;
     }
 
     /* not enough space for character plus terminator */
@@ -127,7 +601,7 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz)
                     buf[cSz] = '\0';
                 }
 
-                ret = wolfSSL_BIO_read(bio, (void*)buf, cSz);
+                ret = wolfSSL_BIO_MEMORY_read(bio, (void*)buf, cSz);
                 /* ret is read after the switch statment */
                 break;
             }
@@ -247,14 +721,20 @@ size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio)
 
 long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **ptr)
 {
-    WOLFSSL_ENTER("BIO_get_mem_ptr");
+    WOLFSSL_ENTER("wolfSSL_BIO_get_mem_ptr");
 
     if (bio == NULL || ptr == NULL) {
         return WOLFSSL_FAILURE;
     }
 
-    *ptr = (WOLFSSL_BUF_MEM*)(bio->mem);
-    return WOLFSSL_SUCCESS;
+    if (bio->type == WOLFSSL_BIO_FILE || bio->type == WOLFSSL_BIO_SOCKET) {
+        WOLFSSL_MSG("NO memory buffer for FILE type");
+        return SSL_FAILURE;
+    }
+
+    *ptr = bio->mem_buf;
+
+    return SSL_SUCCESS;
 }
 
 /*** TBD ***/
@@ -301,6 +781,10 @@ int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size)
     bio->memLen = bio->wrSz;
     bio->wrIdx = 0;
     bio->rdIdx = 0;
+    if (bio->mem_buf != NULL) {
+        bio->mem_buf->data = (char*)bio->mem;
+        bio->mem_buf->length = bio->memLen;
+    }
 
     return WOLFSSL_SUCCESS;
 }
@@ -532,6 +1016,19 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio)
             bio->wrIdx = 0;
             return 0;
 
+        case WOLFSSL_BIO_MEMORY:
+            bio->rdIdx = 0;
+            bio->wrIdx = 0;
+            bio->wrSz  = 0;
+            XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
+            bio->mem = NULL;
+            bio->memLen = 0;
+            if (bio->mem_buf != NULL) {
+                bio->mem_buf->data = (char*)bio->mem;
+                bio->mem_buf->length = bio->memLen;
+            }
+            return 0;
+
         default:
             WOLFSSL_MSG("Unknown BIO type needs added to reset function");
     }

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 477 - 99
src/internal.c


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 372 - 358
src/ssl.c


+ 22 - 0
src/tls.c

@@ -8735,7 +8735,29 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
 #ifndef NO_WOLFSSL_CLIENT
 
 #ifndef NO_OLD_TLS
+
     #ifdef WOLFSSL_ALLOW_TLSV10
+    #ifdef OPENSSL_EXTRA
+    /* Gets a WOLFSL_METHOD type that is not set as client or server
+     *
+     * Returns a pointer to a WOLFSSL_METHOD struct
+     */
+    WOLFSSL_METHOD* wolfTLSv1_method(void) {
+        WOLFSSL_METHOD* m;
+        WOLFSSL_ENTER("wolfTLSv1_method");
+    #ifndef NO_WOLFSSL_CLIENT
+        m = wolfTLSv1_client_method();
+    #else
+        m = wolfTLSv1_server_method();
+    #endif
+        if (m != NULL) {
+            m->side = WOLFSSL_NEITHER_END;
+        }
+
+        return m;
+    }
+    #endif /* OPENSSL_EXTRA */
+
     WOLFSSL_METHOD* wolfTLSv1_client_method(void)
     {
         return wolfTLSv1_client_method_ex(NULL);

+ 36 - 38
src/tls13.c

@@ -2379,10 +2379,10 @@ int SendTls13ClientHello(WOLFSSL* ssl)
     ssl->options.clientState = CLIENT_HELLO_COMPLETE;
 
 #ifdef WOLFSSL_CALLBACKS
-    if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
+    if (ssl->hsInfoOn) AddPacketName(ssl, "ClientHello");
     if (ssl->toInfoOn) {
-        AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
-                      ssl->heap);
+        AddPacketInfo(ssl, "ClientHello", handshake, output, sendSz,
+                      WRITE_PROTO, ssl->heap);
     }
 #endif
 
@@ -2530,7 +2530,7 @@ static int DoTls13HelloRetryRequest(WOLFSSL* ssl, const byte* input,
     WOLFSSL_ENTER("DoTls13HelloRetryRequest");
 
 #ifdef WOLFSSL_CALLBACKS
-    if (ssl->hsInfoOn) AddPacketName("HelloRetryRequest", &ssl->handShakeInfo);
+    if (ssl->hsInfoOn) AddPacketName(ssl, "HelloRetryRequest");
     if (ssl->toInfoOn) AddLateName("HelloRetryRequest", &ssl->timeoutInfo);
 #endif
 
@@ -2617,7 +2617,7 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
     WOLFSSL_ENTER("DoTls13ServerHello");
 
 #ifdef WOLFSSL_CALLBACKS
-    if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
+    if (ssl->hsInfoOn) AddPacketName(ssl, "ServerHello");
     if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
 #endif
 
@@ -2803,8 +2803,7 @@ static int DoTls13EncryptedExtensions(WOLFSSL* ssl, const byte* input,
     WOLFSSL_ENTER("DoTls13EncryptedExtensions");
 
 #ifdef WOLFSSL_CALLBACKS
-    if (ssl->hsInfoOn) AddPacketName("EncryptedExtensions",
-                                     &ssl->handShakeInfo);
+    if (ssl->hsInfoOn) AddPacketName(ssl, "EncryptedExtensions");
     if (ssl->toInfoOn) AddLateName("EncryptedExtensions", &ssl->timeoutInfo);
 #endif
 
@@ -2867,7 +2866,7 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
     WOLFSSL_ENTER("DoTls13CertificateRequest");
 
 #ifdef WOLFSSL_CALLBACKS
-    if (ssl->hsInfoOn) AddPacketName("CertificateRequest", &ssl->handShakeInfo);
+    if (ssl->hsInfoOn) AddPacketName(ssl, "CertificateRequest");
     if (ssl->toInfoOn) AddLateName("CertificateRequest", &ssl->timeoutInfo);
 #endif
 
@@ -3470,7 +3469,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
     WOLFSSL_ENTER("DoTls13ClientHello");
 
 #ifdef WOLFSSL_CALLBACKS
-    if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
+    if (ssl->hsInfoOn) AddPacketName(ssl, "ClientHello");
     if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
 #endif
 
@@ -3697,10 +3696,10 @@ int SendTls13HelloRetryRequest(WOLFSSL* ssl)
 
 #ifdef WOLFSSL_CALLBACKS
     if (ssl->hsInfoOn)
-        AddPacketName("HelloRetryRequest", &ssl->handShakeInfo);
+        AddPacketName(ssl, "HelloRetryRequest");
     if (ssl->toInfoOn) {
-        AddPacketInfo("HelloRetryRequest", &ssl->timeoutInfo, output, sendSz,
-                      ssl->heap);
+        AddPacketInfo(ssl, "HelloRetryRequest", handshake, output, sendSz,
+                      WRITE_PROTO, ssl->heap);
     }
 #endif
     if ((ret = HashOutput(ssl, output, idx, 0)) != 0)
@@ -3831,10 +3830,10 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
 
     #ifdef WOLFSSL_CALLBACKS
     if (ssl->hsInfoOn)
-        AddPacketName("ServerHello", &ssl->handShakeInfo);
+        AddPacketName(ssl, "ServerHello");
     if (ssl->toInfoOn) {
-        AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
-                      ssl->heap);
+        AddPacketInfo(ssl, "ServerHello", handshake, output, sendSz,
+                      WRITE_PROTO, ssl->heap);
     }
     #endif
 
@@ -3916,10 +3915,10 @@ static int SendTls13EncryptedExtensions(WOLFSSL* ssl)
 
 #ifdef WOLFSSL_CALLBACKS
     if (ssl->hsInfoOn)
-        AddPacketName("EncryptedExtensions", &ssl->handShakeInfo);
+        AddPacketName(ssl, "EncryptedExtensions");
     if (ssl->toInfoOn) {
-        AddPacketInfo("EncryptedExtensions", &ssl->timeoutInfo, output,
-                      sendSz, ssl->heap);
+        AddPacketInfo(ssl, "EncryptedExtensions", handshake, output,
+                      sendSz, WRITE_PROTO, ssl->heap);
     }
 #endif
 
@@ -4053,10 +4052,10 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
 
     #ifdef WOLFSSL_CALLBACKS
         if (ssl->hsInfoOn)
-            AddPacketName("CertificateRequest", &ssl->handShakeInfo);
+            AddPacketName(ssl, "CertificateRequest");
         if (ssl->toInfoOn) {
-            AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
-                          sendSz, ssl->heap);
+            AddPacketInfo(ssl, "CertificateRequest", handshake, output,
+                          sendSz, WRITE_PROTO, ssl->heap);
         }
     #endif
 
@@ -4646,10 +4645,10 @@ static int SendTls13Certificate(WOLFSSL* ssl)
 
         #ifdef WOLFSSL_CALLBACKS
             if (ssl->hsInfoOn)
-                AddPacketName("Certificate", &ssl->handShakeInfo);
+                AddPacketName(ssl, "Certificate");
             if (ssl->toInfoOn) {
-                AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
-                               ssl->heap);
+                AddPacketInfo(ssl, "Certificate", handshake, output,
+                        sendSz, WRITE_PROTO, ssl->heap);
             }
         #endif
 
@@ -4986,10 +4985,10 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
 
         #ifdef WOLFSSL_CALLBACKS
             if (ssl->hsInfoOn)
-                AddPacketName("CertificateVerify", &ssl->handShakeInfo);
+                AddPacketName(ssl, "CertificateVerify");
             if (ssl->toInfoOn) {
-                AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
-                              args->output, args->sendSz, ssl->heap);
+                AddPacketInfo(ssl, "CertificateVerify", handshake,
+                            args->output, args->sendSz, WRITE_PROTO, ssl->heap);
             }
         #endif
 
@@ -5136,8 +5135,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
         case TLS_ASYNC_BEGIN:
         {
         #ifdef WOLFSSL_CALLBACKS
-            if (ssl->hsInfoOn) AddPacketName("CertificateVerify",
-                                             &ssl->handShakeInfo);
+            if (ssl->hsInfoOn) AddPacketName(ssl, "CertificateVerify");
             if (ssl->toInfoOn) AddLateName("CertificateVerify",
                                            &ssl->timeoutInfo);
         #endif
@@ -5419,7 +5417,7 @@ static int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
         return BUFFER_ERROR;
 
     #ifdef WOLFSSL_CALLBACKS
-        if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
+        if (ssl->hsInfoOn) AddPacketName(ssl, "Finished");
         if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
     #endif
 
@@ -5531,10 +5529,10 @@ static int SendTls13Finished(WOLFSSL* ssl)
     }
 
     #ifdef WOLFSSL_CALLBACKS
-        if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
+        if (ssl->hsInfoOn) AddPacketName(ssl, "Finished");
         if (ssl->toInfoOn) {
-            AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
-                          ssl->heap);
+            AddPacketInfo(ssl, "Finished", handshake, output, sendSz,
+                          WRITE_PROTO, ssl->heap);
         }
     #endif
 
@@ -5651,10 +5649,10 @@ static int SendTls13KeyUpdate(WOLFSSL* ssl)
         return BUILD_MSG_ERROR;
 
     #ifdef WOLFSSL_CALLBACKS
-        if (ssl->hsInfoOn) AddPacketName("KeyUpdate", &ssl->handShakeInfo);
+        if (ssl->hsInfoOn) AddPacketName(ssl, "KeyUpdate");
         if (ssl->toInfoOn) {
-            AddPacketInfo("KeyUpdate", &ssl->timeoutInfo, output, sendSz,
-                          ssl->heap);
+            AddPacketInfo(ssl, "KeyUpdate", handshake, output, sendSz,
+                          WRITE_PROTO, ssl->heap);
         }
     #endif
 
@@ -6365,8 +6363,8 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
     /* add name later, add on record and handshake header part back on */
     if (ssl->toInfoOn) {
         int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
-        AddPacketInfo(0, &ssl->timeoutInfo, input + *inOutIdx - add,
-                      size + add, ssl->heap);
+        AddPacketInfo(ssl, 0, handshake, input + *inOutIdx - add,
+                      size + add, READ_PROTO, ssl->heap);
         AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
     }
 #endif

+ 89 - 0
src/wolfio.c

@@ -102,6 +102,95 @@ static INLINE int wolfSSL_LastError(void)
 #endif /* USE_WOLFSSL_IO || HAVE_HTTP_CLIENT */
 
 
+/* Use the WOLFSSL read BIO for receiving data. This is set by the fucntion wolfSSL_set_bio and can also be set by wolfSSL_SetIORecv.
+ *
+ * ssl  WOLFSSL struct passed in that has this function set as the receive callback.
+ * buf  buffer to fill with data read
+ * sz   size of buf buffer
+ * ctx  a user set context
+ *
+ * returns the amount of data read or want read. See WOLFSSL_CBIO_ERR_* values.
+ */
+int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx)
+{
+    int recvd = WOLFSSL_CBIO_ERR_GENERAL;
+
+    WOLFSSL_ENTER("BioReceive");
+#ifdef OPENSSL_EXTRA
+    if (ssl->biord == NULL) {
+        WOLFSSL_MSG("WOLFSSL biord not set");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    switch (ssl->biord->type) {
+        case WOLFSSL_BIO_MEMORY:
+            if (wolfSSL_BIO_ctrl_pending(ssl->biord) == 0) {
+               return WOLFSSL_CBIO_ERR_WANT_READ;
+            }
+            recvd = wolfSSL_BIO_read(ssl->biord, buf, sz);
+            if (recvd <= 0) {
+                return WOLFSSL_CBIO_ERR_GENERAL;
+            }
+            break;
+
+       default:
+            WOLFSSL_MSG("This BIO type is unknown / unsupported");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+#else
+    (void)ssl;
+    (void)buf;
+    (void)sz;
+    WOLFSSL_MSG("OPENSSL_EXTRA not compiled in");
+#endif
+    (void)ctx;
+    return recvd;
+}
+
+
+/* Use the WOLFSSL write BIO for sending data. This is set by the fucntion wolfSSL_set_bio and can also be set by wolfSSL_SetIOSend.
+ *
+ * ssl  WOLFSSL struct passed in that has this function set as the send callback.
+ * buf  buffer with data to write out
+ * sz   size of buf buffer
+ * ctx  a user set context
+ *
+ * returns the amount of data sent or want send. See WOLFSSL_CBIO_ERR_* values.
+ */
+int BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
+{
+    int sent = WOLFSSL_CBIO_ERR_GENERAL;
+
+#ifdef OPENSSL_EXTRA
+    if (ssl->biowr == NULL) {
+        WOLFSSL_MSG("WOLFSSL biowr not set\n");
+        return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+
+    switch (ssl->biowr->type) {
+        case WOLFSSL_BIO_MEMORY:
+            sent = wolfSSL_BIO_write(ssl->biowr, buf, sz);
+            if (sent < 0) {
+                return WOLFSSL_CBIO_ERR_GENERAL;
+            }
+            break;
+
+        default:
+            WOLFSSL_MSG("This BIO type is unknown / unsupported");
+            return WOLFSSL_CBIO_ERR_GENERAL;
+    }
+#else
+    (void)ssl;
+    (void)buf;
+    (void)sz;
+    WOLFSSL_MSG("OPENSSL_EXTRA not compiled in");
+#endif
+    (void)ctx;
+
+    return sent;
+}
+
+
 #ifdef USE_WOLFSSL_IO
 
 /* The receive embedded callback

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 805 - 31
tests/api.c


+ 67 - 16
wolfcrypt/src/asn.c

@@ -364,8 +364,6 @@ static int GetASNInt(const byte* input, word32* inOutIdx, int* len,
             if (*len > 0 && (input[*inOutIdx] & 0x80) == 0)
                 return ASN_PARSE_E;
         }
-        else if ((input[*inOutIdx] & 0x80) == 0x80)
-            return ASN_PARSE_E;
     }
 
     return 0;
@@ -2572,6 +2570,11 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
     byte   cbcIv[MAX_IV_SIZE];
 #endif
 
+    if (passwordSz < 0) {
+        WOLFSSL_MSG("Bad password size");
+        return BAD_FUNC_ARG;
+    }
+
     if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
         ERROR_OUT(ASN_PARSE_E, exit_tte);
     }
@@ -3663,6 +3666,7 @@ static int GetName(DecodedCert* cert, int nameType)
     #ifdef OPENSSL_EXTRA
         DecodedName* dName =
                   (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;
+        int dcnum = 0;
     #endif /* OPENSSL_EXTRA */
 
     WOLFSSL_MSG("Getting Cert Name");
@@ -3958,6 +3962,7 @@ static int GetName(DecodedCert* cert, int nameType)
                             WOLFSSL_MSG("\tOut of Memory");
                             return MEMORY_E;
                         }
+                        emailName->type = 0;
                         emailName->name = (char*)XMALLOC(adv + 1,
                                               cert->heap, DYNAMIC_TYPE_ALTNAME);
                         if (emailName->name == NULL) {
@@ -3999,8 +4004,10 @@ static int GetName(DecodedCert* cert, int nameType)
                             XMEMCPY(&full[idx], "/DC=", 4);
                             idx += 4;
                         #ifdef OPENSSL_EXTRA
-                            dName->dcIdx = cert->srcIdx;
-                            dName->dcLen = adv;
+                            dName->dcIdx[dcnum] = cert->srcIdx;
+                            dName->dcLen[dcnum] = adv;
+                            dName->dcNum = dcnum + 1;
+                            dcnum++;
                         #endif /* OPENSSL_EXTRA */
                             break;
 
@@ -4021,6 +4028,7 @@ static int GetName(DecodedCert* cert, int nameType)
     #ifdef OPENSSL_EXTRA
     {
         int totalLen = 0;
+        int i = 0;
 
         if (dName->cnLen != 0)
             totalLen += dName->cnLen + 4;
@@ -4042,8 +4050,10 @@ static int GetName(DecodedCert* cert, int nameType)
             totalLen += dName->uidLen + 5;
         if (dName->serialLen != 0)
             totalLen += dName->serialLen + 14;
-        if (dName->dcLen != 0)
-            totalLen += dName->dcLen + 4;
+        if (dName->dcNum != 0){
+            for (i = 0;i < dName->dcNum;i++)
+                totalLen += dName->dcLen[i] + 4;
+        }
 
         dName->fullName = (char*)XMALLOC(totalLen + 1, cert->heap,
                                                              DYNAMIC_TYPE_X509);
@@ -4122,14 +4132,16 @@ static int GetName(DecodedCert* cert, int nameType)
                 dName->emailIdx = idx;
                 idx += dName->emailLen;
             }
-            if (dName->dcLen != 0) {
-                dName->entryCount++;
-                XMEMCPY(&dName->fullName[idx], "/DC=", 4);
-                idx += 4;
-                XMEMCPY(&dName->fullName[idx],
-                                   &cert->source[dName->dcIdx], dName->dcLen);
-                dName->dcIdx = idx;
-                idx += dName->dcLen;
+            for (i = 0;i < dName->dcNum;i++){
+                if (dName->dcLen[i] != 0) {
+                    dName->entryCount++;
+                    XMEMCPY(&dName->fullName[idx], "/DC=", 4);
+                    idx += 4;
+                    XMEMCPY(&dName->fullName[idx],
+                                    &cert->source[dName->dcIdx[i]], dName->dcLen[i]);
+                    dName->dcIdx[i] = idx;
+                    idx += dName->dcLen[i];
+                }
             }
             if (dName->uidLen != 0) {
                 dName->entryCount++;
@@ -5357,6 +5369,7 @@ static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
                 return MEMORY_E;
             }
 
+            dnsEntry->type = ASN_DNS_TYPE;
             dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
                                          DYNAMIC_TYPE_ALTNAME);
             if (dnsEntry->name == NULL) {
@@ -5393,6 +5406,7 @@ static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
                 return MEMORY_E;
             }
 
+            emailEntry->type = ASN_RFC822_TYPE;
             emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
                                          DYNAMIC_TYPE_ALTNAME);
             if (emailEntry->name == NULL) {
@@ -5410,8 +5424,45 @@ static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
             length -= strLen;
             idx    += strLen;
         }
-    #endif /* IGNORE_NAME_CONSTRAINTS */
-    #ifdef WOLFSSL_SEP
+        else if (b == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
+            DNS_entry* uriEntry;
+            int strLen;
+            word32 lenStartIdx = idx;
+
+            WOLFSSL_MSG("\tPutting URI into list but not using");
+            if (GetLength(input, &idx, &strLen, sz) < 0) {
+                WOLFSSL_MSG("\tfail: str length");
+                return ASN_PARSE_E;
+            }
+            length -= (idx - lenStartIdx);
+
+            uriEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
+                                        DYNAMIC_TYPE_ALTNAME);
+            if (uriEntry == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                return MEMORY_E;
+            }
+
+            uriEntry->type = ASN_URI_TYPE;
+            uriEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
+                                         DYNAMIC_TYPE_ALTNAME);
+            if (uriEntry->name == NULL) {
+                WOLFSSL_MSG("\tOut of Memory");
+                XFREE(uriEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
+                return MEMORY_E;
+            }
+
+            XMEMCPY(uriEntry->name, &input[idx], strLen);
+            uriEntry->name[strLen] = '\0';
+
+            uriEntry->next = cert->altNames;
+            cert->altNames = uriEntry;
+
+            length -= strLen;
+            idx    += strLen;
+        }
+#endif /* IGNORE_NAME_CONSTRAINTS */
+#ifdef WOLFSSL_SEP
         else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
         {
             int strLen;

+ 84 - 57
wolfcrypt/src/evp.c

@@ -25,7 +25,52 @@
 
 static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher);
 
-#ifdef WOLFSSL_SIGNAL
+
+/* Getter function for cipher key length
+ *
+ * c  WOLFSSL_EVP_CIPHER structure to get key length from
+ *
+ * NOTE: OpenSSL_add_all_ciphers() should be called first before using this
+ *       function
+ *
+ * Returns size of key in bytes
+ */
+int wolfSSL_EVP_Cipher_key_length(const WOLFSSL_EVP_CIPHER* c)
+{
+    WOLFSSL_ENTER("wolfSSL_EVP_Cipher_key_length");
+
+    if (c == NULL) {
+        return 0;
+    }
+
+    switch (cipherType(c)) {
+    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
+      case AES_128_CBC_TYPE: return 16;
+      case AES_192_CBC_TYPE: return 24;
+      case AES_256_CBC_TYPE: return 32;
+  #endif
+  #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
+      case AES_128_CTR_TYPE: return 16;
+      case AES_192_CTR_TYPE: return 24;
+      case AES_256_CTR_TYPE: return 32;
+  #endif
+  #if !defined(NO_AES) && defined(HAVE_AES_ECB)
+      case AES_128_ECB_TYPE: return 16;
+      case AES_192_ECB_TYPE: return 24;
+      case AES_256_ECB_TYPE: return 32;
+  #endif
+  #ifndef NO_DES3
+      case DES_CBC_TYPE:      return 8;
+      case DES_EDE3_CBC_TYPE: return 24;
+      case DES_ECB_TYPE:      return 8;
+      case DES_EDE3_ECB_TYPE: return 24;
+  #endif
+      default:
+          return 0;
+      }
+}
+
+
 WOLFSSL_API int  wolfSSL_EVP_EncryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
                                         const WOLFSSL_EVP_CIPHER* type,
                                         const unsigned char* key,
@@ -64,43 +109,6 @@ WOLFSSL_API int  wolfSSL_EVP_DecryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
     return wolfSSL_EVP_CipherInit(ctx, type, (byte*)key, (byte*)iv, 0);
 }
 
-#else /* WOLFSSL_SIGNAL */
-
-WOLFSSL_API int  wolfSSL_EVP_EncryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
-                                        const WOLFSSL_EVP_CIPHER* type,
-                                        unsigned char* key, unsigned char* iv)
-{
-    return wolfSSL_EVP_CipherInit(ctx, type, key, iv, 1);
-}
-
-WOLFSSL_API int  wolfSSL_EVP_EncryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
-                                        const WOLFSSL_EVP_CIPHER* type,
-                                        WOLFSSL_ENGINE *impl,
-                                        unsigned char* key, unsigned char* iv)
-{
-    (void) impl;
-    return wolfSSL_EVP_CipherInit(ctx, type, key, iv, 1);
-}
-
-WOLFSSL_API int  wolfSSL_EVP_DecryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
-                                        const WOLFSSL_EVP_CIPHER* type,
-                                        unsigned char* key, unsigned char* iv)
-{
-    WOLFSSL_ENTER("wolfSSL_EVP_CipherInit");
-    return wolfSSL_EVP_CipherInit(ctx, type, key, iv, 0);
-}
-
-WOLFSSL_API int  wolfSSL_EVP_DecryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
-                                        const WOLFSSL_EVP_CIPHER* type,
-                                        WOLFSSL_ENGINE *impl,
-                                        unsigned char* key, unsigned char* iv)
-{
-    (void) impl;
-    WOLFSSL_ENTER("wolfSSL_EVP_DecryptInit");
-    return wolfSSL_EVP_CipherInit(ctx, type, key, iv, 0);
-}
-
-#endif /* WOLFSSL_SIGNAL */
 
 WOLFSSL_API WOLFSSL_EVP_CIPHER_CTX *wolfSSL_EVP_CIPHER_CTX_new(void)
 {
@@ -143,7 +151,8 @@ WOLFSSL_API int  wolfSSL_EVP_EncryptFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
 WOLFSSL_API int  wolfSSL_EVP_CipherInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
                                     const WOLFSSL_EVP_CIPHER* type,
                                     WOLFSSL_ENGINE *impl,
-                                    unsigned char* key, unsigned char* iv,
+                                    const unsigned char* key,
+                                    const unsigned char* iv,
                                     int enc)
 {
     (void)impl;
@@ -194,7 +203,7 @@ WOLFSSL_API int wolfSSL_EVP_DigestInit_ex(WOLFSSL_EVP_MD_CTX* ctx,
 }
 
 #ifdef DEBUG_WOLFSSL_EVP
-#define PRINT_BUF(b, sz) { int i; for(i=0; i<(sz); i++){printf("%02x(%c),", (b)[i], (b)[i]); if((i+1)%8==0)printf("\n");}}
+#define PRINT_BUF(b, sz) { int _i; for(_i=0; _i<(sz); _i++){printf("%02x(%c),", (b)[_i], (b)[_i]); if((_i+1)%8==0)printf("\n");}}
 #else
 #define PRINT_BUF(b, sz)
 #endif
@@ -304,7 +313,8 @@ WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
     int fill;
 
     *outl = 0;
-    if ((ctx == NULL) || (inl < 0))return BAD_FUNC_ARG;
+    if ((ctx == NULL) || (inl < 0) ||
+        (outl == NULL)|| (out == NULL) || (in == NULL))return BAD_FUNC_ARG;
     WOLFSSL_ENTER("wolfSSL_EVP_CipherUpdate");
 
     if (inl == 0) return WOLFSSL_FAILURE;
@@ -345,7 +355,8 @@ WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
         inl  -= ctx->block_size * blocks;
         in   += ctx->block_size * blocks;
         if(ctx->enc == 0){
-            if ((ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING)){
+            if ((ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING) ||
+                    (ctx->block_size == 1)){
                 ctx->lastUsed = 0;
                 XMEMCPY(ctx->lastBlock, &out[ctx->block_size * blocks], ctx->block_size);
                 *outl+= ctx->block_size * blocks;
@@ -381,11 +392,10 @@ static int checkPad(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *buff)
     int i;
     int n;
     n = buff[ctx->block_size-1];
-
-    if (n > ctx->block_size) return FALSE;
+    if (n > ctx->block_size) return -1;
     for (i = 0; i < n; i++){
         if (buff[ctx->block_size-i-1] != n)
-            return FALSE;
+            return -1;
     }
     return ctx->block_size - n;
 }
@@ -423,7 +433,7 @@ WOLFSSL_API int  wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
             if ((fl = checkPad(ctx, ctx->lastBlock)) >= 0) {
                 XMEMCPY(out, ctx->lastBlock, fl);
                 *outl = fl;
-            } else return WOLFSSL_FAILURE;
+            } else return 0;
         }
     }
     return WOLFSSL_SUCCESS;
@@ -685,23 +695,27 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_decrypt(WOLFSSL_EVP_PKEY_CTX *ctx,
                      unsigned char *out, size_t *outlen,
                      const unsigned char *in, size_t inlen)
 {
-    if (ctx == NULL)return WOLFSSL_FAILURE;
+    int len;
+
+    if (ctx == NULL)return 0;
     WOLFSSL_ENTER("EVP_PKEY_decrypt");
 
     (void)out;
     (void)outlen;
     (void)in;
     (void)inlen;
+    (void)len;
 
     switch (ctx->pkey->type) {
 #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
     case EVP_PKEY_RSA:
-        *outlen = wolfSSL_RSA_private_decrypt((int)inlen, (unsigned char*)in, out,
+        len = wolfSSL_RSA_private_decrypt((int)inlen, (unsigned char*)in, out,
               ctx->pkey->rsa, ctx->padding);
-        if(*outlen > 0)
+        if(len < 0)return 0;
+        else {
+            *outlen = len ;
             return WOLFSSL_SUCCESS;
-        else
-            return WOLFSSL_FAILURE;
+        }
 #endif /* NO_RSA */
 
     case EVP_PKEY_EC:
@@ -725,7 +739,7 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_decrypt_init(WOLFSSL_EVP_PKEY_CTX *ctx)
     WOLFSSL_ENTER("EVP_PKEY_decrypt_init");
     switch(ctx->pkey->type){
     case EVP_PKEY_RSA:
-        ctx->op = EVP_PKEY_OP_ENCRYPT;
+        ctx->op = EVP_PKEY_OP_DECRYPT;
         return WOLFSSL_SUCCESS;
 
     case EVP_PKEY_EC:
@@ -898,12 +912,25 @@ static int md2nid(int md)
 {
     const char * d ;
     d = (const char *)wolfSSL_EVP_get_md((const unsigned char)md);
-    if (d == NULL) {
-        return MEMORY_E;
+    if (XSTRNCMP(d, "SHA", 3) == 0) {
+        if (XSTRLEN(d) > 3) {
+            if (XSTRNCMP(d, "SHA256", 6) == 0) {
+                return NID_sha256;
+            }
+            if (XSTRNCMP(d, "SHA384", 6) == 0) {
+                return NID_sha384;
+            }
+            if (XSTRNCMP(d, "SHA512", 6) == 0) {
+                return NID_sha512;
+            }
+            WOLFSSL_MSG("Unknown SHA type");
+            return 0;
+        }
+        else {
+            return NID_sha1;
+        }
     }
-
-    if (XSTRNCMP(d, "SHA", 3) == 0) return NID_sha1;
-    if (XSTRNCMP(d, "MD5", 3) == 0) return NID_md5;
+    if(XSTRNCMP(d, "MD5", 3) == 0)return NID_md5;
     return 0;
 }
 #endif /* NO_RSA */

+ 1 - 3
wolfcrypt/src/hmac.c

@@ -166,9 +166,7 @@ int wc_HmacSizeByType(int type)
     return ret;
 }
 
-
-/* software implementation */
-static int _InitHmac(Hmac* hmac, int type, void* heap)
+int _InitHmac(Hmac* hmac, int type, void* heap)
 {
     int ret = 0;
 

+ 46 - 4
wolfcrypt/src/logging.c

@@ -30,7 +30,10 @@
 
 #include <wolfssl/wolfcrypt/logging.h>
 #include <wolfssl/wolfcrypt/error-crypt.h>
-
+#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
+/* avoid adding WANT_READ and WANT_WRITE to error queue */
+#include <wolfssl/error-ssl.h>
+#endif
 
 #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
 static wolfSSL_Mutex debug_mutex; /* mutex for access to debug structure */
@@ -247,6 +250,11 @@ void WOLFSSL_ERROR(int error)
                     "wolfSSL error occurred, error = %d", error);
         }
         else {
+            #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
+            /* If running in compatibility mode do not add want read and
+               want right to error queue */
+            if (error != WANT_READ && error != WANT_WRITE) {
+            #endif
             if (error < 0)
                 error = error - (2 * error); /* get absolute value */
             XSNPRINTF(buffer, sizeof(buffer),
@@ -257,6 +265,9 @@ void WOLFSSL_ERROR(int error)
                 /* with void function there is no return here, continue on
                  * to unlock mutex and log what buffer was created. */
             }
+            #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
+            }
+            #endif
 
             wc_UnLockMutex(&debug_mutex);
         }
@@ -315,8 +326,6 @@ int wc_LoggingCleanup(void)
 }
 
 
-#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \
-    defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_MYSQL_COMPATIBLE)
 /* peek at an error node
  *
  * idx : if -1 then the most recent node is looked at, otherwise search
@@ -530,12 +539,12 @@ void wc_RemoveErrorNode(int idx)
     wc_UnLockMutex(&debug_mutex);
 }
 
-#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */
 
 /* Clears out the list of error nodes.
  */
 void wc_ClearErrorNodes(void)
 {
+#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX)
     if (wc_LockMutex(&debug_mutex) != 0) {
         WOLFSSL_MSG("Lock debug mutex failed");
         return;
@@ -557,6 +566,7 @@ void wc_ClearErrorNodes(void)
     wc_errors    = NULL;
     wc_last_node = NULL;
     wc_UnLockMutex(&debug_mutex);
+#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */
 }
 
 int wc_SetLoggingHeap(void* h)
@@ -570,6 +580,38 @@ int wc_SetLoggingHeap(void* h)
     return 0;
 }
 
+
+/* frees all nodes in the queue
+ *
+ * id  this is the thread id
+ */
+int wc_ERR_remove_state(void)
+{
+    struct wc_error_queue* current;
+    struct wc_error_queue* next;
+
+    if (wc_LockMutex(&debug_mutex) != 0) {
+        WOLFSSL_MSG("Lock debug mutex failed");
+        return BAD_MUTEX_E;
+    }
+
+    /* free all nodes from error queue */
+    current = (struct wc_error_queue*)wc_errors;
+    while (current != NULL) {
+        next = current->next;
+        XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
+        current = next;
+    }
+
+    wc_errors          = NULL;
+    wc_last_node       = NULL;
+
+    wc_UnLockMutex(&debug_mutex);
+
+    return 0;
+}
+
+
 #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
 /* empties out the error queue into the file */
 void wc_ERR_print_errors_fp(FILE* fp)

+ 10 - 0
wolfcrypt/src/random.c

@@ -301,6 +301,16 @@ static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz)
     return DRBG_SUCCESS;
 }
 
+/* Returns: DRBG_SUCCESS and DRBG_FAILURE or BAD_FUNC_ARG on fail */
+int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy, word32 entropySz)
+{
+    if (rng == NULL || entropy == NULL) {
+        return BAD_FUNC_ARG;
+    }
+
+    return Hash_DRBG_Reseed(rng->drbg, entropy, entropySz);
+}
+
 static INLINE void array_add_one(byte* data, word32 dataSz)
 {
     int i;

+ 33 - 0
wolfcrypt/src/wc_port.c

@@ -461,6 +461,39 @@ int wolfSSL_CryptHwMutexUnLock(void) {
 /* ---------------------------------------------------------------------------*/
 /* Mutex Ports */
 /* ---------------------------------------------------------------------------*/
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+    static mutex_cb*     compat_mutex_cb = NULL;
+
+    /* Function that locks or unlocks a mutex based on the flag passed in.
+     *
+     * flag lock or unlock i.e. CRYPTO_LOCK
+     * type the type of lock to unlock or lock
+     * file name of the file calling
+     * line the line number from file calling
+     */
+    int wc_LockMutex_ex(int flag, int type, const char* file, int line)
+    {
+        if (compat_mutex_cb != NULL) {
+            compat_mutex_cb(flag, type, file, line);
+            return 0;
+        }
+        else {
+            WOLFSSL_MSG("Mutex call back function not set. Call wc_SetMutexCb");
+            return BAD_STATE_E;
+        }
+    }
+
+
+    /* Set the callback function to use for locking/unlocking mutex
+     *
+     * cb callback function to use
+     */
+    int wc_SetMutexCb(mutex_cb* cb)
+    {
+        compat_mutex_cb = cb;
+        return 0;
+    }
+#endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) */
 #ifdef SINGLE_THREADED
 
     int wc_InitMutex(wolfSSL_Mutex* m)

+ 6 - 8
wolfcrypt/test/test.c

@@ -4250,10 +4250,6 @@ int des3_test(void)
     wc_Des3Free(&enc);
     wc_Des3Free(&dec);
 
-#ifdef WOLFSSL_ASYNC_CRYPT
-    wc_Des3AsyncFree(&enc);
-    wc_Des3AsyncFree(&dec);
-#endif
     return 0;
 }
 #endif /* NO_DES */
@@ -11367,6 +11363,7 @@ int openssl_pkey0_test(void)
     byte   in[] = "Everyone gets Friday off.";
     byte   out[256];
     size_t outlen;
+    size_t keySz;
     byte   plain[256];
 #if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048)
     FILE    *keyFile, *keypubFile;
@@ -11431,6 +11428,7 @@ int openssl_pkey0_test(void)
           printf("error with RSA_LoadDer_ex\n");
           return ERR_BASE_PKEY-12;
         }
+        keySz = (size_t)RSA_size(pubRsa);
 
         prvPkey = wolfSSL_PKEY_new();
         pubPkey = wolfSSL_PKEY_new();
@@ -11464,7 +11462,7 @@ int openssl_pkey0_test(void)
         }
         memset(out, 0, sizeof(out));
         ret = EVP_PKEY_encrypt(enc, out, &outlen, in, sizeof(in));
-        if (ret < 0) {
+        if (ret != 1) {
             printf("error encrypting msg\n");
             return ERR_BASE_PKEY-18;
         }
@@ -11472,7 +11470,7 @@ int openssl_pkey0_test(void)
         show("encrypted msg", out, outlen);
 
         memset(plain, 0, sizeof(plain));
-        ret = EVP_PKEY_decrypt(dec, plain, &outlen, out, sizeof(out));
+        ret = EVP_PKEY_decrypt(dec, plain, &outlen, out, keySz);
         if (ret != 1) {
             printf("error decrypting msg\n");
             return ERR_BASE_PKEY-19;
@@ -11508,7 +11506,7 @@ int openssl_pkey0_test(void)
 
         memset(out, 0, sizeof(out));
         ret = EVP_PKEY_encrypt(enc, out, &outlen, in, sizeof(in));
-        if (ret < 0) {
+        if (ret != 1) {
             printf("error encrypting msg\n");
             return ERR_BASE_PKEY-35;
         }
@@ -11516,7 +11514,7 @@ int openssl_pkey0_test(void)
         show("encrypted msg", out, outlen);
 
         memset(plain, 0, sizeof(plain));
-        ret = EVP_PKEY_decrypt(dec, plain, &outlen, out, sizeof(out));
+        ret = EVP_PKEY_decrypt(dec, plain, &outlen, out, keySz);
         if (ret != 1) {
             printf("error decrypting msg\n");
             return ERR_BASE_PKEY-36;

+ 1 - 1
wolfssl/callbacks.h

@@ -24,7 +24,7 @@
 #ifndef WOLFSSL_CALLBACKS_H
 #define WOLFSSL_CALLBACKS_H
 
-#include <sys/time.h>
+#include <wolfssl/wolfcrypt/wc_port.h>
 
 #ifdef __cplusplus
     extern "C" {

+ 38 - 7
wolfssl/internal.h

@@ -108,8 +108,10 @@
 
 #include <wolfssl/wolfcrypt/hash.h>
 
-#ifdef WOLFSSL_CALLBACKS
+#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
     #include <wolfssl/callbacks.h>
+#endif
+#ifdef WOLFSSL_CALLBACKS
     #include <signal.h>
 #endif
 
@@ -1180,9 +1182,15 @@ enum Misc {
 
     PREV_ORDER         = -1,   /* Sequence number is in previous epoch. */
     PEER_ORDER         = 1,    /* Peer sequence number for verify. */
-    CUR_ORDER          = 0     /* Current sequence number. */
+    CUR_ORDER          = 0,    /* Current sequence number. */
+    WRITE_PROTO        = 1,    /* writing a protocol message */
+    READ_PROTO         = 0     /* reading a protocol message */
 };
 
+/* minimum Downgrade Minor version */
+#ifndef WOLFSSL_MIN_DOWNGRADE
+    #define WOLFSSL_MIN_DOWNGRADE TLSv1_MINOR
+#endif
 
 /* Set max implicit IV size for AEAD cipher suites */
 #define AEAD_MAX_IMP_SZ 12
@@ -1304,11 +1312,13 @@ enum states {
     SERVER_CERT_COMPLETE,
     SERVER_KEYEXCHANGE_COMPLETE,
     SERVER_HELLODONE_COMPLETE,
+	SERVER_CHANGECIPHERSPEC_COMPLETE,
     SERVER_FINISHED_COMPLETE,
     SERVER_HELLO_RETRY_REQUEST,
 
     CLIENT_HELLO_COMPLETE,
     CLIENT_KEYEXCHANGE_COMPLETE,
+	CLIENT_CHANGECIPHERSPEC_COMPLETE,
     CLIENT_FINISHED_COMPLETE,
 
     HANDSHAKE_DONE
@@ -1356,6 +1366,7 @@ struct WOLFSSL_BIO_METHOD {
 
 /* wolfSSL BIO type */
 struct WOLFSSL_BIO {
+    WOLFSSL_BUF_MEM* mem_buf;
     WOLFSSL*     ssl;           /* possible associated ssl */
 #ifndef NO_FILESYSTEM
     XFILE        file;
@@ -1372,6 +1383,7 @@ struct WOLFSSL_BIO {
     int         memLen;        /* memory buffer length */
     int         fd;            /* possible file descriptor */
     int         eof;           /* eof flag */
+    int         flags;
     byte        type;          /* method type */
     byte        close;         /* close flag */
 };
@@ -2258,6 +2270,7 @@ struct WOLFSSL_CTX {
 #endif
     Suites*     suites;           /* make dynamic, user may not need/set */
     void*       heap;             /* for user memory overrides */
+    byte        verifyDepth;
     byte        verifyPeer;
     byte        verifyNone;
     byte        failNoCert;
@@ -2305,11 +2318,13 @@ struct WOLFSSL_CTX {
     short       minEccKeySz;      /* minimum ECC key size */
 #endif
 #ifdef OPENSSL_EXTRA
+    byte              sessionCtx[ID_LEN]; /* app session context ID */
     word32            disabledCurves;   /* curves disabled by user */
-    byte              verifyDepth;      /* maximum verification depth */
     unsigned long     mask;             /* store SSL_OP_ flags */
     const unsigned char *alpn_cli_protos;/* ALPN client protocol list */
     unsigned int         alpn_cli_protos_len;
+    byte              sessionCtxSz;
+    CallbackInfoState* CBIS;      /* used to get info about SSL state */
 #endif
     CallbackIORecv CBIORecv;
     CallbackIOSend CBIOSend;
@@ -2346,6 +2361,7 @@ struct WOLFSSL_CTX {
     pem_password_cb* passwd_cb;
     void*           userdata;
     WOLFSSL_X509_STORE x509_store; /* points to ctx->cm */
+    WOLFSSL_X509_STORE* x509_store_pt; /* take ownership of external store */
     byte            readAhead;
     void*           userPRFArg; /* passed to prf callback */
 #endif
@@ -2680,6 +2696,10 @@ struct WOLFSSL_SESSION {
     word16             idLen;                     /* serverID length          */
     byte               serverID[SERVER_ID_LEN];   /* for easier client lookup */
 #endif
+#ifdef OPENSSL_EXTRA
+    byte               sessionCtxSz;              /* sessionCtx length        */
+    byte               sessionCtx[ID_LEN];        /* app specific context id  */
+#endif
 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
     #ifdef WOLFSSL_TLS13
     byte               namedGroup;
@@ -2692,6 +2712,8 @@ struct WOLFSSL_SESSION {
     #ifdef WOLFSSL_EARLY_DATA
     word32             maxEarlyDataSz;
     #endif
+#endif
+#ifdef HAVE_SESSION_TICKET
     byte*              ticket;
     word16             ticketLen;
     byte               staticTicket[SESSION_TICKET_LEN];
@@ -3276,6 +3298,8 @@ struct WOLFSSL {
              /* side that decrements dupCount to zero frees overall structure */
     byte            dupSide;            /* write side or read side */
 #endif
+    CallbackIORecv  CBIORecv;
+    CallbackIOSend  CBIOSend;
 #ifdef WOLFSSL_STATIC_MEMORY
     WOLFSSL_HEAP_HINT heap_hint;
 #endif
@@ -3308,6 +3332,7 @@ struct WOLFSSL {
     word32          timeout;            /* session timeout */
     word32          fragOffset;         /* fragment offset */
     word16          curSize;
+    byte            verifyDepth;
     RecordLayerHeader curRL;
     MsgsReceived    msgsReceived;       /* peer messages received */
     ProtocolVersion version;            /* negotiated version */
@@ -3316,10 +3341,15 @@ struct WOLFSSL {
     Keys            keys;
     Options         options;
 #ifdef OPENSSL_EXTRA
+    CallbackInfoState* CBIS;             /* used to get info about SSL state */
+    int              cbmode;             /* read or write on info callback */
+    int              cbtype;             /* event type in info callback */
     WOLFSSL_BIO*     biord;              /* socket bio read  to free/close */
     WOLFSSL_BIO*     biowr;              /* socket bio write to free/close */
+    byte             sessionCtx[ID_LEN]; /* app session context ID */
     unsigned long    peerVerifyRet;
     byte             readAhead;
+    byte             sessionCtxSz;       /* size of sessionCtx stored */
 #ifdef HAVE_PK_CALLBACKS
     void*            loggingCtx;         /* logging callback argument */
 #endif
@@ -3401,8 +3431,8 @@ struct WOLFSSL {
 #endif /* WOLFSSL_DTLS_DROP_STATS */
 #endif /* WOLFSSL_DTLS */
 #ifdef WOLFSSL_CALLBACKS
-    HandShakeInfo   handShakeInfo;      /* info saved during handshake */
     TimeoutInfo     timeoutInfo;        /* info saved during handshake */
+    HandShakeInfo   handShakeInfo;      /* info saved during handshake */
 #endif
 #ifdef OPENSSL_EXTRA
     SSL_Msg_Cb      protoMsgCb;         /* inspect protocol message callback */
@@ -3575,20 +3605,21 @@ typedef struct EncryptedInfo {
 #endif
 
 
-#ifdef WOLFSSL_CALLBACKS
+#if defined(WOLFSSL_CALLBACKS) || defined(OPENSSL_EXTRA)
     WOLFSSL_LOCAL
     void InitHandShakeInfo(HandShakeInfo*, WOLFSSL*);
     WOLFSSL_LOCAL
     void FinishHandShakeInfo(HandShakeInfo*);
     WOLFSSL_LOCAL
-    void AddPacketName(const char*, HandShakeInfo*);
+    void AddPacketName(WOLFSSL* ssl, const char* name);
 
     WOLFSSL_LOCAL
     void InitTimeoutInfo(TimeoutInfo*);
     WOLFSSL_LOCAL
     void FreeTimeoutInfo(TimeoutInfo*, void*);
     WOLFSSL_LOCAL
-    void AddPacketInfo(const char*, TimeoutInfo*, const byte*, int, void*);
+    void AddPacketInfo(WOLFSSL* ssl, const char* name, int type,
+                               const byte* data, int sz, int write, void* heap);
     WOLFSSL_LOCAL
     void AddLateName(const char*, TimeoutInfo*);
     WOLFSSL_LOCAL

+ 3 - 6
wolfssl/openssl/aes.h

@@ -43,10 +43,7 @@
  * to need the size of the structure. */
 typedef struct WOLFSSL_AES_KEY {
     /* aligned and big enough for Aes from wolfssl/wolfcrypt/aes.h */
-    ALIGN16 void* holder[360 / sizeof(void*)];
-    #ifdef WOLFSSL_ASYNC_CRYPT
-        void* additional[64 / sizeof(void*)]; /* async uses additional memory */
-    #endif
+    ALIGN16 void* holder[(360 + WC_ASYNC_DEV_SIZE)/ sizeof(void*)];
     #ifdef GCM_TABLE
     /* key-based fast multiplication table. */
     ALIGN16 void* M0[4096 / sizeof(void*)];
@@ -54,9 +51,9 @@ typedef struct WOLFSSL_AES_KEY {
 } WOLFSSL_AES_KEY;
 typedef WOLFSSL_AES_KEY AES_KEY;
 
-WOLFSSL_API void wolfSSL_AES_set_encrypt_key
+WOLFSSL_API int wolfSSL_AES_set_encrypt_key
     (const unsigned char *, const int bits, AES_KEY *);
-WOLFSSL_API void wolfSSL_AES_set_decrypt_key
+WOLFSSL_API int wolfSSL_AES_set_decrypt_key
     (const unsigned char *, const int bits, AES_KEY *);
 WOLFSSL_API void wolfSSL_AES_cbc_encrypt
     (const unsigned char *in, unsigned char* out, size_t len,

+ 7 - 0
wolfssl/openssl/bio.h

@@ -32,6 +32,12 @@
     extern "C" {
 #endif
 
+#define BIO_FLAG_BASE64_NO_NL WOLFSSL_BIO_FLAG_BASE64_NO_NL
+#define BIO_FLAG_READ         WOLFSSL_BIO_FLAG_READ
+#define BIO_FLAG_WRITE        WOLFSSL_BIO_FLAG_WRITE
+#define BIO_FLAG_IO_SPECIAL   WOLFSSL_BIO_FLAG_IO_SPECIAL
+#define BIO_FLAG_RETRY        WOLFSSL_BIO_FLAG_RETRY
+
 #define BIO_find_type wolfSSL_BIO_find_type
 #define BIO_next      wolfSSL_BIO_next
 #define BIO_gets      wolfSSL_BIO_gets
@@ -40,6 +46,7 @@
 #define BIO_TYPE_FILE WOLFSSL_BIO_FILE
 #define BIO_TYPE_BIO  WOLFSSL_BIO_BIO
 #define BIO_TYPE_MEM  WOLFSSL_BIO_MEMORY
+#define BIO_TYPE_BASE64 WOLFSSL_BIO_BASE64
 
 
 #ifdef __cplusplus

+ 2 - 0
wolfssl/openssl/bn.h

@@ -95,6 +95,7 @@ WOLFSSL_API int wolfSSL_BN_lshift(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, int);
 WOLFSSL_API int wolfSSL_BN_add_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG);
 WOLFSSL_API int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM*, int);
 WOLFSSL_API int wolfSSL_BN_set_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG);
+WOLFSSL_API unsigned long wolfSSL_BN_get_word(const WOLFSSL_BIGNUM*);
 
 WOLFSSL_API int wolfSSL_BN_add(WOLFSSL_BIGNUM*, WOLFSSL_BIGNUM*,
                                WOLFSSL_BIGNUM*);
@@ -151,6 +152,7 @@ typedef WOLFSSL_BN_GENCB BN_GENCB;
 #define BN_dup  wolfSSL_BN_dup
 #define BN_copy wolfSSL_BN_copy
 
+#define BN_get_word wolfSSL_BN_get_word
 #define BN_set_word wolfSSL_BN_set_word
 
 #define BN_dec2bn wolfSSL_BN_dec2bn

+ 0 - 6
wolfssl/openssl/buffer.h

@@ -30,12 +30,6 @@
     extern "C" {
 #endif
 
-struct WOLFSSL_BUF_MEM {
-    char*  data;
-    size_t length; /* current length */
-    size_t max;    /* maximum length */
-};
-
 
 WOLFSSL_API WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void);
 WOLFSSL_API int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len);

+ 5 - 6
wolfssl/openssl/crypto.h

@@ -36,8 +36,6 @@
 WOLFSSL_API const char*   wolfSSLeay_version(int type);
 WOLFSSL_API unsigned long wolfSSLeay(void);
 
-/* depreciated */
-#define CRYPTO_thread_id() 0
 
 #define CRYPTO_THREADID void
 
@@ -47,11 +45,13 @@ WOLFSSL_API unsigned long wolfSSLeay(void);
 
 #define SSLEAY_VERSION 0x0090600fL
 #define SSLEAY_VERSION_NUMBER SSLEAY_VERSION
+#define CRYPTO_lock wc_LockMutex_ex
 
 /* this function was used to set the default malloc, free, and realloc */
 #define CRYPTO_malloc_init() /* CRYPTO_malloc_init is not needed */
 
-#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
+    defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)
 #define CRYPTO_set_mem_ex_functions      wolfSSL_CRYPTO_set_mem_ex_functions
 #define FIPS_mode                        wolfSSL_FIPS_mode
 #define FIPS_mode_set                    wolfSSL_FIPS_mode_set
@@ -61,9 +61,8 @@ typedef void (CRYPTO_free_func)(void*parent, void*ptr, CRYPTO_EX_DATA *ad, int i
 #define CRYPTO_THREADID_set_callback wolfSSL_THREADID_set_callback
 #define CRYPTO_THREADID_set_numeric wolfSSL_THREADID_set_numeric
 
-#define CRYPTO_lock wc_LockMutex
-#define CRYPTO_r_lock wc_LockMutex
-#define CRYPTO_unlock wc_UnLockMutex
+#define CRYPTO_r_lock wc_LockMutex_ex
+#define CRYPTO_unlock wc_LockMutex_ex
 
 #define CRYPTO_THREAD_lock wc_LockMutex
 #define CRYPTO_THREAD_r_lock wc_LockMutex

+ 1 - 0
wolfssl/openssl/dh.h

@@ -64,6 +64,7 @@ typedef WOLFSSL_DH DH;
 #define DH_size         wolfSSL_DH_size
 #define DH_generate_key wolfSSL_DH_generate_key
 #define DH_compute_key  wolfSSL_DH_compute_key
+#define get_rfc3526_prime_1536 wolfSSL_DH_1536_prime
 
 
 #ifdef __cplusplus

+ 20 - 22
wolfssl/openssl/evp.h

@@ -35,6 +35,9 @@
 #include "prefix_evp.h"
 #endif
 
+#ifndef NO_MD4
+    #include <wolfssl/openssl/md4.h>
+#endif
 #ifndef NO_MD5
     #include <wolfssl/openssl/md5.h>
 #endif
@@ -58,12 +61,15 @@
 #endif
 
 typedef char WOLFSSL_EVP_CIPHER;
-#ifndef WOLFSSL_EVP_TYPE_DEFINED
-typedef struct WOLFSSL_EVP_PKEY WOLFSSL_EVP_PKEY;
+#ifndef WOLFSSL_EVP_TYPE_DEFINED /* guard on redeclaration */
 typedef char   WOLFSSL_EVP_MD;
+typedef struct WOLFSSL_EVP_PKEY WOLFSSL_EVP_PKEY;
 #define WOLFSSL_EVP_TYPE_DEFINED
 #endif
 
+#ifndef NO_MD4
+    WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_md4(void);
+#endif
 #ifndef NO_MD5
     WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void);
 #endif
@@ -93,6 +99,9 @@ WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void);
 
 
 typedef union {
+    #ifndef NO_MD4
+        WOLFSSL_MD4_CTX    md4;
+    #endif
     #ifndef NO_MD5
         WOLFSSL_MD5_CTX    md5;
     #endif
@@ -203,7 +212,6 @@ typedef struct WOLFSSL_EVP_CIPHER_CTX {
     int  lastUsed;
 } WOLFSSL_EVP_CIPHER_CTX;
 
-
 typedef struct  WOLFSSL_EVP_PKEY_CTX {
     WOLFSSL_EVP_PKEY *pkey;
     int op; /* operation */
@@ -266,18 +274,20 @@ WOLFSSL_API int  wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx);
 
 WOLFSSL_API int  wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX*);
 WOLFSSL_API int  wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER*);
+WOLFSSL_API int wolfSSL_EVP_Cipher_key_length(const WOLFSSL_EVP_CIPHER* c);
 
 
 WOLFSSL_API int  wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
                                     const WOLFSSL_EVP_CIPHER* type,
-                                    unsigned char* key, unsigned char* iv,
+                                    const unsigned char* key,
+                                    const unsigned char* iv,
                                     int enc);
 WOLFSSL_API int  wolfSSL_EVP_CipherInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
                                     const WOLFSSL_EVP_CIPHER* type,
                                     WOLFSSL_ENGINE *impl,
-                                    unsigned char* key, unsigned char* iv,
+                                    const unsigned char* key,
+                                    const unsigned char* iv,
                                     int enc);
-#ifdef WOLFSSL_SIGNAL
 WOLFSSL_API int  wolfSSL_EVP_EncryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
                                     const WOLFSSL_EVP_CIPHER* type,
                                     const unsigned char* key,
@@ -296,22 +306,6 @@ WOLFSSL_API int  wolfSSL_EVP_DecryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
                                     WOLFSSL_ENGINE *impl,
                                     const unsigned char* key,
                                     const unsigned char* iv);
-#else
-WOLFSSL_API int  wolfSSL_EVP_EncryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
-                                         const WOLFSSL_EVP_CIPHER* type,
-                                         unsigned char* key, unsigned char* iv);
-WOLFSSL_API int  wolfSSL_EVP_EncryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
-                                            const WOLFSSL_EVP_CIPHER* type,
-                                            WOLFSSL_ENGINE *impl,
-                                            unsigned char* key, unsigned char* iv);
-WOLFSSL_API int  wolfSSL_EVP_DecryptInit(WOLFSSL_EVP_CIPHER_CTX* ctx,
-                                            const WOLFSSL_EVP_CIPHER* type,
-                                            unsigned char* key, unsigned char* iv);
-WOLFSSL_API int  wolfSSL_EVP_DecryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
-                                            const WOLFSSL_EVP_CIPHER* type,
-                                            WOLFSSL_ENGINE *impl,
-                                            unsigned char* key, unsigned char* iv);
-#endif  /* WOLFSSL_SIGNAL */
 WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
                                    unsigned char *out, int *outl,
                                    const unsigned char *in, int inl);
@@ -429,6 +423,9 @@ typedef WOLFSSL_EVP_CIPHER     EVP_CIPHER;
 typedef WOLFSSL_EVP_MD_CTX     EVP_MD_CTX;
 typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX;
 
+#ifndef NO_MD4
+    #define EVP_md4       wolfSSL_EVP_md4
+#endif
 #ifndef NO_MD5
     #define EVP_md5       wolfSSL_EVP_md5
 #endif
@@ -489,6 +486,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX;
 #define EVP_CIPHER_CTX_mode           wolfSSL_EVP_CIPHER_CTX_mode
 
 #define EVP_CIPHER_iv_length          wolfSSL_EVP_CIPHER_iv_length
+#define EVP_CIPHER_key_length         wolfSSL_EVP_Cipher_key_length
 
 #define EVP_CipherInit                wolfSSL_EVP_CipherInit
 #define EVP_CipherInit_ex             wolfSSL_EVP_CipherInit_ex

+ 13 - 7
wolfssl/openssl/hmac.h

@@ -53,9 +53,14 @@ WOLFSSL_API unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md,
 typedef struct WOLFSSL_HMAC_CTX {
     Hmac hmac;
     int  type;
+    word32  save_ipad[WC_HMAC_BLOCK_SIZE  / sizeof(word32)];  /* same block size all*/
+    word32  save_opad[WC_HMAC_BLOCK_SIZE  / sizeof(word32)];
 } WOLFSSL_HMAC_CTX;
 
-WOLFSSL_API int wolfSSL_HMAC_CTX_init(WOLFSSL_HMAC_CTX* ctx);
+
+WOLFSSL_API int wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX* ctx);
+WOLFSSL_API int wolfSSL_HMAC_CTX_copy(WOLFSSL_HMAC_CTX* des,
+                                       WOLFSSL_HMAC_CTX* src);
 WOLFSSL_API int wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key,
                                  int keylen, const EVP_MD* type);
 WOLFSSL_API int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key,
@@ -70,12 +75,13 @@ typedef struct WOLFSSL_HMAC_CTX HMAC_CTX;
 
 #define HMAC(a,b,c,d,e,f,g) wolfSSL_HMAC((a),(b),(c),(d),(e),(f),(g))
 
-#define HMAC_CTX_init    wolfSSL_HMAC_CTX_init
-#define HMAC_Init        wolfSSL_HMAC_Init
-#define HMAC_Init_ex     wolfSSL_HMAC_Init_ex
-#define HMAC_Update      wolfSSL_HMAC_Update
-#define HMAC_Final       wolfSSL_HMAC_Final
-#define HMAC_cleanup     wolfSSL_HMAC_cleanup
+#define HMAC_CTX_init wolfSSL_HMAC_CTX_Init
+#define HMAC_CTX_copy wolfSSL_HMAC_CTX_copy
+#define HMAC_Init_ex  wolfSSL_HMAC_Init_ex
+#define HMAC_Init     wolfSSL_HMAC_Init
+#define HMAC_Update   wolfSSL_HMAC_Update
+#define HMAC_Final    wolfSSL_HMAC_Final
+#define HMAC_cleanup  wolfSSL_HMAC_cleanup
 
 
 #ifdef __cplusplus

+ 62 - 1
wolfssl/openssl/md4.h

@@ -1 +1,62 @@
-/* md4.h for libcurl */
+/* md4.h
+ *
+ * Copyright (C) 2006-2016 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifndef WOLFSSL_MD4_H_
+#define WOLFSSL_MD4_H_
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifndef NO_MD4
+
+#ifdef WOLFSSL_PREFIX
+#include "prefix_md4.h"
+#endif
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+typedef struct WOLFSSL_MD4_CTX {
+    int buffer[32];      /* big enough to hold, check size in Init */
+} WOLFSSL_MD4_CTX;
+
+
+WOLFSSL_API void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX*);
+WOLFSSL_API void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX*, const void*, unsigned long);
+WOLFSSL_API void wolfSSL_MD4_Final(unsigned char*, WOLFSSL_MD4_CTX*);
+
+
+typedef WOLFSSL_MD4_CTX MD4_CTX;
+
+#define MD4_Init   wolfSSL_MD4_Init
+#define MD4_Update wolfSSL_MD4_Update
+#define MD4_Final  wolfSSL_MD4_Final
+
+#ifdef __cplusplus
+    }  /* extern "C" */
+#endif
+
+#endif /* NO_MD4 */
+
+#endif /* WOLFSSL_MD4_H_ */
+

+ 2 - 1
wolfssl/openssl/pem.h

@@ -34,7 +34,8 @@
     extern "C" {
 #endif
 
-#define PEM_write_bio_PrivateKey wolfSSL_PEM_write_bio_PrivateKey
+#define PEM_write_bio_PrivateKey    wolfSSL_PEM_write_bio_PrivateKey
+#define PEM_write_bio_RSAPrivateKey wolfSSL_PEM_write_bio_RSAPrivateKey
 
 /* RSA */
 WOLFSSL_API

+ 1 - 4
wolfssl/openssl/rc4.h

@@ -39,10 +39,7 @@
  * the size of RC4_KEY structures. */
 typedef struct WOLFSSL_RC4_KEY {
     /* big enough for Arc4 from wolfssl/wolfcrypt/arc4.h */
-    unsigned char holder[272];
-    #ifdef WOLFSSL_ASYNC_CRYPT
-        unsigned char additional[64]; /* async uses additional memory */
-    #endif
+    void* holder[(272 + WC_ASYNC_DEV_SIZE) / sizeof(void*)];
 } WOLFSSL_RC4_KEY;
 typedef WOLFSSL_RC4_KEY RC4_KEY;
 

+ 44 - 18
wolfssl/openssl/ssl.h

@@ -91,7 +91,6 @@ typedef WOLFSSL_ASN1_OBJECT BASIC_CONSTRAINTS;
 #define ASN1_UTCTIME         WOLFSSL_ASN1_TIME
 #define ASN1_GENERALIZEDTIME WOLFSSL_ASN1_TIME
 
-typedef WOLFSSL_MD4_CTX        MD4_CTX;
 typedef WOLFSSL_COMP_METHOD    COMP_METHOD;
 typedef WOLFSSL_X509_REVOKED   X509_REVOKED;
 typedef WOLFSSL_X509_OBJECT    X509_OBJECT;
@@ -100,6 +99,14 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
 
 #define CRYPTO_free   XFREE
 #define CRYPTO_malloc XMALLOC
+#define CRYPTO_EX_new  WOLFSSL_CRYPTO_EX_new
+#define CRYPTO_EX_dup  WOLFSSL_CRYPTO_EX_dup
+#define CRYPTO_EX_free WOLFSSL_CRYPTO_EX_free
+
+#define STACK_OF(x) WOLFSSL_STACK
+
+/* this function was used to set the default malloc, free, and realloc */
+#define CRYPTO_malloc_init() /* CRYPTO_malloc_init is not needed */
 
 #define SSL_get_client_random(ssl,out,outSz) \
                                   wolfSSL_get_client_random((ssl),(out),(outSz))
@@ -132,6 +139,7 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
 #define SSLv23_method       wolfSSLv23_method
 #define SSLv3_server_method wolfSSLv3_server_method
 #define SSLv3_client_method wolfSSLv3_client_method
+#define TLSv1_method        wolfTLSv1_method
 #define TLSv1_server_method wolfTLSv1_server_method
 #define TLSv1_client_method wolfTLSv1_client_method
 #define TLSv1_1_server_method wolfTLSv1_1_server_method
@@ -139,6 +147,8 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
 #define TLSv1_2_server_method wolfTLSv1_2_server_method
 #define TLSv1_2_client_method wolfTLSv1_2_client_method
 
+#define X509_FILETYPE_ASN1 SSL_FILETYPE_ASN1
+
 #ifdef WOLFSSL_DTLS
     #define DTLSv1_client_method wolfDTLSv1_client_method
     #define DTLSv1_server_method wolfDTLSv1_server_method
@@ -240,9 +250,9 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
 #define SSLv2_client_method wolfSSLv2_client_method
 #define SSLv2_server_method wolfSSLv2_server_method
 
-#define MD4_Init wolfSSL_MD4_Init
-#define MD4_Update  wolfSSL_MD4_Update
-#define MD4_Final wolfSSL_MD4_Final
+#define MD4_Init   wolfSSL_MD4_Init
+#define MD4_Update wolfSSL_MD4_Update
+#define MD4_Final  wolfSSL_MD4_Final
 
 #define BIO_new      wolfSSL_BIO_new
 #define BIO_free     wolfSSL_BIO_free
@@ -273,8 +283,8 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
 #define BIO_f_base64  wolfSSL_BIO_f_base64
 #define BIO_set_flags wolfSSL_BIO_set_flags
 
-#define OpenSSL_add_all_digests()
-#define OpenSSL_add_all_ciphers()
+#define OpenSSL_add_all_digests()  wolfCrypt_Init()
+#define OpenSSL_add_all_ciphers()  wolfCrypt_Init()
 #define OpenSSL_add_all_algorithms wolfSSL_add_all_algorithms
 #define SSLeay_add_ssl_algorithms  wolfSSL_add_all_algorithms
 #define SSLeay_add_all_algorithms  wolfSSL_add_all_algorithms
@@ -294,7 +304,10 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
 
 #define SSL_get_ex_new_index wolfSSL_get_ex_new_index
 
+/* depreciated */
+#define CRYPTO_thread_id       wolfSSL_thread_id
 #define CRYPTO_set_id_callback wolfSSL_set_id_callback
+
 #define CRYPTO_set_locking_callback wolfSSL_set_locking_callback
 #define CRYPTO_set_dynlock_create_callback wolfSSL_set_dynlock_create_callback
 #define CRYPTO_set_dynlock_lock_callback wolfSSL_set_dynlock_lock_callback
@@ -523,6 +536,7 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
 #define SSL_need_tmp_RSA(ssl)                0
 #define SSL_set_tmp_rsa(ssl,rsa)             1
 /*#endif*/
+
 #define CONF_modules_unload(a)
 
 #define SSL_get_hit wolfSSL_session_reused
@@ -571,6 +585,14 @@ enum {
     NID_anyExtendedKeyUsage = 76,
 };
 
+enum {
+    GEN_DNS   = 0x02, /* ASN_DNS_TYPE */
+    GEN_EMAIL = 0x01, /* ASN_RFC822_TYPE */
+    GEN_URI   = 0x06  /* ASN_URI_TYPE */
+};
+
+#define PEM_write_bio_X509_REQ wolfSSL_PEM_write_bio_X509_REQ
+#define PEM_write_bio_X509_AUX wolfSSL_PEM_write_bio_X509_AUX
 
 #define PEM_read_bio_DHparams wolfSSL_PEM_read_bio_DHparams
 #define PEM_read_bio_DSAparams wolfSSL_PEM_read_bio_DSAparams
@@ -687,7 +709,8 @@ enum {
 #define X509_V_FLAG_USE_CHECK_TIME WOLFSSL_USE_CHECK_TIME
 #define X509_V_FLAG_NO_CHECK_TIME  WOLFSSL_NO_CHECK_TIME
 
-#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX)
+#define SSL3_RANDOM_SIZE                 32 /* same as RAN_LEN in internal.h */
+#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(OPENSSL_EXTRA)
 #include <wolfssl/openssl/asn1.h>
 
 #define SSL2_VERSION                     0x0002
@@ -697,7 +720,6 @@ enum {
 #define SSL23_ST_SR_CLNT_HELLO_A        (0x210|0x2000)
 #define SSL3_ST_SR_CLNT_HELLO_A         (0x110|0x2000)
 #define ASN1_STRFLGS_ESC_MSB             4
-#define X509_V_ERR_CERT_REJECTED         28
 
 #define SSL_MAX_MASTER_KEY_LENGTH        WOLFSSL_MAX_MASTER_KEY_LENGTH
 
@@ -705,6 +727,7 @@ enum {
 #define SSL_alert_type_string_long       wolfSSL_alert_type_string_long
 #define SSL_CIPHER_get_bits              wolfSSL_CIPHER_get_bits
 #define sk_X509_NAME_num                 wolfSSL_sk_X509_NAME_num
+#define sk_GENERAL_NAME_num              wolfSSL_sk_GENERAL_NAME_num
 #define sk_X509_num                      wolfSSL_sk_X509_num
 #define X509_NAME_print_ex               wolfSSL_X509_NAME_print_ex
 #define X509_get0_pubkey_bitstr          wolfSSL_X509_get0_pubkey_bitstr
@@ -719,6 +742,7 @@ enum {
 
 #define sk_X509_NAME_value               wolfSSL_sk_X509_NAME_value
 #define sk_X509_value                    wolfSSL_sk_X509_value
+#define sk_GENERAL_NAME_value            wolfSSL_sk_GENERAL_NAME_value
 #define SSL_SESSION_get_ex_data          wolfSSL_SESSION_get_ex_data
 #define SSL_SESSION_set_ex_data          wolfSSL_SESSION_set_ex_data
 #define SSL_SESSION_get_ex_new_index     wolfSSL_SESSION_get_ex_new_index
@@ -727,7 +751,10 @@ enum {
 typedef WOLFSSL_ASN1_BIT_STRING    ASN1_BIT_STRING;
 #define X509_STORE_get1_certs            wolfSSL_X509_STORE_get1_certs
 #define sk_X509_pop_free                 wolfSSL_sk_X509_pop_free
+#define sk_GENERAL_NAME_pop_free         wolfSSL_sk_GENERAL_NAME_pop_free
+#define GENERAL_NAME_free                NULL
 
+#define SSL3_AL_FATAL                        2
 #define SSL_TLSEXT_ERR_OK                    0
 #define SSL_TLSEXT_ERR_ALERT_FATAL           alert_fatal
 #define SSL_TLSEXT_ERR_NOACK                 alert_warning
@@ -787,9 +814,16 @@ typedef WOLFSSL_ASN1_BIT_STRING    ASN1_BIT_STRING;
 #define SSL_set_msg_callback_arg        wolfSSL_set_msg_callback_arg
 
 
-#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
-    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
+/* Nginx uses this to determine if reached end of certs in file.
+ * PEM_read_bio_X509 is called and the return error is lost.
+ * The error that needs to be detected is: SSL_NO_PEM_HEADER.
+ */
+#define ERR_GET_LIB(l)  (int)((((unsigned long)l)>>24L)&0xffL)
+#define PEM_R_NO_START_LINE     108
+#define ERR_LIB_PEM             9
+#define ERR_LIB_X509            10
 
+#ifdef WOLFSSL_NGINX
 #include <wolfssl/error-ssl.h>
 
 #define OPENSSL_STRING    WOLFSSL_STRING
@@ -818,14 +852,6 @@ typedef WOLFSSL_ASN1_BIT_STRING    ASN1_BIT_STRING;
 #define SSL_R_WRONG_VERSION_NUMBER                 VERSION_ERROR
 #define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC  ENCRYPT_ERROR
 
-/* Nginx uses this to determine if reached end of certs in file.
- * PEM_read_bio_X509 is called and the return error is lost.
- * The error that needs to be detected is: SSL_NO_PEM_HEADER.
- */
-#define ERR_GET_LIB(l)  (int)((((unsigned long)l)>>24L)&0xffL)
-#define PEM_R_NO_START_LINE     108
-#define ERR_LIB_PEM             9
-
 #ifdef HAVE_SESSION_TICKET
 #define SSL_OP_NO_TICKET                  SSL_OP_NO_TICKET
 #define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72

+ 101 - 50
wolfssl/ssl.h

@@ -175,7 +175,6 @@ typedef struct WOLFSSL_ASN1_STRING      WOLFSSL_ASN1_STRING;
 typedef struct WOLFSSL_dynlock_value    WOLFSSL_dynlock_value;
 typedef struct WOLFSSL_DH               WOLFSSL_DH;
 typedef struct WOLFSSL_ASN1_BIT_STRING  WOLFSSL_ASN1_BIT_STRING;
-typedef struct WOLFSSL_BUF_MEM          WOLFSSL_BUF_MEM;
 
 #define WOLFSSL_ASN1_UTCTIME          WOLFSSL_ASN1_TIME
 #define WOLFSSL_ASN1_GENERALIZEDTIME  WOLFSSL_ASN1_TIME
@@ -193,11 +192,28 @@ struct WOLFSSL_ASN1_TIME {
     /* ASN_TIME | LENGTH | date bytes */
 };
 
-#ifndef WOLFSSL_EVP_TYPE_DEFINED
-typedef struct WOLFSSL_EVP_PKEY WOLFSSL_EVP_PKEY;
-typedef char   WOLFSSL_EVP_MD;
-#define WOLFSSL_EVP_TYPE_DEFINED
-#endif
+struct WOLFSSL_ASN1_STRING {
+    int length;
+    int type; /* type of string i.e. CTC_UTF8 */
+    char* data;
+    long flags;
+};
+
+#define WOLFSSL_MAX_SNAME 40
+struct WOLFSSL_ASN1_OBJECT {
+    void*  heap;
+    unsigned char* obj;
+    /* sName is short name i.e sha256 rather than oid (null terminated) */
+    char   sName[WOLFSSL_MAX_SNAME];
+    int    type; /* oid */
+    int    grp;  /* type of OID, i.e. oidCertPolicyType */
+    unsigned int  objSz;
+    unsigned char dynamic; /* if 1 then obj was dynamiclly created, 0 otherwise */
+    struct d { /* derefrenced */
+        WOLFSSL_ASN1_STRING  ia5_internal;
+        WOLFSSL_ASN1_STRING* ia5; /* points to ia5_internal */
+    } d;
+};
 
 struct WOLFSSL_EVP_PKEY {
     void* heap;
@@ -224,11 +240,13 @@ struct WOLFSSL_EVP_PKEY {
 };
 typedef struct WOLFSSL_EVP_PKEY WOLFSSL_PKCS8_PRIV_KEY_INFO;
 
-#define WOLFSSL_EVP_PKEY_DEFAULT EVP_PKEY_RSA /* default key type */
+#ifndef WOLFSSL_EVP_TYPE_DEFINED /* guard on redeclaration */
+typedef struct WOLFSSL_EVP_PKEY     WOLFSSL_EVP_PKEY;
+typedef char   WOLFSSL_EVP_MD;
+#define WOLFSSL_EVP_TYPE_DEFINED
+#endif
 
-typedef struct WOLFSSL_MD4_CTX {
-    int buffer[32];      /* big enough to hold, check size in Init */
-} WOLFSSL_MD4_CTX;
+#define WOLFSSL_EVP_PKEY_DEFAULT EVP_PKEY_RSA /* default key type */
 
 
 enum BIO_TYPE {
@@ -237,9 +255,24 @@ enum BIO_TYPE {
     WOLFSSL_BIO_SSL    = 3,
     WOLFSSL_BIO_MEMORY = 4,
     WOLFSSL_BIO_BIO    = 5,
-    WOLFSSL_BIO_FILE   = 6
+    WOLFSSL_BIO_FILE   = 6,
+    WOLFSSL_BIO_BASE64 = 7
+};
+
+enum BIO_FLAGS {
+    WOLFSSL_BIO_FLAG_BASE64_NO_NL = 0x01,
+    WOLFSSL_BIO_FLAG_READ         = 0x02,
+    WOLFSSL_BIO_FLAG_WRITE        = 0x04,
+    WOLFSSL_BIO_FLAG_IO_SPECIAL   = 0x08,
+    WOLFSSL_BIO_FLAG_RETRY        = 0x10
 };
 
+typedef struct WOLFSSL_BUF_MEM {
+    char*  data;   /* dereferenced */
+    size_t length; /* current length */
+    size_t max;    /* maximum length */
+} WOLFSSL_BUF_MEM;
+
 typedef struct WOLFSSL_COMP_METHOD {
     int type;            /* stunnel dereference */
 } WOLFSSL_COMP_METHOD;
@@ -301,6 +334,7 @@ typedef struct WOLFSSL_BUFFER_INFO {
 typedef struct WOLFSSL_X509_STORE_CTX {
     WOLFSSL_X509_STORE* store;    /* Store full of a CA cert chain */
     WOLFSSL_X509* current_cert;   /* stunnel dereference */
+    WOLFSSL_X509_CHAIN* sesChain; /* pointer to WOLFSSL_SESSION peer chain */
     WOLFSSL_STACK* chain;
 #ifdef OPENSSL_EXTRA
     WOLFSSL_X509_VERIFY_PARAM* param; /* certificate validation parameter */
@@ -309,7 +343,7 @@ typedef struct WOLFSSL_X509_STORE_CTX {
     void* ex_data;               /* external data, for fortress build */
     void* userCtx;               /* user ctx */
     int   error;                 /* current error */
-    int   error_depth;           /* cert depth for this error */
+    int   error_depth;           /* index of cert depth for this error */
     int   discardSessionCerts;   /* so verify callback can flag for discard */
     int   totalCerts;            /* number of peer cert buffers */
     WOLFSSL_BUFFER_INFO* certs;  /* peer certs */
@@ -318,7 +352,9 @@ typedef struct WOLFSSL_X509_STORE_CTX {
 
 typedef char* WOLFSSL_STRING;
 
-/* Valid Alert types from page 16/17 */
+/* Valid Alert types from page 16/17
+ * Add alert string to the function wolfSSL_alert_type_string_long in src/ssl.c
+ */
 enum AlertDescription {
     close_notify                    =   0,
     unexpected_message              =  10,
@@ -382,6 +418,7 @@ WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_client_method_ex(void* heap);
 WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_method(void);
 WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_server_method(void);
 WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_client_method(void);
+WOLFSSL_API WOLFSSL_METHOD* wolfTLSv1_method(void);
 WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_server_method(void);
 WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_client_method(void);
 WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_1_server_method(void);
@@ -449,6 +486,7 @@ WOLFSSL_API int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX*, const char*, in
 
 WOLFSSL_API long wolfSSL_get_verify_depth(WOLFSSL* ssl);
 WOLFSSL_API long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx);
+WOLFSSL_API void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx,int depth);
 WOLFSSL_API int wolfSSL_use_certificate_file(WOLFSSL*, const char*, int);
 WOLFSSL_API int wolfSSL_use_PrivateKey_file(WOLFSSL*, const char*, int);
 WOLFSSL_API int wolfSSL_use_certificate_chain_file(WOLFSSL*, const char *file);
@@ -548,6 +586,24 @@ WOLFSSL_API
 
 typedef int (*VerifyCallback)(int, WOLFSSL_X509_STORE_CTX*);
 typedef int (pem_password_cb)(char*, int, int, void*);
+#ifdef OPENSSL_EXTRA
+typedef void (CallbackInfoState)(const WOLFSSL*, int, int);
+
+typedef struct WOLFSSL_CRYPTO_EX_DATA {
+    WOLFSSL_STACK* data;
+} WOLFSSL_CRYPTO_EX_DATA;
+
+typedef int  (WOLFSSL_CRYPTO_EX_new)(void* p, void* ptr,
+        WOLFSSL_CRYPTO_EX_DATA* a, int idx, long argValue, void* arg);
+typedef int  (WOLFSSL_CRYPTO_EX_dup)(WOLFSSL_CRYPTO_EX_DATA* out,
+        WOLFSSL_CRYPTO_EX_DATA* in, void* inPtr, int idx, long argV, void* arg);
+typedef void (WOLFSSL_CRYPTO_EX_free)(void* p, void* ptr,
+        WOLFSSL_CRYPTO_EX_DATA* a, int idx, long argValue, void* arg);
+
+WOLFSSL_API int  wolfSSL_get_ex_new_index(long argValue, void* arg,
+        WOLFSSL_CRYPTO_EX_new* a, WOLFSSL_CRYPTO_EX_dup* b,
+        WOLFSSL_CRYPTO_EX_free* c);
+#endif
 
 WOLFSSL_API void wolfSSL_CTX_set_verify(WOLFSSL_CTX*, int,
                                       VerifyCallback verify_callback);
@@ -639,6 +695,11 @@ WOLFSSL_API int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk,
                                                             WOLFSSL_X509* x509);
 WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk);
 WOLFSSL_API void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk);
+WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_sk_GENERAL_NAME_value(
+        WOLFSSL_STACK* sk, int i);
+WOLFSSL_API int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk);
+WOLFSSL_API void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk,
+        void f (WOLFSSL_ASN1_OBJECT*));
 WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void);
 WOLFSSL_API void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj);
 WOLFSSL_API int wolfSSL_sk_ASN1_OBJECT_push(WOLF_STACK_OF(WOLFSSL_ASN1_OBJEXT)* sk,
@@ -686,11 +747,6 @@ WOLFSSL_API WOLFSSL_METHOD* wolfSSLv23_client_method(void);
 WOLFSSL_API WOLFSSL_METHOD* wolfSSLv2_client_method(void);
 WOLFSSL_API WOLFSSL_METHOD* wolfSSLv2_server_method(void);
 
-WOLFSSL_API void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX*);
-WOLFSSL_API void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX*, const void*, unsigned long);
-WOLFSSL_API void wolfSSL_MD4_Final(unsigned char*, WOLFSSL_MD4_CTX*);
-
-
 WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD*);
 WOLFSSL_API int  wolfSSL_BIO_free(WOLFSSL_BIO*);
 WOLFSSL_API int  wolfSSL_BIO_free_all(WOLFSSL_BIO*);
@@ -759,8 +815,7 @@ WOLFSSL_API WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void);
 WOLFSSL_API WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void);
 WOLFSSL_API int wolfSSL_COMP_add_compression_method(int, void*);
 
-WOLFSSL_API int wolfSSL_get_ex_new_index(long, void*, void*, void*, void*);
-
+WOLFSSL_API unsigned long wolfSSL_thread_id(void);
 WOLFSSL_API void wolfSSL_set_id_callback(unsigned long (*f)(void));
 WOLFSSL_API void wolfSSL_set_locking_callback(void (*f)(int, int, const char*,
                                                       int));
@@ -806,7 +861,7 @@ WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_type_new(int type);
 WOLFSSL_API void wolfSSL_ASN1_STRING_free(WOLFSSL_ASN1_STRING* asn1);
 WOLFSSL_API int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1,
                                                   const void* data, int dataSz);
-WOLFSSL_API char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING*);
+WOLFSSL_API unsigned char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING*);
 WOLFSSL_API int wolfSSL_ASN1_STRING_length(WOLFSSL_ASN1_STRING*);
 WOLFSSL_API int         wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX*);
 WOLFSSL_API const char* wolfSSL_X509_verify_cert_error_string(long);
@@ -843,8 +898,6 @@ WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL*
 
 WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509*);
 WOLFSSL_API int       wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL*, WOLFSSL_EVP_PKEY*);
-WOLFSSL_API void      wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX*,
-                                                     int);
 WOLFSSL_API void      wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT*);
 WOLFSSL_API WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY_bio(
         WOLFSSL_BIO* bio, WOLFSSL_PKCS8_PRIV_KEY_INFO** pkey);
@@ -871,6 +924,8 @@ WOLFSSL_API WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509*);
 
 WOLFSSL_API int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO*, const WOLFSSL_ASN1_TIME*);
 
+WOLFSSL_API char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* time,
+                                                            char* buf, int len);
 WOLFSSL_API int  wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER*,
                                        const WOLFSSL_ASN1_INTEGER*);
 WOLFSSL_API long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER*);
@@ -889,6 +944,8 @@ WOLFSSL_API void  wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX*,
                                                WOLF_STACK_OF(WOLFSSL_X509_NAME)*);
 WOLFSSL_API void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX*, int);
 WOLFSSL_API int   wolfSSL_get_ex_data_X509_STORE_CTX_idx(void);
+WOLFSSL_API void wolfSSL_X509_STORE_CTX_set_error(
+                                           WOLFSSL_X509_STORE_CTX* ctx, int er);
 WOLFSSL_API void* wolfSSL_get_ex_data(const WOLFSSL*, int);
 
 WOLFSSL_API void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX*,
@@ -903,9 +960,9 @@ WOLFSSL_API void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX*,
 WOLFSSL_API unsigned long wolfSSL_ERR_peek_error(void);
 WOLFSSL_API int           wolfSSL_GET_REASON(int);
 
-WOLFSSL_API char* wolfSSL_alert_type_string_long(int);
-WOLFSSL_API char* wolfSSL_alert_desc_string_long(int);
-WOLFSSL_API char* wolfSSL_state_string_long(const WOLFSSL*);
+WOLFSSL_API const char* wolfSSL_alert_type_string_long(int);
+WOLFSSL_API const char* wolfSSL_alert_desc_string_long(int);
+WOLFSSL_API const char* wolfSSL_state_string_long(const WOLFSSL*);
 
 WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_generate_key(int, unsigned long,
                                                void(*)(int, int, void*), void*);
@@ -1036,6 +1093,7 @@ enum {
 
     SSL_ST_CONNECT = 0x1000,
     SSL_ST_ACCEPT  = 0x2000,
+    SSL_ST_MASK    = 0x0FFF,
 
     SSL_CB_LOOP = 0x01,
     SSL_CB_EXIT = 0x02,
@@ -1050,6 +1108,8 @@ enum {
     SSL_CB_ACCEPT_EXIT = (SSL_ST_ACCEPT | SSL_CB_EXIT),
     SSL_CB_CONNECT_LOOP = (SSL_ST_CONNECT | SSL_CB_LOOP),
     SSL_CB_CONNECT_EXIT = (SSL_ST_CONNECT | SSL_CB_EXIT),
+	SSL_CB_MODE_READ = 1,
+	SSL_CB_MODE_WRITE = 2,
 
     SSL_MODE_ENABLE_PARTIAL_WRITE = 2,
 
@@ -1110,6 +1170,8 @@ enum {
     X509_V_ERR_NO_EXPLICIT_POLICY,
     X509_V_ERR_UNNESTED_RESOURCE,
 
+    X509_R_CERT_ALREADY_IN_HASH_TABLE,
+
     XN_FLAG_SPC_EQ  = (1 << 23),
     XN_FLAG_ONELINE = 0,
     XN_FLAG_RFC2253 = 1,
@@ -1314,7 +1376,7 @@ WOLFSSL_API long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx);
 WOLFSSL_API long wolfSSL_CTX_clear_options(WOLFSSL_CTX*, long);
 
 #ifndef NO_CERTS
-  WOLFSSL_API int  wolfSSL_CTX_check_private_key(WOLFSSL_CTX*);
+  WOLFSSL_API int  wolfSSL_CTX_check_private_key(const WOLFSSL_CTX*);
 #endif /* !NO_CERTS */
 
 WOLFSSL_API void wolfSSL_ERR_free_strings(void);
@@ -2352,11 +2414,6 @@ WOLFSSL_API int wolfSSL_accept_ex(WOLFSSL*, HandShakeCallBack, TimeoutCallBack,
     WOLFSSL_API void wolfSSL_cert_service(void);
 #endif
 
-#if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
-WOLFSSL_API char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* time,
-                                                            char* buf, int len);
-#endif /* WOLFSSL_MYSQL_COMPATIBLE */
-
 #ifdef OPENSSL_EXTRA
 
 enum {
@@ -2462,13 +2519,6 @@ struct WOLFSSL_ASN1_BIT_STRING {
     long flags;
 };
 
-struct WOLFSSL_ASN1_STRING {
-    int length;
-    int type; /* type of string i.e. CTC_UTF8 */
-    char* data;
-    long flags;
-};
-
 
 #include <wolfssl/openssl/asn1.h>
 struct WOLFSSL_X509_NAME_ENTRY {
@@ -2491,7 +2541,6 @@ WOLFSSL_API void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME* name);
 WOLFSSL_API char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x);
 WOLFSSL_API int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name);
 /* These are to be merged shortly */
-WOLFSSL_API void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx,int depth);
 WOLFSSL_API void wolfSSL_set_verify_depth(WOLFSSL *ssl,int depth);
 WOLFSSL_API void* wolfSSL_get_app_data( const WOLFSSL *ssl);
 WOLFSSL_API int wolfSSL_set_app_data(WOLFSSL *ssl, void *arg);
@@ -2524,7 +2573,8 @@ WOLFSSL_API int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 *x);
 #endif /* HAVE_STUNNEL || HAVE_LIGHTY */
 
 
-#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+#if defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
+    defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)
 
 #include <wolfssl/openssl/crypto.h>
 
@@ -2533,9 +2583,10 @@ typedef int (*CallbackSniRecv)(WOLFSSL *ssl, int *ret, void* exArg);
 
 WOLFSSL_API int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
     void *(*r) (void *, size_t, const char *, int), void (*f) (void *));
-    
+
 WOLFSSL_API void wolfSSL_CRYPTO_cleanup_all_ex_data(void);
 
+WOLFSSL_API WOLFSSL_BIGNUM* wolfSSL_DH_1536_prime(WOLFSSL_BIGNUM* bn);
 WOLFSSL_API WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator,
     void (*callback) (int, int, void *), void *cb_arg);
 
@@ -2647,12 +2698,8 @@ typedef void (*SSL_Msg_Cb)(int write_p, int version, int content_type,
 
 WOLFSSL_API int wolfSSL_CTX_set_msg_callback(WOLFSSL_CTX *ctx, SSL_Msg_Cb cb);
 WOLFSSL_API int wolfSSL_set_msg_callback(WOLFSSL *ssl, SSL_Msg_Cb cb);
-WOLFSSL_API void wolfSSL_CTX_set_msg_callback_arg(WOLFSSL_CTX *ctx, void* arg);
-WOLFSSL_API void wolfSSL_set_msg_callback_arg(WOLFSSL *ssl, void* arg);
-
-#endif
-
-#ifdef OPENSSL_EXTRA
+WOLFSSL_API int wolfSSL_CTX_set_msg_callback_arg(WOLFSSL_CTX *ctx, void* arg);
+WOLFSSL_API int wolfSSL_set_msg_callback_arg(WOLFSSL *ssl, void* arg);
 WOLFSSL_API unsigned long wolfSSL_ERR_peek_error_line_data(const char **file,
     int *line, const char **data, int *flags);
 WOLFSSL_API int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx,
@@ -2662,7 +2709,12 @@ WOLFSSL_API void *wolfSSL_OPENSSL_memdup(const void *data,
 WOLFSSL_API void wolfSSL_ERR_load_BIO_strings(void);
 #endif
 
-#if defined WOLFSSL_NGINX || defined WOLFSSL_HAPROXY
+#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
+    defined(OPENSSL_EXTRA)
+WOLFSSL_API void wolfSSL_OPENSSL_config(char *config_name);
+#endif
+
+#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
 /* Not an OpenSSL API. */
 WOLFSSL_LOCAL int wolfSSL_get_ocsp_response(WOLFSSL* ssl, byte** response);
 /* Not an OpenSSL API. */
@@ -2671,7 +2723,6 @@ WOLFSSL_LOCAL char* wolfSSL_get_ocsp_url(WOLFSSL* ssl);
 WOLFSSL_API int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url);
 
 WOLFSSL_API WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl);
-WOLFSSL_API void wolfSSL_OPENSSL_config(char *config_name);
 WOLFSSL_API int wolfSSL_X509_get_ex_new_index(int idx, void *arg, void *a,
     void *b, void *c);
 WOLFSSL_API void *wolfSSL_X509_get_ex_data(WOLFSSL_X509 *x509, int idx);

+ 10 - 2
wolfssl/test.h

@@ -261,6 +261,7 @@
 #define svrCertFile    "certs/server-cert.pem"
 #define svrKeyFile     "certs/server-key.pem"
 #define cliCertFile    "certs/client-cert.pem"
+#define cliCertDerFile "certs/client-cert.der"
 #define cliKeyFile     "certs/client-key.pem"
 #define ntruCertFile   "certs/ntru-cert.pem"
 #define ntruKeyFile    "certs/ntru-key.raw"
@@ -280,6 +281,7 @@
 #define svrCertFile    "./certs/server-cert.pem"
 #define svrKeyFile     "./certs/server-key.pem"
 #define cliCertFile    "./certs/client-cert.pem"
+#define cliCertDerFile "./certs/client-cert.der"
 #define cliKeyFile     "./certs/client-key.pem"
 #define ntruCertFile   "./certs/ntru-cert.pem"
 #define ntruKeyFile    "./certs/ntru-key.raw"
@@ -468,8 +470,14 @@ static INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userdata)
 {
     (void)rw;
     (void)userdata;
-    strncpy(passwd, "yassl123", sz);
-    return 8;
+    if (userdata != NULL) {
+        strncpy(passwd, (char*)userdata, sz);
+        return (int)XSTRLEN((char*)userdata);
+    }
+    else {
+        strncpy(passwd, "yassl123", sz);
+        return 8;
+    }
 }
 
 #endif

+ 9 - 14
wolfssl/wolfcrypt/asn.h

@@ -82,6 +82,7 @@ enum ASN_Tags {
     ASN_RFC822_TYPE       = 0x01,
     ASN_DNS_TYPE          = 0x02,
     ASN_DIR_TYPE          = 0x04,
+    ASN_URI_TYPE          = 0x06, /* the value 6 is from GeneralName OID */
     ASN_GENERALIZED_TIME  = 0x18,
     CRL_EXTENSIONS        = 0xa0,
     ASN_EXTENSIONS        = 0xa3,
@@ -207,7 +208,8 @@ enum Misc_ASN {
     HEADER_ENCRYPTED_KEY_SIZE = 88,/* Extra header size for encrypted key */
     TRAILING_ZERO       = 1,       /* Used for size of zero pad */
     MIN_VERSION_SZ      = 3,       /* Min bytes needed for GetMyVersion */
-#if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+#if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || \
+    defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)
     MAX_TIME_STRING_SZ  = 25,      /* Max length of formatted time string */
 #endif
 };
@@ -407,6 +409,7 @@ typedef struct DNS_entry   DNS_entry;
 
 struct DNS_entry {
     DNS_entry* next;   /* next on DNS list */
+    int        type;   /* i.e. ASN_DNS_TYPE */
     char*      name;   /* actual DNS name */
 };
 
@@ -420,6 +423,7 @@ struct Base_entry {
     byte        type;   /* Name base type (DNS or RFC822) */
 };
 
+#define DOMAIN_COMPONENT_MAX 10
 
 struct DecodedName {
     char*   fullName;
@@ -445,8 +449,10 @@ struct DecodedName {
     int     uidLen;
     int     serialIdx;
     int     serialLen;
-    int     dcIdx;
-    int     dcLen;
+    int     dcIdx[DOMAIN_COMPONENT_MAX];
+    int     dcLen[DOMAIN_COMPONENT_MAX];
+    int     dcNum;
+    int     dcMode;
 };
 
 enum SignatureState {
@@ -662,17 +668,6 @@ struct DecodedCert {
     SignatureCtx sigCtx;
 };
 
-#define WOLFSSL_MAX_SNAME 40
-struct WOLFSSL_ASN1_OBJECT {
-    void*  heap;
-    byte*  obj;
-    /* sName is short name i.e sha256 rather than oid (null terminated) */
-    char   sName[WOLFSSL_MAX_SNAME];
-    int    type; /* oid */
-    word32 objSz;
-    byte   dynamic; /* if 1 then obj was dynamiclly created, 0 otherwise */
-};
-
 
 extern const char* BEGIN_CERT;
 extern const char* END_CERT;

+ 2 - 0
wolfssl/wolfcrypt/hmac.h

@@ -156,6 +156,8 @@ WOLFSSL_API void wc_HmacFree(Hmac*);
 
 WOLFSSL_API int wolfSSL_GetHmacMaxSize(void);
 
+WOLFSSL_LOCAL int _InitHmac(Hmac* hmac, int type, void* heap);
+
 #ifdef HAVE_HKDF
 
 WOLFSSL_API int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz,

+ 1 - 0
wolfssl/wolfcrypt/logging.h

@@ -64,6 +64,7 @@ WOLFSSL_API void wolfSSL_Debugging_OFF(void);
     WOLFSSL_LOCAL int wc_PullErrorNode(const char **file, const char **reason,
                             int *line);
     WOLFSSL_API   int wc_SetLoggingHeap(void* h);
+    WOLFSSL_API   int wc_ERR_remove_state(void);
     #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
         WOLFSSL_API   void wc_ERR_print_errors_fp(FILE* fp);
     #endif

+ 1 - 0
wolfssl/wolfcrypt/md4.h

@@ -33,6 +33,7 @@
 
 /* in bytes */
 enum {
+    MD4             =  9,    /* hash type unique */
     MD4_BLOCK_SIZE  = 64,
     MD4_DIGEST_SIZE = 16,
     MD4_PAD_SIZE    = 56

+ 1 - 1
wolfssl/wolfcrypt/memory.h

@@ -97,7 +97,7 @@ WOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb*,
         #ifndef SESSION_CERTS
             #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,16128
         #else
-            #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,21696
+            #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,21920
         #endif
     #endif
     #ifndef WOLFMEM_DIST

+ 2 - 5
wolfssl/wolfcrypt/random.h

@@ -132,11 +132,6 @@ typedef struct OS_Seed {
     #define WC_RNG_TYPE_DEFINED
 #endif
 
-#ifdef HAVE_HASHDRBG
-    /* Private DRBG state */
-    struct DRBG;
-#endif
-
 /* RNG context */
 struct WC_RNG {
     OS_Seed seed;
@@ -180,6 +175,8 @@ WOLFSSL_API int  wc_FreeRng(WC_RNG*);
 
 
 #ifdef HAVE_HASHDRBG
+    WOLFSSL_LOCAL int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy,
+                                        word32 entropySz);
     WOLFSSL_API int wc_RNG_HealthTest(int reseed,
                                         const byte* entropyA, word32 entropyASz,
                                         const byte* entropyB, word32 entropyBSz,

+ 10 - 1
wolfssl/wolfcrypt/types.h

@@ -327,7 +327,8 @@
         /* snprintf is used in asn.c for GetTimeString, PKCS7 test, and when
            debugging is turned on */
         #ifndef USE_WINDOWS_API
-            #if defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
+            #if defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
+               !defined(NO_STDIO_FILESYSTEM)
                 /* case where stdio is not included else where but is needed for
                  * snprintf */
                 #include <stdio.h>
@@ -353,6 +354,14 @@
         #endif
 	#endif
 
+    #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
+        !defined(NO_STDIO_FILESYSTEM)
+        #ifndef XGETENV
+            #include <stdlib.h>
+            #define XGETENV getenv
+        #endif
+    #endif /* OPENSSL_EXTRA */
+
 	#ifndef CTYPE_USER
 	    #include <ctype.h>
 	    #if defined(HAVE_ECC) || defined(HAVE_OCSP) || \

+ 7 - 0
wolfssl/wolfcrypt/wc_port.h

@@ -195,6 +195,13 @@ WOLFSSL_API wolfSSL_Mutex* wc_InitAndAllocMutex(void);
 WOLFSSL_API int wc_FreeMutex(wolfSSL_Mutex*);
 WOLFSSL_API int wc_LockMutex(wolfSSL_Mutex*);
 WOLFSSL_API int wc_UnLockMutex(wolfSSL_Mutex*);
+#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
+/* dynamiclly set which mutex to use. unlock / lock is controlled by flag */
+typedef void (mutex_cb)(int flag, int type, const char* file, int line);
+
+WOLFSSL_API int wc_LockMutex_ex(int flag, int type, const char* file, int line);
+WOLFSSL_API int wc_SetMutexCb(mutex_cb* cb);
+#endif
 
 /* main crypto initialization function */
 WOLFSSL_API int wolfCrypt_Init(void);

+ 2 - 0
wolfssl/wolfio.h

@@ -279,6 +279,8 @@ WOLFSSL_API  int wolfIO_Recv(SOCKET_T sd, char *buf, int sz, int rdFlags);
 #endif /* USE_WOLFSSL_IO || HAVE_HTTP_CLIENT */
 
 
+WOLFSSL_API int BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx);
+WOLFSSL_API int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx);
 #if defined(USE_WOLFSSL_IO)
     /* default IO callbacks */
     WOLFSSL_API int EmbedReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx);

Vissa filer visades inte eftersom för många filer har ändrats