diff options
Diffstat (limited to 'thirdparty/libwebsockets/lib/tls/mbedtls/wrapper')
23 files changed, 6736 insertions, 0 deletions
| diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl3.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl3.h new file mode 100644 index 0000000000..007b392f3e --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl3.h @@ -0,0 +1,44 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL3_H_ +#define _SSL3_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +# define SSL3_AD_CLOSE_NOTIFY             0 +# define SSL3_AD_UNEXPECTED_MESSAGE      10/* fatal */ +# define SSL3_AD_BAD_RECORD_MAC          20/* fatal */ +# define SSL3_AD_DECOMPRESSION_FAILURE   30/* fatal */ +# define SSL3_AD_HANDSHAKE_FAILURE       40/* fatal */ +# define SSL3_AD_NO_CERTIFICATE          41 +# define SSL3_AD_BAD_CERTIFICATE         42 +# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 +# define SSL3_AD_CERTIFICATE_REVOKED     44 +# define SSL3_AD_CERTIFICATE_EXPIRED     45 +# define SSL3_AD_CERTIFICATE_UNKNOWN     46 +# define SSL3_AD_ILLEGAL_PARAMETER       47/* fatal */ + +# define SSL3_AL_WARNING                  1 +# define SSL3_AL_FATAL                    2 + +#define SSL3_VERSION                 0x0300 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_cert.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_cert.h new file mode 100644 index 0000000000..86cf31ad51 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_cert.h @@ -0,0 +1,55 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL_CERT_H_ +#define _SSL_CERT_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "ssl_types.h" + +/** + * @brief create a certification object include private key object according to input certification + * + * @param ic - input certification point + * + * @return certification object point + */ +CERT *__ssl_cert_new(CERT *ic); + +/** + * @brief create a certification object include private key object + * + * @param none + * + * @return certification object point + */ +CERT* ssl_cert_new(void); + +/** + * @brief free a certification object + * + * @param cert - certification object point + * + * @return none + */ +void ssl_cert_free(CERT *cert); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_code.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_code.h new file mode 100644 index 0000000000..80fdbb20f3 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_code.h @@ -0,0 +1,124 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL_CODE_H_ +#define _SSL_CODE_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "ssl3.h" +#include "tls1.h" +#include "x509_vfy.h" + +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ +# define SSL_SENT_SHUTDOWN       1 +# define SSL_RECEIVED_SHUTDOWN   2 + +# define SSL_VERIFY_NONE                 0x00 +# define SSL_VERIFY_PEER                 0x01 +# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +# define SSL_VERIFY_CLIENT_ONCE          0x04 + +/* + * The following 3 states are kept in ssl->rlayer.rstate when reads fail, you + * should not need these + */ +# define SSL_ST_READ_HEADER                      0xF0 +# define SSL_ST_READ_BODY                        0xF1 +# define SSL_ST_READ_DONE                        0xF2 + +# define SSL_NOTHING            1 +# define SSL_WRITING            2 +# define SSL_READING            3 +# define SSL_X509_LOOKUP        4 +# define SSL_ASYNC_PAUSED       5 +# define SSL_ASYNC_NO_JOBS      6 + + +# define SSL_ERROR_NONE                  0 +# define SSL_ERROR_SSL                   1 +# define SSL_ERROR_WANT_READ             2 +# define SSL_ERROR_WANT_WRITE            3 +# define SSL_ERROR_WANT_X509_LOOKUP      4 +# define SSL_ERROR_SYSCALL               5/* look at error stack/return value/errno */ +# define SSL_ERROR_ZERO_RETURN           6 +# define SSL_ERROR_WANT_CONNECT          7 +# define SSL_ERROR_WANT_ACCEPT           8 +# define SSL_ERROR_WANT_ASYNC            9 +# define SSL_ERROR_WANT_ASYNC_JOB       10 + +/* Message flow states */ +typedef enum { +    /* No handshake in progress */ +    MSG_FLOW_UNINITED, +    /* A permanent error with this connection */ +    MSG_FLOW_ERROR, +    /* We are about to renegotiate */ +    MSG_FLOW_RENEGOTIATE, +    /* We are reading messages */ +    MSG_FLOW_READING, +    /* We are writing messages */ +    MSG_FLOW_WRITING, +    /* Handshake has finished */ +    MSG_FLOW_FINISHED +} MSG_FLOW_STATE; + +/* SSL subsystem states */ +typedef enum { +    TLS_ST_BEFORE, +    TLS_ST_OK, +    DTLS_ST_CR_HELLO_VERIFY_REQUEST, +    TLS_ST_CR_SRVR_HELLO, +    TLS_ST_CR_CERT, +    TLS_ST_CR_CERT_STATUS, +    TLS_ST_CR_KEY_EXCH, +    TLS_ST_CR_CERT_REQ, +    TLS_ST_CR_SRVR_DONE, +    TLS_ST_CR_SESSION_TICKET, +    TLS_ST_CR_CHANGE, +    TLS_ST_CR_FINISHED, +    TLS_ST_CW_CLNT_HELLO, +    TLS_ST_CW_CERT, +    TLS_ST_CW_KEY_EXCH, +    TLS_ST_CW_CERT_VRFY, +    TLS_ST_CW_CHANGE, +    TLS_ST_CW_NEXT_PROTO, +    TLS_ST_CW_FINISHED, +    TLS_ST_SW_HELLO_REQ, +    TLS_ST_SR_CLNT_HELLO, +    DTLS_ST_SW_HELLO_VERIFY_REQUEST, +    TLS_ST_SW_SRVR_HELLO, +    TLS_ST_SW_CERT, +    TLS_ST_SW_KEY_EXCH, +    TLS_ST_SW_CERT_REQ, +    TLS_ST_SW_SRVR_DONE, +    TLS_ST_SR_CERT, +    TLS_ST_SR_KEY_EXCH, +    TLS_ST_SR_CERT_VRFY, +    TLS_ST_SR_NEXT_PROTO, +    TLS_ST_SR_CHANGE, +    TLS_ST_SR_FINISHED, +    TLS_ST_SW_SESSION_TICKET, +    TLS_ST_SW_CERT_STATUS, +    TLS_ST_SW_CHANGE, +    TLS_ST_SW_FINISHED +} OSSL_HANDSHAKE_STATE; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_dbg.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_dbg.h new file mode 100644 index 0000000000..ad32cb92ff --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_dbg.h @@ -0,0 +1,190 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL_DEBUG_H_ +#define _SSL_DEBUG_H_ + +#include "platform/ssl_port.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef CONFIG_OPENSSL_DEBUG_LEVEL +    #define SSL_DEBUG_LEVEL CONFIG_OPENSSL_DEBUG_LEVEL +#else +    #define SSL_DEBUG_LEVEL 0 +#endif + +#define SSL_DEBUG_ON  (SSL_DEBUG_LEVEL + 1) +#define SSL_DEBUG_OFF (SSL_DEBUG_LEVEL - 1) + +#ifdef CONFIG_OPENSSL_DEBUG +    #ifndef SSL_DEBUG_LOG +        #error "SSL_DEBUG_LOG is not defined" +    #endif + +    #ifndef SSL_DEBUG_FL +        #define SSL_DEBUG_FL "\n" +    #endif + +    #define SSL_SHOW_LOCATION()                         \ +        SSL_DEBUG_LOG("SSL assert : %s %d\n",           \ +            __FILE__, __LINE__) + +    #define SSL_DEBUG(level, fmt, ...)                  \ +    {                                                   \ +        if (level > SSL_DEBUG_LEVEL) {                  \ +            SSL_DEBUG_LOG(fmt SSL_DEBUG_FL, ##__VA_ARGS__); \ +        }                                               \ +    } +#else /* CONFIG_OPENSSL_DEBUG */ +    #define SSL_SHOW_LOCATION() + +    #define SSL_DEBUG(level, fmt, ...) +#endif /* CONFIG_OPENSSL_DEBUG */ + +/** + * OpenSSL assert function + * + * if select "CONFIG_OPENSSL_ASSERT_DEBUG", SSL_ASSERT* will show error file name and line + * if select "CONFIG_OPENSSL_ASSERT_EXIT", SSL_ASSERT* will just return error code. + * if select "CONFIG_OPENSSL_ASSERT_DEBUG_EXIT" SSL_ASSERT* will show error file name and line, + * then return error code. + * if select "CONFIG_OPENSSL_ASSERT_DEBUG_BLOCK", SSL_ASSERT* will show error file name and line, + * then block here with "while (1)" + * + * SSL_ASSERT1 may will return "-1", so function's return argument is integer. + * SSL_ASSERT2 may will return "NULL", so function's return argument is a point. + * SSL_ASSERT2 may will return nothing, so function's return argument is "void". + */ +#if defined(CONFIG_OPENSSL_ASSERT_DEBUG) +    #define SSL_ASSERT1(s)                              \ +    {                                                   \ +        if (!(s)) {                                     \ +            SSL_SHOW_LOCATION();                        \ +        }                                               \ +    } + +    #define SSL_ASSERT2(s)                              \ +    {                                                   \ +        if (!(s)) {                                     \ +            SSL_SHOW_LOCATION();                        \ +        }                                               \ +    } + +    #define SSL_ASSERT3(s)                              \ +    {                                                   \ +        if (!(s)) {                                     \ +            SSL_SHOW_LOCATION();                        \ +        }                                               \ +    } +#elif defined(CONFIG_OPENSSL_ASSERT_EXIT) +    #define SSL_ASSERT1(s)                              \ +    {                                                   \ +        if (!(s)) {                                     \ +            return -1;                                  \ +        }                                               \ +    } + +    #define SSL_ASSERT2(s)                              \ +    {                                                   \ +        if (!(s)) {                                     \ +            return NULL;                                \ +        }                                               \ +    } + +    #define SSL_ASSERT3(s)                              \ +    {                                                   \ +        if (!(s)) {                                     \ +            return ;                                    \ +        }                                               \ +    } +#elif defined(CONFIG_OPENSSL_ASSERT_DEBUG_EXIT) +    #define SSL_ASSERT1(s)                              \ +    {                                                   \ +        if (!(s)) {                                     \ +            SSL_SHOW_LOCATION();                        \ +            return -1;                                  \ +        }                                               \ +    } + +    #define SSL_ASSERT2(s)                              \ +    {                                                   \ +        if (!(s)) {                                     \ +            SSL_SHOW_LOCATION();                        \ +            return NULL;                                \ +        }                                               \ +    } + +    #define SSL_ASSERT3(s)                              \ +    {                                                   \ +        if (!(s)) {                                     \ +            SSL_SHOW_LOCATION();                        \ +            return ;                                    \ +        }                                               \ +    } +#elif defined(CONFIG_OPENSSL_ASSERT_DEBUG_BLOCK) +    #define SSL_ASSERT1(s)                              \ +    {                                                   \ +        if (!(s)) {                                     \ +            SSL_SHOW_LOCATION();                        \ +            while (1);                                  \ +        }                                               \ +    } + +    #define SSL_ASSERT2(s)                              \ +    {                                                   \ +        if (!(s)) {                                     \ +            SSL_SHOW_LOCATION();                        \ +            while (1);                                  \ +        }                                               \ +    } + +    #define SSL_ASSERT3(s)                              \ +    {                                                   \ +        if (!(s)) {                                     \ +            SSL_SHOW_LOCATION();                        \ +            while (1);                                  \ +        }                                               \ +    } +#else +    #define SSL_ASSERT1(s) +    #define SSL_ASSERT2(s) +    #define SSL_ASSERT3(s) +#endif + +#define SSL_PLATFORM_DEBUG_LEVEL SSL_DEBUG_OFF +#define SSL_PLATFORM_ERROR_LEVEL SSL_DEBUG_ON + +#define SSL_CERT_DEBUG_LEVEL     SSL_DEBUG_OFF +#define SSL_CERT_ERROR_LEVEL     SSL_DEBUG_ON + +#define SSL_PKEY_DEBUG_LEVEL     SSL_DEBUG_OFF +#define SSL_PKEY_ERROR_LEVEL     SSL_DEBUG_ON + +#define SSL_X509_DEBUG_LEVEL     SSL_DEBUG_OFF +#define SSL_X509_ERROR_LEVEL     SSL_DEBUG_ON + +#define SSL_LIB_DEBUG_LEVEL      SSL_DEBUG_OFF +#define SSL_LIB_ERROR_LEVEL      SSL_DEBUG_ON + +#define SSL_STACK_DEBUG_LEVEL    SSL_DEBUG_OFF +#define SSL_STACK_ERROR_LEVEL    SSL_DEBUG_ON + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_lib.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_lib.h new file mode 100644 index 0000000000..42b2de7501 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_lib.h @@ -0,0 +1,30 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL_LIB_H_ +#define _SSL_LIB_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "ssl_types.h" + + void _ssl_set_alpn_list(const SSL *ssl); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_methods.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_methods.h new file mode 100644 index 0000000000..cd2f8c0533 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_methods.h @@ -0,0 +1,121 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL_METHODS_H_ +#define _SSL_METHODS_H_ + +#include "ssl_types.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * TLS method function implement + */ +#define IMPLEMENT_TLS_METHOD_FUNC(func_name, \ +                    new, free, \ +                    handshake, shutdown, clear, \ +                    read, send, pending, \ +                    set_fd, get_fd, \ +                    set_bufflen, \ +                    get_verify_result, \ +                    get_state) \ +        static const SSL_METHOD_FUNC func_name LOCAL_ATRR = { \ +                new, \ +                free, \ +                handshake, \ +                shutdown, \ +                clear, \ +                read, \ +                send, \ +                pending, \ +                set_fd, \ +                get_fd, \ +                set_bufflen, \ +                get_verify_result, \ +                get_state \ +        }; + +#define IMPLEMENT_TLS_METHOD(ver, mode, fun, func_name) \ +    const SSL_METHOD* func_name(void) { \ +        static const SSL_METHOD func_name##_data LOCAL_ATRR = { \ +                ver, \ +                mode, \ +                &(fun), \ +        }; \ +        return &func_name##_data; \ +    } + +#define IMPLEMENT_SSL_METHOD(ver, mode, fun, func_name) \ +    const SSL_METHOD* func_name(void) { \ +        static const SSL_METHOD func_name##_data LOCAL_ATRR = { \ +                ver, \ +                mode, \ +                &(fun), \ +        }; \ +        return &func_name##_data; \ +    } + +#define IMPLEMENT_X509_METHOD(func_name, \ +                new, \ +                free, \ +                load, \ +                show_info) \ +    const X509_METHOD* func_name(void) { \ +        static const X509_METHOD func_name##_data LOCAL_ATRR = { \ +                new, \ +                free, \ +                load, \ +                show_info \ +        }; \ +        return &func_name##_data; \ +    } + +#define IMPLEMENT_PKEY_METHOD(func_name, \ +                new, \ +                free, \ +                load) \ +    const PKEY_METHOD* func_name(void) { \ +        static const PKEY_METHOD func_name##_data LOCAL_ATRR = { \ +                new, \ +                free, \ +                load \ +        }; \ +        return &func_name##_data; \ +    } + +/** + * @brief get X509 object method + * + * @param none + * + * @return X509 object method point + */ +const X509_METHOD* X509_method(void); + +/** + * @brief get private key object method + * + * @param none + * + * @return private key object method point + */ +const PKEY_METHOD* EVP_PKEY_method(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_pkey.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_pkey.h new file mode 100644 index 0000000000..e790fcc995 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_pkey.h @@ -0,0 +1,86 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL_PKEY_H_ +#define _SSL_PKEY_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "ssl_types.h" + +/** + * @brief create a private key object according to input private key + * + * @param ipk - input private key point + * + * @return new private key object point + */ +EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk); + +/** + * @brief create a private key object + * + * @param none + * + * @return private key object point + */ +EVP_PKEY* EVP_PKEY_new(void); + +/** + * @brief load a character key context into system context. If '*a' is pointed to the + *        private key, then load key into it. Or create a new private key object + * + * @param type   - private key type + * @param a      - a point pointed to a private key point + * @param pp     - a point pointed to the key context memory point + * @param length - key bytes + * + * @return private key object point + */ +EVP_PKEY* d2i_PrivateKey(int type, +                         EVP_PKEY **a, +                         const unsigned char **pp, +                         long length); + +/** + * @brief free a private key object + * + * @param pkey - private key object point + * + * @return none + */ +void EVP_PKEY_free(EVP_PKEY *x); + +/** + * @brief load private key into the SSL + * + * @param type - private key type + * @param ssl  - SSL point + * @param len  - data bytes + * @param d    - data point + * + * @return result + *     0 : failed + *     1 : OK  + */ + int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_stack.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_stack.h new file mode 100644 index 0000000000..7a7051a026 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_stack.h @@ -0,0 +1,52 @@ +#ifndef _SSL_STACK_H_ +#define _SSL_STACK_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "ssl_types.h" + +#define STACK_OF(type)  struct stack_st_##type + +#define SKM_DEFINE_STACK_OF(t1, t2, t3) \ +    STACK_OF(t1); \ +    static ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \ +    { \ +        return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \ +    } \ + +#define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t) + +/** + * @brief create a openssl stack object + * + * @param c - stack function + * + * @return openssl stack object point + */ +OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c); + +/** + * @brief create a NULL function openssl stack object + * + * @param none + * + * @return openssl stack object point + */ +OPENSSL_STACK *OPENSSL_sk_new_null(void); + +/** + * @brief free openssl stack object + * + * @param openssl stack object point + * + * @return none + */ +void OPENSSL_sk_free(OPENSSL_STACK *stack); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_types.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_types.h new file mode 100644 index 0000000000..68ac748a28 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_types.h @@ -0,0 +1,303 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL_TYPES_H_ +#define _SSL_TYPES_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include <lws_config.h> +#if defined(LWS_WITH_ESP32) +#undef MBEDTLS_CONFIG_FILE +#define MBEDTLS_CONFIG_FILE <mbedtls/esp_config.h> +#endif + +#include "ssl_code.h" + +typedef void SSL_CIPHER; + +typedef void X509_STORE_CTX; +typedef void X509_STORE; + +typedef void RSA; + +typedef void STACK; +typedef void BIO; + +#if defined(WIN32) || defined(_WIN32) +#define ossl_inline __inline +#else +#define ossl_inline inline +#endif + +#define SSL_METHOD_CALL(f, s, ...)        s->method->func->ssl_##f(s, ##__VA_ARGS__) +#define X509_METHOD_CALL(f, x, ...)       x->method->x509_##f(x, ##__VA_ARGS__) +#define EVP_PKEY_METHOD_CALL(f, k, ...)   k->method->pkey_##f(k, ##__VA_ARGS__) + +typedef int (*OPENSSL_sk_compfunc)(const void *, const void *); + +struct stack_st; +typedef struct stack_st OPENSSL_STACK; + +struct ssl_method_st; +typedef struct ssl_method_st SSL_METHOD; + +struct ssl_method_func_st; +typedef struct ssl_method_func_st SSL_METHOD_FUNC; + +struct record_layer_st; +typedef struct record_layer_st RECORD_LAYER; + +struct ossl_statem_st; +typedef struct ossl_statem_st OSSL_STATEM; + +struct ssl_session_st; +typedef struct ssl_session_st SSL_SESSION; + +struct ssl_ctx_st; +typedef struct ssl_ctx_st SSL_CTX; + +struct ssl_st; +typedef struct ssl_st SSL; + +struct cert_st; +typedef struct cert_st CERT; + +struct x509_st; +typedef struct x509_st X509; + +struct X509_VERIFY_PARAM_st; +typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; + +struct evp_pkey_st; +typedef struct evp_pkey_st EVP_PKEY; + +struct x509_method_st; +typedef struct x509_method_st X509_METHOD; + +struct pkey_method_st; +typedef struct pkey_method_st PKEY_METHOD; + +struct stack_st { + +    char **data; + +    int num_alloc; + +    OPENSSL_sk_compfunc c; +}; + +struct evp_pkey_st { + +    void *pkey_pm; + +    const PKEY_METHOD *method; +}; + +struct x509_st { + +    /* X509 certification platform private point */ +    void *x509_pm; + +    const X509_METHOD *method; +}; + +struct cert_st { + +    int sec_level; + +    X509 *x509; + +    EVP_PKEY *pkey; + +}; + +struct ossl_statem_st { + +    MSG_FLOW_STATE state; + +    int hand_state; +}; + +struct record_layer_st { + +    int rstate; + +    int read_ahead; +}; + +struct ssl_session_st { + +    long timeout; + +    long time; + +    X509 *peer; +}; + +struct X509_VERIFY_PARAM_st { + +    int depth; + +}; + +typedef int (*next_proto_cb)(SSL *ssl, unsigned char **out, +                             unsigned char *outlen, const unsigned char *in, +                             unsigned int inlen, void *arg); + +struct ssl_ctx_st +{ +    int version; + +    int references; + +    unsigned long options; + +    const SSL_METHOD *method; + +    CERT *cert; + +    X509 *client_CA; + +    const char **alpn_protos; + +    next_proto_cb alpn_cb; + +    int verify_mode; + +    int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx); + +    long session_timeout; + +    int read_ahead; + +    int read_buffer_len; + +    X509_VERIFY_PARAM param; +}; + +struct ssl_st +{ +    /* protocol version(one of SSL3.0, TLS1.0, etc.) */ +    int version; + +    unsigned long options; + +    /* shut things down(0x01 : sent, 0x02 : received) */ +    int shutdown; + +    CERT *cert; + +    X509 *client_CA; + +    SSL_CTX  *ctx; + +    const SSL_METHOD *method; + +    const char **alpn_protos; + +    RECORD_LAYER rlayer; + +    /* where we are */ +    OSSL_STATEM statem; + +    SSL_SESSION *session; + +    int verify_mode; + +    int (*verify_callback) (int ok, X509_STORE_CTX *ctx); + +    int rwstate; +    int interrupted_remaining_write; + +    long verify_result; + +    X509_VERIFY_PARAM param; + +    int err; + +    void (*info_callback) (const SSL *ssl, int type, int val); + +    /* SSL low-level system arch point */ +    void *ssl_pm; +}; + +struct ssl_method_st { +    /* protocol version(one of SSL3.0, TLS1.0, etc.) */ +    int version; + +    /* SSL mode(client(0) , server(1), not known(-1)) */ +    int endpoint; + +    const SSL_METHOD_FUNC *func; +}; + +struct ssl_method_func_st { + +    int (*ssl_new)(SSL *ssl); + +    void (*ssl_free)(SSL *ssl); + +    int (*ssl_handshake)(SSL *ssl); + +    int (*ssl_shutdown)(SSL *ssl); + +    int (*ssl_clear)(SSL *ssl); + +    int (*ssl_read)(SSL *ssl, void *buffer, int len); + +    int (*ssl_send)(SSL *ssl, const void *buffer, int len); + +    int (*ssl_pending)(const SSL *ssl); + +    void (*ssl_set_fd)(SSL *ssl, int fd, int mode); + +    int (*ssl_get_fd)(const SSL *ssl, int mode); + +    void (*ssl_set_bufflen)(SSL *ssl, int len); + +    long (*ssl_get_verify_result)(const SSL *ssl); + +    OSSL_HANDSHAKE_STATE (*ssl_get_state)(const SSL *ssl); +}; + +struct x509_method_st { + +    int (*x509_new)(X509 *x, X509 *m_x); + +    void (*x509_free)(X509 *x); + +    int (*x509_load)(X509 *x, const unsigned char *buf, int len); + +    int (*x509_show_info)(X509 *x); +}; + +struct pkey_method_st { + +    int (*pkey_new)(EVP_PKEY *pkey, EVP_PKEY *m_pkey); + +    void (*pkey_free)(EVP_PKEY *pkey); + +    int (*pkey_load)(EVP_PKEY *pkey, const unsigned char *buf, int len); +}; + +#define OPENSSL_NPN_NEGOTIATED 1 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_x509.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_x509.h new file mode 100644 index 0000000000..7594d064b4 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/ssl_x509.h @@ -0,0 +1,110 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL_X509_H_ +#define _SSL_X509_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "ssl_types.h" +#include "ssl_stack.h" + +DEFINE_STACK_OF(X509_NAME) + +/** + * @brief create a X509 certification object according to input X509 certification + * + * @param ix - input X509 certification point + * + * @return new X509 certification object point + */ +X509* __X509_new(X509 *ix); + +/** + * @brief create a X509 certification object + * + * @param none + * + * @return X509 certification object point + */ +X509* X509_new(void); + +/** + * @brief load a character certification context into system context. If '*cert' is pointed to the + *        certification, then load certification into it. Or create a new X509 certification object + * + * @param cert   - a point pointed to X509 certification + * @param buffer - a point pointed to the certification context memory point + * @param length - certification bytes + * + * @return X509 certification object point + */ +X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); + +/** + * @brief free a X509 certification object + * + * @param x - X509 certification object point + * + * @return none + */ +void X509_free(X509 *x); + +/** + * @brief set SSL context client CA certification + * + * @param ctx - SSL context point + * @param x   - X509 certification point + * + * @return result + *     0 : failed + *     1 : OK + */ +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +/** + * @brief add CA client certification into the SSL + * + * @param ssl - SSL point + * @param x   - X509 certification point + * + * @return result + *     0 : failed + *     1 : OK + */ +int SSL_add_client_CA(SSL *ssl, X509 *x); + +/** + * @brief load certification into the SSL + * + * @param ssl - SSL point + * @param len - data bytes + * @param d   - data point + * + * @return result + *     0 : failed + *     1 : OK + * + */ +int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d); + +const char *X509_verify_cert_error_string(long n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/tls1.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/tls1.h new file mode 100644 index 0000000000..7af1b0157d --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/tls1.h @@ -0,0 +1,58 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _TLS1_H_ +#define _TLS1_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +# define TLS1_AD_DECRYPTION_FAILED       21 +# define TLS1_AD_RECORD_OVERFLOW         22 +# define TLS1_AD_UNKNOWN_CA              48/* fatal */ +# define TLS1_AD_ACCESS_DENIED           49/* fatal */ +# define TLS1_AD_DECODE_ERROR            50/* fatal */ +# define TLS1_AD_DECRYPT_ERROR           51 +# define TLS1_AD_EXPORT_RESTRICTION      60/* fatal */ +# define TLS1_AD_PROTOCOL_VERSION        70/* fatal */ +# define TLS1_AD_INSUFFICIENT_SECURITY   71/* fatal */ +# define TLS1_AD_INTERNAL_ERROR          80/* fatal */ +# define TLS1_AD_INAPPROPRIATE_FALLBACK  86/* fatal */ +# define TLS1_AD_USER_CANCELLED          90 +# define TLS1_AD_NO_RENEGOTIATION        100 +/* codes 110-114 are from RFC3546 */ +# define TLS1_AD_UNSUPPORTED_EXTENSION   110 +# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 +# define TLS1_AD_UNRECOGNIZED_NAME       112 +# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 +# define TLS1_AD_UNKNOWN_PSK_IDENTITY    115/* fatal */ +# define TLS1_AD_NO_APPLICATION_PROTOCOL 120 /* fatal */ + +/* Special value for method supporting multiple versions */ +#define TLS_ANY_VERSION                 0x10000 + +#define TLS1_VERSION                    0x0301 +#define TLS1_1_VERSION                  0x0302 +#define TLS1_2_VERSION                  0x0303 + +#define SSL_TLSEXT_ERR_OK 0 +#define SSL_TLSEXT_ERR_NOACK 3 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/x509_vfy.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/x509_vfy.h new file mode 100644 index 0000000000..26bf6c88a8 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/internal/x509_vfy.h @@ -0,0 +1,116 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _X509_VFY_H_ +#define _X509_VFY_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define         X509_V_OK                                       0 +#define         X509_V_ERR_UNSPECIFIED                          1 +#define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT            2 +#define         X509_V_ERR_UNABLE_TO_GET_CRL                    3 +#define         X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE     4 +#define         X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE      5 +#define         X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY   6 +#define         X509_V_ERR_CERT_SIGNATURE_FAILURE               7 +#define         X509_V_ERR_CRL_SIGNATURE_FAILURE                8 +#define         X509_V_ERR_CERT_NOT_YET_VALID                   9 +#define         X509_V_ERR_CERT_HAS_EXPIRED                     10 +#define         X509_V_ERR_CRL_NOT_YET_VALID                    11 +#define         X509_V_ERR_CRL_HAS_EXPIRED                      12 +#define         X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD       13 +#define         X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD        14 +#define         X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD       15 +#define         X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD       16 +#define         X509_V_ERR_OUT_OF_MEM                           17 +#define         X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT          18 +#define         X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN            19 +#define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY    20 +#define         X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE      21 +#define         X509_V_ERR_CERT_CHAIN_TOO_LONG                  22 +#define         X509_V_ERR_CERT_REVOKED                         23 +#define         X509_V_ERR_INVALID_CA                           24 +#define         X509_V_ERR_PATH_LENGTH_EXCEEDED                 25 +#define         X509_V_ERR_INVALID_PURPOSE                      26 +#define         X509_V_ERR_CERT_UNTRUSTED                       27 +#define         X509_V_ERR_CERT_REJECTED                        28 +/* These are 'informational' when looking for issuer cert */ +#define         X509_V_ERR_SUBJECT_ISSUER_MISMATCH              29 +#define         X509_V_ERR_AKID_SKID_MISMATCH                   30 +#define         X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH          31 +#define         X509_V_ERR_KEYUSAGE_NO_CERTSIGN                 32 +#define         X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER             33 +#define         X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION         34 +#define         X509_V_ERR_KEYUSAGE_NO_CRL_SIGN                 35 +#define         X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION     36 +#define         X509_V_ERR_INVALID_NON_CA                       37 +#define         X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED           38 +#define         X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE        39 +#define         X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED       40 +#define         X509_V_ERR_INVALID_EXTENSION                    41 +#define         X509_V_ERR_INVALID_POLICY_EXTENSION             42 +#define         X509_V_ERR_NO_EXPLICIT_POLICY                   43 +#define         X509_V_ERR_DIFFERENT_CRL_SCOPE                  44 +#define         X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE        45 +#define         X509_V_ERR_UNNESTED_RESOURCE                    46 +#define         X509_V_ERR_PERMITTED_VIOLATION                  47 +#define         X509_V_ERR_EXCLUDED_VIOLATION                   48 +#define         X509_V_ERR_SUBTREE_MINMAX                       49 +/* The application is not happy */ +#define         X509_V_ERR_APPLICATION_VERIFICATION             50 +#define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE          51 +#define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX        52 +#define         X509_V_ERR_UNSUPPORTED_NAME_SYNTAX              53 +#define         X509_V_ERR_CRL_PATH_VALIDATION_ERROR            54 +/* Another issuer check debug option */ +#define         X509_V_ERR_PATH_LOOP                            55 +/* Suite B mode algorithm violation */ +#define         X509_V_ERR_SUITE_B_INVALID_VERSION              56 +#define         X509_V_ERR_SUITE_B_INVALID_ALGORITHM            57 +#define         X509_V_ERR_SUITE_B_INVALID_CURVE                58 +#define         X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM  59 +#define         X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED              60 +#define         X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 +/* Host, email and IP check errors */ +#define         X509_V_ERR_HOSTNAME_MISMATCH                    62 +#define         X509_V_ERR_EMAIL_MISMATCH                       63 +#define         X509_V_ERR_IP_ADDRESS_MISMATCH                  64 +/* DANE TLSA errors */ +#define         X509_V_ERR_DANE_NO_MATCH                        65 +/* security level errors */ +#define         X509_V_ERR_EE_KEY_TOO_SMALL                     66 +#define         X509_V_ERR_CA_KEY_TOO_SMALL                     67 +#define         X509_V_ERR_CA_MD_TOO_WEAK                       68 +/* Caller error */ +#define         X509_V_ERR_INVALID_CALL                         69 +/* Issuer lookup error */ +#define         X509_V_ERR_STORE_LOOKUP                         70 +/* Certificate transparency */ +#define         X509_V_ERR_NO_VALID_SCTS                        71 + +#define         X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION         72 + +typedef void X509_STORE_CTX; +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/openssl/ssl.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/openssl/ssl.h new file mode 100755 index 0000000000..e2b74fc6af --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/openssl/ssl.h @@ -0,0 +1,1833 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL_H_ +#define _SSL_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include <stdlib.h> +#include "internal/ssl_x509.h" +#include "internal/ssl_pkey.h" + +/* +{ +*/ + +#define SSL_CB_ALERT 0x4000 + +#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT		(1 << 0) +#define X509_CHECK_FLAG_NO_WILDCARDS			(1 << 1) +#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS		(1 << 2) +#define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS		(1 << 3) +#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS		(1 << 4) + + mbedtls_x509_crt * + ssl_ctx_get_mbedtls_x509_crt(SSL_CTX *ssl_ctx); + + mbedtls_x509_crt * + ssl_get_peer_mbedtls_x509_crt(SSL *ssl); + + int SSL_set_sni_callback(SSL *ssl, int(*cb)(void *, mbedtls_ssl_context *, + 				const unsigned char *, size_t), void *param); + + void SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); + + int SSL_CTX_add_client_CA_ASN1(SSL_CTX *ssl, int len, +                 const unsigned char *d); + + SSL *SSL_SSL_from_mbedtls_ssl_context(mbedtls_ssl_context *msc); + +/** + * @brief create a SSL context + * + * @param method - the SSL context method point + * + * @return the context point + */ +SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); + +/** + * @brief free a SSL context + * + * @param method - the SSL context point + * + * @return none + */ +void SSL_CTX_free(SSL_CTX *ctx); + +/** + * @brief create a SSL + * + * @param ctx - the SSL context point + * + * @return the SSL point + */ +SSL* SSL_new(SSL_CTX *ctx); + +/** + * @brief free the SSL + * + * @param ssl - the SSL point + * + * @return none + */ +void SSL_free(SSL *ssl); + +/** + * @brief connect to the remote SSL server + * + * @param ssl - the SSL point + * + * @return result + *     1 : OK + *    -1 : failed + */ +int SSL_connect(SSL *ssl); + +/** + * @brief accept the remote connection + * + * @param ssl - the SSL point + * + * @return result + *     1 : OK + *    -1 : failed + */ +int SSL_accept(SSL *ssl); + +/** + * @brief read data from to remote + * + * @param ssl    - the SSL point which has been connected + * @param buffer - the received data buffer point + * @param len    - the received data length + * + * @return result + *     > 0 : OK, and return received data bytes + *     = 0 : connection is closed + *     < 0 : an error catch + */ +int SSL_read(SSL *ssl, void *buffer, int len); + +/** + * @brief send the data to remote + * + * @param ssl    - the SSL point which has been connected + * @param buffer - the send data buffer point + * @param len    - the send data length + * + * @return result + *     > 0 : OK, and return sent data bytes + *     = 0 : connection is closed + *     < 0 : an error catch + */ +int SSL_write(SSL *ssl, const void *buffer, int len); + +/** + * @brief get the verifying result of the SSL certification + * + * @param ssl - the SSL point + * + * @return the result of verifying + */ +long SSL_get_verify_result(const SSL *ssl); + +/** + * @brief shutdown the connection + * + * @param ssl - the SSL point + * + * @return result + *     1 : OK + *     0 : shutdown is not finished + *    -1 : an error catch + */ +int SSL_shutdown(SSL *ssl); + +/** + * @brief bind the socket file description into the SSL + * + * @param ssl - the SSL point + * @param fd  - socket handle + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_set_fd(SSL *ssl, int fd); + +/** + * @brief These functions load the private key into the SSL_CTX or SSL object + * + * @param ctx  - the SSL context point + * @param pkey - private key object point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); + +/** + * @brief These functions load the certification into the SSL_CTX or SSL object + * + * @param ctx  - the SSL context point + * @param pkey - certification object point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the SSLV2.3 version SSL context client method + */ +const SSL_METHOD* SSLv23_client_method(void); + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the TLSV1.0 version SSL context client method + */ +const SSL_METHOD* TLSv1_client_method(void); + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the SSLV1.0 version SSL context client method + */ +const SSL_METHOD* SSLv3_client_method(void); + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the TLSV1.1 version SSL context client method + */ +const SSL_METHOD* TLSv1_1_client_method(void); + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the TLSV1.2 version SSL context client method + */ +const SSL_METHOD* TLSv1_2_client_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLS any version SSL context client method + */ +const SSL_METHOD* TLS_client_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the SSLV2.3 version SSL context server method + */ +const SSL_METHOD* SSLv23_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLSV1.1 version SSL context server method + */ +const SSL_METHOD* TLSv1_1_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLSV1.2 version SSL context server method + */ +const SSL_METHOD* TLSv1_2_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLSV1.0 version SSL context server method + */ +const SSL_METHOD* TLSv1_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the SSLV3.0 version SSL context server method + */ +const SSL_METHOD* SSLv3_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLS any version SSL context server method + */ +const SSL_METHOD* TLS_server_method(void); + + +/** + * @brief set the SSL context ALPN select callback function + * + * @param ctx - SSL context point + * @param cb  - ALPN select callback function + * @param arg - ALPN select callback function entry private data point + * + * @return none + */ +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, +                                int (*cb) (SSL *ssl, +                                           const unsigned char **out, +                                           unsigned char *outlen, +                                           const unsigned char *in, +                                           unsigned int inlen, +                                           void *arg), +                                void *arg); + +void SSL_set_alpn_select_cb(SSL *ssl, void *arg); + +/** + * @brief set the SSL context ALPN select protocol + * + * @param ctx        - SSL context point + * @param protos     - ALPN protocol name + * @param protos_len - ALPN protocol name bytes + * + * @return result + *     0 : OK + *     1 : failed + */ +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, unsigned int protos_len); + +/** + * @brief set the SSL context next ALPN select callback function + * + * @param ctx - SSL context point + * @param cb  - ALPN select callback function + * @param arg - ALPN select callback function entry private data point + * + * @return none + */ +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, +                                      int (*cb) (SSL *ssl, +                                                 unsigned char **out, +                                                 unsigned char *outlen, +                                                 const unsigned char *in, +                                                 unsigned int inlen, +                                                 void *arg), +                                      void *arg); + +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, +                             unsigned int *len); + +void _ssl_set_alpn_list(const SSL *ssl); + +/** + * @brief get SSL error code + * + * @param ssl       - SSL point + * @param ret_code  - SSL return code + * + * @return SSL error number + */ +int SSL_get_error(const SSL *ssl, int ret_code); + +/** + * @brief clear the SSL error code + * + * @param none + * + * @return none + */ +void ERR_clear_error(void); + +/** + * @brief get the current SSL error code + * + * @param none + * + * @return current SSL error number + */ +int ERR_get_error(void); + +/** + * @brief register the SSL error strings + * + * @param none + * + * @return none + */ +void ERR_load_SSL_strings(void); + +/** + * @brief initialize the SSL library + * + * @param none + * + * @return none + */ +void SSL_library_init(void); + +/** + * @brief generates a human-readable string representing the error code e + *        and store it into the "ret" point memory + * + * @param e   - error code + * @param ret - memory point to store the string + * + * @return the result string point + */ +char *ERR_error_string(unsigned long e, char *ret); + +/** + * @brief add the SSL context option + * + * @param ctx - SSL context point + * @param opt - new SSL context option + * + * @return the SSL context option + */ +unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt); + +/** + * @brief add the SSL context mode + * + * @param ctx - SSL context point + * @param mod - new SSL context mod + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_set_mode(SSL_CTX *ctx, int mod); + +/* +} +*/ + +/** + * @brief perform the SSL handshake + * + * @param ssl - SSL point + * + * @return result + *     1 : OK + *     0 : failed + *    -1 : a error catch + */ +int SSL_do_handshake(SSL *ssl); + +/** + * @brief get the SSL current version + * + * @param ssl - SSL point + * + * @return the version string + */ +const char *SSL_get_version(const SSL *ssl); + +/** + * @brief set  the SSL context version + * + * @param ctx  - SSL context point + * @param meth - SSL method point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + +/** + * @brief get the bytes numbers which are to be read + * + * @param ssl  - SSL point + * + * @return bytes number + */ +int SSL_pending(const SSL *ssl); + +/** + * @brief check if SSL want nothing + * + * @param ssl - SSL point + * + * @return result + *     0 : false + *     1 : true + */ +int SSL_want_nothing(const SSL *ssl); + +/** + * @brief check if SSL want to read + * + * @param ssl - SSL point + * + * @return result + *     0 : false + *     1 : true + */ +int SSL_want_read(const SSL *ssl); + +/** + * @brief check if SSL want to write + * + * @param ssl - SSL point + * + * @return result + *     0 : false + *     1 : true + */ +int SSL_want_write(const SSL *ssl); + +/** + * @brief get the SSL context current method + * + * @param ctx - SSL context point + * + * @return the SSL context current method + */ +const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); + +/** + * @brief get the SSL current method + * + * @param ssl - SSL point + * + * @return the SSL current method + */ +const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); + +/** + * @brief set the SSL method + * + * @param ssl  - SSL point + * @param meth - SSL method point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method); + +/** + * @brief add CA client certification into the SSL + * + * @param ssl - SSL point + * @param x   - CA certification point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_add_client_CA(SSL *ssl, X509 *x); + +/** + * @brief add CA client certification into the SSL context + * + * @param ctx - SSL context point + * @param x   - CA certification point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +/** + * @brief set the SSL CA certification list + * + * @param ssl       - SSL point + * @param name_list - CA certification list + * + * @return none + */ +void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list); + +/** + * @brief set the SSL context CA certification list + * + * @param ctx       - SSL context point + * @param name_list - CA certification list + * + * @return none + */ +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); + +/** + * @briefget the SSL CA certification list + * + * @param ssl - SSL point + * + * @return CA certification list + */ +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl); + +/** + * @brief get the SSL context CA certification list + * + * @param ctx - SSL context point + * + * @return CA certification list + */ +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); + +/** + * @brief get the SSL certification point + * + * @param ssl - SSL point + * + * @return SSL certification point + */ +X509 *SSL_get_certificate(const SSL *ssl); + +/** + * @brief get the SSL private key point + * + * @param ssl - SSL point + * + * @return SSL private key point + */ +EVP_PKEY *SSL_get_privatekey(const SSL *ssl); + +/** + * @brief set the SSL information callback function + * + * @param ssl - SSL point + * @param cb  - information callback function + * + * @return none + */ +void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)); + +/** + * @brief get the SSL state + * + * @param ssl - SSL point + * + * @return SSL state + */ +OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); + +/** + * @brief set the SSL context read buffer length + * + * @param ctx - SSL context point + * @param len - read buffer length + * + * @return none + */ +void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); + +/** + * @brief set the SSL read buffer length + * + * @param ssl - SSL point + * @param len - read buffer length + * + * @return none + */ +void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); + +/** + * @brief set the SSL security level + * + * @param ssl   - SSL point + * @param level - security level + * + * @return none + */ +void SSL_set_security_level(SSL *ssl, int level); + +/** + * @brief get the SSL security level + * + * @param ssl - SSL point + * + * @return security level + */ +int SSL_get_security_level(const SSL *ssl); + +/** + * @brief get the SSL verifying mode of the SSL context + * + * @param ctx - SSL context point + * + * @return verifying mode + */ +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); + +/** + * @brief get the SSL verifying depth of the SSL context + * + * @param ctx - SSL context point + * + * @return verifying depth + */ +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); + +/** + * @brief set the SSL context verifying of the SSL context + * + * @param ctx             - SSL context point + * @param mode            - verifying mode + * @param verify_callback - verifying callback function + * + * @return none + */ +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); + +/** + * @brief set the SSL verifying of the SSL context + * + * @param ctx             - SSL point + * @param mode            - verifying mode + * @param verify_callback - verifying callback function + * + * @return none + */ +void SSL_set_verify(SSL *s, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); + +/** + * @brief set the SSL verify depth of the SSL context + * + * @param ctx   - SSL context point + * @param depth - verifying depth + * + * @return none + */ +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); + +/** + * @brief certification verifying callback function + * + * @param preverify_ok - verifying result + * @param x509_ctx     - X509 certification point + * + * @return verifying result + */ +int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); + +/** + * @brief set the session timeout time + * + * @param ctx - SSL context point + * @param t   - new session timeout time + * + * @return old session timeout time + */ +long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); + +/** + * @brief get the session timeout time + * + * @param ctx - SSL context point + * + * @return current session timeout time + */ +long SSL_CTX_get_timeout(const SSL_CTX *ctx); + +/** + * @brief set the SSL context cipher through the list string + * + * @param ctx - SSL context point + * @param str - cipher controller list string + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); + +/** + * @brief set the SSL cipher through the list string + * + * @param ssl - SSL point + * @param str - cipher controller list string + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_set_cipher_list(SSL *ssl, const char *str); + +/** + * @brief get the SSL cipher list string + * + * @param ssl - SSL point + * + * @return cipher controller list string + */ +const char *SSL_get_cipher_list(const SSL *ssl, int n); + +/** + * @brief get the SSL cipher + * + * @param ssl - SSL point + * + * @return current cipher + */ +const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl); + +/** + * @brief get the SSL cipher string + * + * @param ssl - SSL point + * + * @return cipher string + */ +const char *SSL_get_cipher(const SSL *ssl); + +/** + * @brief get the SSL context object X509 certification storage + * + * @param ctx - SSL context point + * + * @return x509 certification storage + */ +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); + +/** + * @brief set the SSL context object X509 certification store + * + * @param ctx   - SSL context point + * @param store - X509 certification store + * + * @return none + */ +void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store); + +/** + * @brief get the SSL specifical statement + * + * @param ssl - SSL point + * + * @return specifical statement + */ +int SSL_want(const SSL *ssl); + +/** + * @brief check if the SSL is SSL_X509_LOOKUP state + * + * @param ssl - SSL point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_want_x509_lookup(const SSL *ssl); + +/** + * @brief reset the SSL + * + * @param ssl - SSL point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_clear(SSL *ssl); + +/** + * @brief get the socket handle of the SSL + * + * @param ssl - SSL point + * + * @return result + *     >= 0 : yes, and return socket handle + *      < 0 : a error catch + */ +int SSL_get_fd(const SSL *ssl); + +/** + * @brief get the read only socket handle of the SSL + * + * @param ssl - SSL point + * + * @return result + *     >= 0 : yes, and return socket handle + *      < 0 : a error catch + */ +int SSL_get_rfd(const SSL *ssl); + +/** + * @brief get the write only socket handle of the SSL + * + * @param ssl - SSL point + * + * @return result + *     >= 0 : yes, and return socket handle + *      < 0 : a error catch + */ +int SSL_get_wfd(const SSL *ssl); + +/** + * @brief set the SSL if we can read as many as data + * + * @param ssl - SSL point + * @param yes - enable the function + * + * @return none + */ +void SSL_set_read_ahead(SSL *s, int yes); + +/** + * @brief set the SSL context if we can read as many as data + * + * @param ctx - SSL context point + * @param yes - enbale the function + * + * @return none + */ +void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes); + +/** + * @brief get the SSL ahead signal if we can read as many as data + * + * @param ssl - SSL point + * + * @return SSL context ahead signal + */ +int SSL_get_read_ahead(const SSL *ssl); + +/** + * @brief get the SSL context ahead signal if we can read as many as data + * + * @param ctx - SSL context point + * + * @return SSL context ahead signal + */ +long SSL_CTX_get_read_ahead(SSL_CTX *ctx); + +/** + * @brief check if some data can be read + * + * @param ssl - SSL point + * + * @return + *         1 : there are bytes to be read + *         0 : no data + */ +int SSL_has_pending(const SSL *ssl); + +/** + * @brief load the X509 certification into SSL context + * + * @param ctx - SSL context point + * @param x   - X509 certification point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);//loads the certificate x into ctx + +/** + * @brief load the ASN1 certification into SSL context + * + * @param ctx - SSL context point + * @param len - certification length + * @param d   - data point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); + +/** + * @brief load the certification file into SSL context + * + * @param ctx  - SSL context point + * @param file - certification file name + * @param type - certification encoding type + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); + +/** + * @brief load the certification chain file into SSL context + * + * @param ctx  - SSL context point + * @param file - certification chain file name + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); + + +/** + * @brief load the ASN1 private key into SSL context + * + * @param ctx - SSL context point + * @param d   - data point + * @param len - private key length + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d,  long len);//adds the private key of type pk stored at memory location d (length len) to ctx + +/** + * @brief load the private key file into SSL context + * + * @param ctx  - SSL context point + * @param file - private key file name + * @param type - private key encoding type + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); + +/** + * @brief load the RSA private key into SSL context + * + * @param ctx - SSL context point + * @param x   - RSA private key point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); + +/** + * @brief load the RSA ASN1 private key into SSL context + * + * @param ctx - SSL context point + * @param d   - data point + * @param len - RSA private key length + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); + +/** + * @brief load the RSA private key file into SSL context + * + * @param ctx  - SSL context point + * @param file - RSA private key file name + * @param type - private key encoding type + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); + + +/** + * @brief check if the private key and certification is matched + * + * @param ctx  - SSL context point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_check_private_key(const SSL_CTX *ctx); + +/** + * @brief set the SSL context server information + * + * @param ctx               - SSL context point + * @param serverinfo        - server information string + * @param serverinfo_length - server information length + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, size_t serverinfo_length); + +/** + * @brief load  the SSL context server infomation file into SSL context + * + * @param ctx  - SSL context point + * @param file - server information file + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); + +/** + * @brief SSL select next function + * + * @param out        - point of output data point + * @param outlen     - output data length + * @param in         - input data + * @param inlen      - input data length + * @param client     - client data point + * @param client_len -client data length + * + * @return NPN state + *         OPENSSL_NPN_UNSUPPORTED : not support + *         OPENSSL_NPN_NEGOTIATED  : negotiated + *         OPENSSL_NPN_NO_OVERLAP  : no overlap + */ +int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, +                          const unsigned char *in, unsigned int inlen, +                          const unsigned char *client, unsigned int client_len); + +/** + * @brief load the extra certification chain into the SSL context + * + * @param ctx  - SSL context point + * @param x509 - X509 certification + * + * @return result + *     1 : OK + *     0 : failed + */ +long SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *); + +/** + * @brief control the SSL context + * + * @param ctx  - SSL context point + * @param cmd  - command + * @param larg - parameter length + * @param parg - parameter point + * + * @return result + *     1 : OK + *     0 : failed + */ +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg); + +/** + * @brief get the SSL context cipher + * + * @param ctx - SSL context point + * + * @return SSL context cipher + */ +STACK *SSL_CTX_get_ciphers(const SSL_CTX *ctx); + +/** + * @brief check if the SSL context can read as many as data + * + * @param ctx - SSL context point + * + * @return result + *     1 : OK + *     0 : failed + */ +long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx); + +/** + * @brief get the SSL context extra data + * + * @param ctx - SSL context point + * @param idx - index + * + * @return data point + */ +char *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx); + +/** + * @brief get the SSL context quiet shutdown option + * + * @param ctx - SSL context point + * + * @return quiet shutdown option + */ +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); + +/** + * @brief load the SSL context CA file + * + * @param ctx    - SSL context point + * @param CAfile - CA certification file + * @param CApath - CA certification file path + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath); + +/** + * @brief add SSL context reference count by '1' + * + * @param ctx - SSL context point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_up_ref(SSL_CTX *ctx); + +/** + * @brief set SSL context application private data + * + * @param ctx - SSL context point + * @param arg - private data + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_set_app_data(SSL_CTX *ctx, void *arg); + +/** + * @brief set SSL context client certification callback function + * + * @param ctx - SSL context point + * @param cb  - callback function + * + * @return none + */ +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); + +/** + * @brief set the SSL context if we can read as many as data + * + * @param ctx - SSL context point + * @param m   - enable the fuction + * + * @return none + */ +void SSL_CTX_set_default_read_ahead(SSL_CTX *ctx, int m); + +/** + * @brief set SSL context default verifying path + * + * @param ctx - SSL context point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); + +/** + * @brief set SSL context default verifying directory + * + * @param ctx - SSL context point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx); + +/** + * @brief set SSL context default verifying file + * + * @param ctx - SSL context point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_set_default_verify_file(SSL_CTX *ctx); + +/** + * @brief set SSL context extra data + * + * @param ctx - SSL context point + * @param idx - data index + * @param arg - data point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, char *arg); + +/** + * @brief clear the SSL context option bit of "op" + * + * @param ctx - SSL context point + * @param op  - option + * + * @return SSL context option + */ +unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op); + +/** + * @brief get the SSL context option + * + * @param ctx - SSL context point + * @param op  - option + * + * @return SSL context option + */ +unsigned long SSL_CTX_get_options(SSL_CTX *ctx); + +/** + * @brief set the SSL context quiet shutdown mode + * + * @param ctx  - SSL context point + * @param mode - mode + * + * @return none + */ +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); + +/** + * @brief get the SSL context X509 certification + * + * @param ctx - SSL context point + * + * @return X509 certification + */ +X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); + +/** + * @brief get the SSL context private key + * + * @param ctx - SSL context point + * + * @return private key + */ +EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); + +/** + * @brief set SSL context PSK identity hint + * + * @param ctx  - SSL context point + * @param hint - PSK identity hint + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint); + +/** + * @brief set SSL context PSK server callback function + * + * @param ctx      - SSL context point + * @param callback - callback function + * + * @return none + */ +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, +                                     unsigned int (*callback)(SSL *ssl, +                                                              const char *identity, +                                                              unsigned char *psk, +                                                              int max_psk_len)); +/** + * @brief get alert description string + * + * @param value - alert value + * + * @return alert description string + */ +const char *SSL_alert_desc_string(int value); + +/** + * @brief get alert description long string + * + * @param value - alert value + * + * @return alert description long string + */ +const char *SSL_alert_desc_string_long(int value); + +/** + * @brief get alert type string + * + * @param value - alert value + * + * @return alert type string + */ +const char *SSL_alert_type_string(int value); + +/** + * @brief get alert type long string + * + * @param value - alert value + * + * @return alert type long string + */ +const char *SSL_alert_type_string_long(int value); + +/** + * @brief get SSL context of the SSL + * + * @param ssl - SSL point + * + * @return SSL context + */ +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); + +/** + * @brief get SSL application data + * + * @param ssl - SSL point + * + * @return application data + */ +char *SSL_get_app_data(SSL *ssl); + +/** + * @brief get SSL cipher bits + * + * @param ssl - SSL point + * @param alg_bits - algorithm bits + * + * @return strength bits + */ +int SSL_get_cipher_bits(const SSL *ssl, int *alg_bits); + +/** + * @brief get SSL cipher name + * + * @param ssl - SSL point + * + * @return SSL cipher name + */ +char *SSL_get_cipher_name(const SSL *ssl); + +/** + * @brief get SSL cipher version + * + * @param ssl - SSL point + * + * @return SSL cipher version + */ +char *SSL_get_cipher_version(const SSL *ssl); + +/** + * @brief get SSL extra data + * + * @param ssl - SSL point + * @param idx - data index + * + * @return extra data + */ +char *SSL_get_ex_data(const SSL *ssl, int idx); + +/** + * @brief get index of the SSL extra data X509 storage context + * + * @param none + * + * @return data index + */ +int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +/** + * @brief get peer certification chain + * + * @param ssl - SSL point + * + * @return certification chain + */ +STACK *SSL_get_peer_cert_chain(const SSL *ssl); + +/** + * @brief get peer certification + * + * @param ssl - SSL point + * + * @return certification + */ +X509 *SSL_get_peer_certificate(const SSL *ssl); + +/** + * @brief get SSL quiet shutdown mode + * + * @param ssl - SSL point + * + * @return quiet shutdown mode + */ +int SSL_get_quiet_shutdown(const SSL *ssl); + +/** + * @brief get SSL read only IO handle + * + * @param ssl - SSL point + * + * @return IO handle + */ +BIO *SSL_get_rbio(const SSL *ssl); + +/** + * @brief get SSL shared ciphers + * + * @param ssl - SSL point + * @param buf - buffer to store the ciphers + * @param len - buffer len + * + * @return shared ciphers + */ +char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); + +/** + * @brief get SSL shutdown mode + * + * @param ssl - SSL point + * + * @return shutdown mode + */ +int SSL_get_shutdown(const SSL *ssl); + +/** + * @brief get SSL session time + * + * @param ssl - SSL point + * + * @return session time + */ +long SSL_get_time(const SSL *ssl); + +/** + * @brief get SSL session timeout time + * + * @param ssl - SSL point + * + * @return session timeout time + */ +long SSL_get_timeout(const SSL *ssl); + +/** + * @brief get SSL verifying mode + * + * @param ssl - SSL point + * + * @return verifying mode + */ +int SSL_get_verify_mode(const SSL *ssl); + +/** + * @brief get SSL verify parameters + * + * @param ssl - SSL point + * + * @return verify parameters + */ +X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); + +/** + * @brief set expected hostname the peer cert CN should have + * + * @param param - verify parameters from SSL_get0_param() + * + * @param name - the expected hostname + * + * @param namelen - the length of the hostname, or 0 if NUL terminated + * + * @return verify parameters + */ +int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, +                                const char *name, size_t namelen); + +/** + * @brief set parameters for X509 host verify action + * + * @param param -verify parameters from SSL_get0_param() + * + * @param flags - bitfield of X509_CHECK_FLAG_... parameters to set + * + * @return 1 for success, 0 for failure + */ +int X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, +				    unsigned long flags); + +/** + * @brief clear parameters for X509 host verify action + * + * @param param -verify parameters from SSL_get0_param() + * + * @param flags - bitfield of X509_CHECK_FLAG_... parameters to clear + * + * @return 1 for success, 0 for failure + */ +int X509_VERIFY_PARAM_clear_hostflags(X509_VERIFY_PARAM *param, +				      unsigned long flags); + +/** + * @brief get SSL write only IO handle + * + * @param ssl - SSL point + * + * @return IO handle + */ +BIO *SSL_get_wbio(const SSL *ssl); + +/** + * @brief load SSL client CA certification file + * + * @param file - file name + * + * @return certification loading object + */ +STACK *SSL_load_client_CA_file(const char *file); + +/** + * @brief add SSL reference by '1' + * + * @param ssl - SSL point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_up_ref(SSL *ssl); + +/** + * @brief read and put data into buf, but not clear the SSL low-level storage + * + * @param ssl - SSL point + * @param buf - storage buffer point + * @param num - data bytes + * + * @return result + *     > 0 : OK, and return read bytes + *     = 0 : connect is closed + *     < 0 : a error catch + */ +int SSL_peek(SSL *ssl, void *buf, int num); + +/** + * @brief make SSL renegotiate + * + * @param ssl - SSL point + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_renegotiate(SSL *ssl); + +/** + * @brief get the state string where SSL is reading + * + * @param ssl - SSL point + * + * @return state string + */ +const char *SSL_rstate_string(SSL *ssl); + +/** + * @brief get the statement long string where SSL is reading + * + * @param ssl - SSL point + * + * @return statement long string + */ +const char *SSL_rstate_string_long(SSL *ssl); + +/** + * @brief set SSL accept statement + * + * @param ssl - SSL point + * + * @return none + */ +void SSL_set_accept_state(SSL *ssl); + +/** + * @brief set SSL application data + * + * @param ssl - SSL point + * @param arg - SSL application data point + * + * @return none + */ +void SSL_set_app_data(SSL *ssl, char *arg); + +/** + * @brief set SSL BIO + * + * @param ssl  - SSL point + * @param rbio - read only IO + * @param wbio - write only IO + * + * @return none + */ +void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); + +/** + * @brief clear SSL option + * + * @param ssl - SSL point + * @param op  - clear option + * + * @return SSL option + */ +unsigned long SSL_clear_options(SSL *ssl, unsigned long op); + +/** + * @brief get SSL option + * + * @param ssl - SSL point + * + * @return SSL option + */ +unsigned long SSL_get_options(SSL *ssl); + +/** + * @brief clear SSL option + * + * @param ssl - SSL point + * @param op  - setting option + * + * @return SSL option + */ +unsigned long SSL_set_options(SSL *ssl, unsigned long op); + +/** + * @brief set SSL quiet shutdown mode + * + * @param ssl  - SSL point + * @param mode - quiet shutdown mode + * + * @return none + */ +void SSL_set_quiet_shutdown(SSL *ssl, int mode); + +/** + * @brief set SSL shutdown mode + * + * @param ssl  - SSL point + * @param mode - shutdown mode + * + * @return none + */ +void SSL_set_shutdown(SSL *ssl, int mode); + +/** + * @brief set SSL session time + * + * @param ssl - SSL point + * @param t   - session time + * + * @return session time + */ +void SSL_set_time(SSL *ssl, long t); + +/** + * @brief set SSL session timeout time + * + * @param ssl - SSL point + * @param t   - session timeout time + * + * @return session timeout time + */ +void SSL_set_timeout(SSL *ssl, long t); + +/** + * @brief get SSL statement string + * + * @param ssl - SSL point + * + * @return SSL statement string + */ +char *SSL_state_string(const SSL *ssl); + +/** + * @brief get SSL statement long string + * + * @param ssl - SSL point + * + * @return SSL statement long string + */ +char *SSL_state_string_long(const SSL *ssl); + +/** + * @brief get SSL renegotiation count + * + * @param ssl - SSL point + * + * @return renegotiation count + */ +long SSL_total_renegotiations(SSL *ssl); + +/** + * @brief get SSL version + * + * @param ssl - SSL point + * + * @return SSL version + */ +int SSL_version(const SSL *ssl); + +/** + * @brief set SSL PSK identity hint + * + * @param ssl  - SSL point + * @param hint - identity hint + * + * @return result + *     1 : OK + *     0 : failed + */ +int SSL_use_psk_identity_hint(SSL *ssl, const char *hint); + +/** + * @brief get SSL PSK identity hint + * + * @param ssl - SSL point + * + * @return identity hint + */ +const char *SSL_get_psk_identity_hint(SSL *ssl); + +/** + * @brief get SSL PSK identity + * + * @param ssl - SSL point + * + * @return identity + */ +const char *SSL_get_psk_identity(SSL *ssl); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/platform/ssl_pm.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/platform/ssl_pm.h new file mode 100644 index 0000000000..cbbe3aa3a2 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/platform/ssl_pm.h @@ -0,0 +1,61 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL_PM_H_ +#define _SSL_PM_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include <string.h> +#include "ssl_types.h" +#include "ssl_port.h" + +#define LOCAL_ATRR + +int ssl_pm_new(SSL *ssl); +void ssl_pm_free(SSL *ssl); + +int ssl_pm_handshake(SSL *ssl); +int ssl_pm_shutdown(SSL *ssl); +int ssl_pm_clear(SSL *ssl); + +int ssl_pm_read(SSL *ssl, void *buffer, int len); +int ssl_pm_send(SSL *ssl, const void *buffer, int len); +int ssl_pm_pending(const SSL *ssl); + +void ssl_pm_set_fd(SSL *ssl, int fd, int mode); +int ssl_pm_get_fd(const SSL *ssl, int mode); + +OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl); + +void ssl_pm_set_bufflen(SSL *ssl, int len); + +int x509_pm_show_info(X509 *x); +int x509_pm_new(X509 *x, X509 *m_x); +void x509_pm_free(X509 *x); +int x509_pm_load(X509 *x, const unsigned char *buffer, int len); + +int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pk); +void pkey_pm_free(EVP_PKEY *pk); +int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len); + +long ssl_pm_get_verify_result(const SSL *ssl); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/platform/ssl_port.h b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/platform/ssl_port.h new file mode 100644 index 0000000000..74c7634355 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/include/platform/ssl_port.h @@ -0,0 +1,46 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SSL_PORT_H_ +#define _SSL_PORT_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "string.h" +#include "stdlib.h" +#if defined(LWS_HAVE_MALLOC_H) +#include "malloc.h" +#endif + +void *ssl_mem_zalloc(size_t size); + +#define ssl_mem_malloc malloc +#define ssl_mem_free   free + +#define ssl_memcpy     memcpy +#define ssl_strlen     strlen + +#define ssl_speed_up_enter() +#define ssl_speed_up_exit() + +#define SSL_DEBUG_FL +#define SSL_DEBUG_LOG(fmt, ...) ESP_LOGI("openssl", fmt, ##__VA_ARGS__) + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_cert.c b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_cert.c new file mode 100644 index 0000000000..5c608125ac --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_cert.c @@ -0,0 +1,87 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ssl_cert.h" +#include "ssl_pkey.h" +#include "ssl_x509.h" +#include "ssl_dbg.h" +#include "ssl_port.h" + +/** + * @brief create a certification object according to input certification + */ +CERT *__ssl_cert_new(CERT *ic) +{ +    CERT *cert; + +    X509 *ix; +    EVP_PKEY *ipk; + +    cert = ssl_mem_zalloc(sizeof(CERT)); +    if (!cert) { +        SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "no enough memory > (cert)"); +        goto no_mem; +    } + +    if (ic) { +        ipk = ic->pkey; +        ix = ic->x509; +    } else { +        ipk = NULL; +        ix = NULL; +    } + +    cert->pkey = __EVP_PKEY_new(ipk); +    if (!cert->pkey) { +        SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "__EVP_PKEY_new() return NULL"); +        goto pkey_err; +    } + +    cert->x509 = __X509_new(ix); +    if (!cert->x509) { +        SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "__X509_new() return NULL"); +        goto x509_err; +    } + +    return cert; + +x509_err: +    EVP_PKEY_free(cert->pkey); +pkey_err: +    ssl_mem_free(cert); +no_mem: +    return NULL; +} + +/** + * @brief create a certification object include private key object + */ +CERT *ssl_cert_new(void) +{ +    return __ssl_cert_new(NULL); +} + +/** + * @brief free a certification object + */ +void ssl_cert_free(CERT *cert) +{ +    SSL_ASSERT3(cert); + +    X509_free(cert->x509); + +    EVP_PKEY_free(cert->pkey); + +    ssl_mem_free(cert); +} diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_lib.c b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_lib.c new file mode 100644 index 0000000000..2f688ca9ef --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_lib.c @@ -0,0 +1,1736 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ssl_lib.h" +#include "ssl_pkey.h" +#include "ssl_x509.h" +#include "ssl_cert.h" +#include "ssl_dbg.h" +#include "ssl_port.h" + +char * +lws_strncpy(char *dest, const char *src, size_t size); + +#define SSL_SEND_DATA_MAX_LENGTH 1460 + +/** + * @brief create a new SSL session object + */ +static SSL_SESSION* SSL_SESSION_new(void) +{ +    SSL_SESSION *session; + +    session = ssl_mem_zalloc(sizeof(SSL_SESSION)); +    if (!session) { +        SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no enough memory > (session)"); +        goto failed1; +    } + +    session->peer = X509_new(); +    if (!session->peer) { +       SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "X509_new() return NULL"); +       goto failed2; +    } + +    return session; + +failed2: +    ssl_mem_free(session); +failed1: +    return NULL; +} + +/** + * @brief free a new SSL session object + */ +static void SSL_SESSION_free(SSL_SESSION *session) +{ +    X509_free(session->peer); +    ssl_mem_free(session); +} + +/** + * @brief Discover whether the current connection is in the error state + */ +int ossl_statem_in_error(const SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    if (ssl->statem.state == MSG_FLOW_ERROR) +        return 1; + +    return 0; +} + +/** + * @brief get the SSL specifical statement + */ +int SSL_want(const SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    return ssl->rwstate; +} + +/** + * @brief check if SSL want nothing + */ +int SSL_want_nothing(const SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    if (ssl->err) +	    return 1; + +    return (SSL_want(ssl) == SSL_NOTHING); +} + +/** + * @brief check if SSL want to read + */ +int SSL_want_read(const SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    if (ssl->err) +	    return 0; + +    return (SSL_want(ssl) == SSL_READING); +} + +/** + * @brief check if SSL want to write + */ +int SSL_want_write(const SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    if (ssl->err) +	    return 0; + +    return (SSL_want(ssl) == SSL_WRITING); +} + +/** + * @brief check if SSL want to lookup X509 certification + */ +int SSL_want_x509_lookup(const SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    return (SSL_want(ssl) == SSL_WRITING); +} + +/** + * @brief get SSL error code + */ +int SSL_get_error(const SSL *ssl, int ret_code) +{ +    int ret = SSL_ERROR_SYSCALL; + +    SSL_ASSERT1(ssl); + +    if (ret_code > 0) +        ret = SSL_ERROR_NONE; +    else if (ret_code < 0) +    { +        if (ssl->err == SSL_ERROR_WANT_READ || SSL_want_read(ssl)) +            ret = SSL_ERROR_WANT_READ; +        else if (ssl->err == SSL_ERROR_WANT_WRITE || SSL_want_write(ssl)) +            ret = SSL_ERROR_WANT_WRITE; +        else +            ret = SSL_ERROR_SYSCALL; //unknown +    } +    else // ret_code == 0 +    { +        if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) +            ret = SSL_ERROR_ZERO_RETURN; +        else +            ret = SSL_ERROR_SYSCALL; +    } + +    return ret; +} + +/** + * @brief get the SSL state + */ +OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl) +{ +    OSSL_HANDSHAKE_STATE state; + +    SSL_ASSERT1(ssl); + +    state = SSL_METHOD_CALL(get_state, ssl); + +    return state; +} + +/** + * @brief create a SSL context + */ +SSL_CTX* SSL_CTX_new(const SSL_METHOD *method) +{ +    SSL_CTX *ctx; +    CERT *cert; +    X509 *client_ca; + +    if (!method) { +        SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no no_method"); +        return NULL; +    } + +    client_ca = X509_new(); +    if (!client_ca) { +        SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "X509_new() return NULL"); +        goto failed1; +    } + +    cert = ssl_cert_new(); +    if (!cert) { +        SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "ssl_cert_new() return NULL"); +        goto failed2; +    } + +    ctx = (SSL_CTX *)ssl_mem_zalloc(sizeof(SSL_CTX)); +    if (!ctx) { +        SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no enough memory > (ctx)"); +        goto failed3; +    } + +    ctx->method = method; +    ctx->client_CA = client_ca; +    ctx->cert = cert; + +    ctx->version = method->version; + +    return ctx; + +failed3: +    ssl_cert_free(cert); +failed2: +    X509_free(client_ca); +failed1: +    return NULL; +} + +/** + * @brief free a SSL context + */ +void SSL_CTX_free(SSL_CTX* ctx) +{ +    SSL_ASSERT3(ctx); + +    ssl_cert_free(ctx->cert); + +    X509_free(ctx->client_CA); + +    if (ctx->alpn_protos) +	    ssl_mem_free(ctx->alpn_protos); + +    ssl_mem_free(ctx); +} + +/** + * @brief set  the SSL context version + */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) +{ +    SSL_ASSERT1(ctx); +    SSL_ASSERT1(meth); + +    ctx->method = meth; + +    ctx->version = meth->version; + +    return 1; +} + +/** + * @brief get the SSL context current method + */ +const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx) +{ +    SSL_ASSERT2(ctx); + +    return ctx->method; +} + +/** + * @brief create a SSL + */ +SSL *SSL_new(SSL_CTX *ctx) +{ +    int ret = 0; +    SSL *ssl; + +    if (!ctx) { +        SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no ctx"); +        return NULL; +    } + +    ssl = (SSL *)ssl_mem_zalloc(sizeof(SSL)); +    if (!ssl) { +        SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no enough memory > (ssl)"); +        goto failed1; +    } + +    ssl->session = SSL_SESSION_new(); +    if (!ssl->session) { +        SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_SESSION_new() return NULL"); +        goto failed2; +    } + +    ssl->cert = __ssl_cert_new(ctx->cert); +    if (!ssl->cert) { +        SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "__ssl_cert_new() return NULL"); +        goto failed3; +    } + +    ssl->client_CA = __X509_new(ctx->client_CA); +    if (!ssl->client_CA) { +        SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "__X509_new() return NULL"); +        goto failed4; +    } + +    ssl->ctx = ctx; +    ssl->method = ctx->method; + +    ssl->version = ctx->version; +    ssl->options = ctx->options; + +    ssl->verify_mode = ctx->verify_mode; + +    ret = SSL_METHOD_CALL(new, ssl); +    if (ret) { +        SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_METHOD_CALL(new) return %d", ret); +        goto failed5; +    } + +   _ssl_set_alpn_list(ssl); + +    ssl->rwstate = SSL_NOTHING; + +    return ssl; + +failed5: +    X509_free(ssl->client_CA); +failed4: +    ssl_cert_free(ssl->cert); +failed3: +    SSL_SESSION_free(ssl->session); +failed2: +    ssl_mem_free(ssl); +failed1: +    return NULL; +} + +/** + * @brief free the SSL + */ +void SSL_free(SSL *ssl) +{ +    SSL_ASSERT3(ssl); + +    SSL_METHOD_CALL(free, ssl); + +    X509_free(ssl->client_CA); + +    ssl_cert_free(ssl->cert); + +    SSL_SESSION_free(ssl->session); + +    if (ssl->alpn_protos) +	    ssl_mem_free(ssl->alpn_protos); + +    ssl_mem_free(ssl); +} + +/** + * @brief perform the SSL handshake + */ +int SSL_do_handshake(SSL *ssl) +{ +    int ret; + +    SSL_ASSERT1(ssl); + +    ret = SSL_METHOD_CALL(handshake, ssl); + +    return ret; +} + +/** + * @brief connect to the remote SSL server + */ +int SSL_connect(SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    return SSL_do_handshake(ssl); +} + +/** + * @brief accept the remote connection + */ +int SSL_accept(SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    return SSL_do_handshake(ssl); +} + +/** + * @brief shutdown the connection + */ +int SSL_shutdown(SSL *ssl) +{ +    int ret; + +    SSL_ASSERT1(ssl); + +    if (SSL_get_state(ssl) != TLS_ST_OK) return 1; + +    ret = SSL_METHOD_CALL(shutdown, ssl); + +    return ret; +} + +/** + * @brief reset the SSL + */ +int SSL_clear(SSL *ssl) +{ +    int ret; + +    SSL_ASSERT1(ssl); + +    ret = SSL_shutdown(ssl); +    if (1 != ret) { +        SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_shutdown return %d", ret); +        goto failed1; +    } + +    SSL_METHOD_CALL(free, ssl); + +    ret = SSL_METHOD_CALL(new, ssl); +    if (!ret) { +        SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_METHOD_CALL(new) return %d", ret); +        goto failed1; +    } + +    return 1; + +failed1: +    return ret; +} + +/** + * @brief read data from to remote + */ +int SSL_read(SSL *ssl, void *buffer, int len) +{ +    int ret; + +    SSL_ASSERT1(ssl); +    SSL_ASSERT1(buffer); +    SSL_ASSERT1(len); + +    ssl->rwstate = SSL_READING; + +    ret = SSL_METHOD_CALL(read, ssl, buffer, len); + +    if (ret == len) +        ssl->rwstate = SSL_NOTHING; + +    return ret; +} + +/** + * @brief send the data to remote + */ +int SSL_write(SSL *ssl, const void *buffer, int len) +{ +    int ret; +    int send_bytes, bytes; +    const unsigned char *pbuf; + +    SSL_ASSERT1(ssl); +    SSL_ASSERT1(buffer); +    SSL_ASSERT1(len); + +    ssl->rwstate = SSL_WRITING; + +    send_bytes = len; +    pbuf = (const unsigned char *)buffer; + +    do { +        if (send_bytes > SSL_SEND_DATA_MAX_LENGTH) +            bytes = SSL_SEND_DATA_MAX_LENGTH; +        else +            bytes = send_bytes; + +	if (ssl->interrupted_remaining_write) { +		bytes = ssl->interrupted_remaining_write; +		ssl->interrupted_remaining_write = 0; +	} + +        ret = SSL_METHOD_CALL(send, ssl, pbuf, bytes); +	//printf("%s: ssl_pm said %d for %d requested (cum %d)\n", __func__, ret, bytes, len -send_bytes); +        /* the return is a NEGATIVE OpenSSL error code, or the length sent */ +        if (ret > 0) { +            pbuf += ret; +            send_bytes -= ret; +        } else +		ssl->interrupted_remaining_write = bytes; +    } while (ret > 0 && send_bytes && ret == bytes); + +    if (ret >= 0) { +        ret = len - send_bytes; +	if (!ret) +	        ssl->rwstate = SSL_NOTHING; +    } else { +	    if (send_bytes == len) +		ret = -1; +	    else +		    ret = len - send_bytes; +    } + +    return ret; +} + +/** + * @brief get SSL context of the SSL + */ +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) +{ +    SSL_ASSERT2(ssl); + +    return ssl->ctx; +} + +/** + * @brief get the SSL current method + */ +const SSL_METHOD *SSL_get_ssl_method(SSL *ssl) +{ +    SSL_ASSERT2(ssl); + +    return ssl->method; +} + +/** + * @brief set the SSL method + */ +int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method) +{ +    int ret; + +    SSL_ASSERT1(ssl); +    SSL_ASSERT1(method); + +    if (ssl->version != method->version) { + +        ret = SSL_shutdown(ssl); +        if (1 != ret) { +            SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_shutdown return %d", ret); +            goto failed1; +        } + +        SSL_METHOD_CALL(free, ssl); + +        ssl->method = method; + +        ret = SSL_METHOD_CALL(new, ssl); +        if (!ret) { +            SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_METHOD_CALL(new) return %d", ret); +            goto failed1; +        } +    } else { +        ssl->method = method; +    } + + +    return 1; + +failed1: +    return ret; +} + +/** + * @brief get SSL shutdown mode + */ +int SSL_get_shutdown(const SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    return ssl->shutdown; +} + +/** + * @brief set SSL shutdown mode + */ +void SSL_set_shutdown(SSL *ssl, int mode) +{ +    SSL_ASSERT3(ssl); + +    ssl->shutdown = mode; +} + + +/** + * @brief get the number of the bytes to be read + */ +int SSL_pending(const SSL *ssl) +{ +    int ret; + +    SSL_ASSERT1(ssl); + +    ret = SSL_METHOD_CALL(pending, ssl); + +    return ret; +} + +/** + * @brief check if some data can be read + */ +int SSL_has_pending(const SSL *ssl) +{ +    int ret; + +    SSL_ASSERT1(ssl); + +    if (SSL_pending(ssl)) +        ret = 1; +    else +        ret = 0; + +    return ret; +} + +/** + * @brief clear the SSL context option bit of "op" + */ +unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op) +{ +    SSL_ASSERT1(ctx); + +    return ctx->options &= ~op; +} + +/** + * @brief get the SSL context option + */ +unsigned long SSL_CTX_get_options(SSL_CTX *ctx) +{ +    SSL_ASSERT1(ctx); + +    return ctx->options; +} + +/** + * @brief set the option of the SSL context + */ +unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt) +{ +    SSL_ASSERT1(ctx); + +    return ctx->options |= opt; +} + +/** + * @brief clear SSL option + */ +unsigned long SSL_clear_options(SSL *ssl, unsigned long op) +{ +    SSL_ASSERT1(ssl); + +    return ssl->options & ~op; +} + +/** + * @brief get SSL option + */ +unsigned long SSL_get_options(SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    return ssl->options; +} + +/** + * @brief clear SSL option + */ +unsigned long SSL_set_options(SSL *ssl, unsigned long op) +{ +    SSL_ASSERT1(ssl); + +    return ssl->options |= op; +} + +/** + * @brief get the socket handle of the SSL + */ +int SSL_get_fd(const SSL *ssl) +{ +    int ret; + +    SSL_ASSERT1(ssl); + +    ret = SSL_METHOD_CALL(get_fd, ssl, 0); + +    return ret; +} + +/** + * @brief get the read only socket handle of the SSL + */ +int SSL_get_rfd(const SSL *ssl) +{ +    int ret; + +    SSL_ASSERT1(ssl); + +    ret = SSL_METHOD_CALL(get_fd, ssl, 0); + +    return ret; +} + +/** + * @brief get the write only socket handle of the SSL + */ +int SSL_get_wfd(const SSL *ssl) +{ +    int ret; + +    SSL_ASSERT1(ssl); + +    ret = SSL_METHOD_CALL(get_fd, ssl, 0); + +    return ret; +} + +/** + * @brief bind the socket file description into the SSL + */ +int SSL_set_fd(SSL *ssl, int fd) +{ +    SSL_ASSERT1(ssl); +    SSL_ASSERT1(fd >= 0); + +    SSL_METHOD_CALL(set_fd, ssl, fd, 0); + +    return 1; +} + +/** + * @brief bind the read only socket file description into the SSL + */ +int SSL_set_rfd(SSL *ssl, int fd) +{ +    SSL_ASSERT1(ssl); +    SSL_ASSERT1(fd >= 0); + +    SSL_METHOD_CALL(set_fd, ssl, fd, 0); + +    return 1; +} + +/** + * @brief bind the write only socket file description into the SSL + */ +int SSL_set_wfd(SSL *ssl, int fd) +{ +    SSL_ASSERT1(ssl); +    SSL_ASSERT1(fd >= 0); + +    SSL_METHOD_CALL(set_fd, ssl, fd, 0); + +    return 1; +} + +/** + * @brief get SSL version + */ +int SSL_version(const SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    return ssl->version; +} + +/** + * @brief get the SSL version string + */ +static const char* ssl_protocol_to_string(int version) +{ +    const char *str; + +    if (version == TLS1_2_VERSION) +        str = "TLSv1.2"; +    else if (version == TLS1_1_VERSION) +        str = "TLSv1.1"; +    else if (version == TLS1_VERSION) +        str = "TLSv1"; +    else if (version == SSL3_VERSION) +        str = "SSLv3"; +    else +        str = "unknown"; + +    return str; +} + +/** + * @brief get the SSL current version + */ +const char *SSL_get_version(const SSL *ssl) +{ +    SSL_ASSERT2(ssl); + +    return ssl_protocol_to_string(SSL_version(ssl)); +} + +/** + * @brief get alert description string + */ +const char* SSL_alert_desc_string(int value) +{ +    const char *str; + +    switch (value & 0xff) +    { +        case SSL3_AD_CLOSE_NOTIFY: +            str = "CN"; +            break; +        case SSL3_AD_UNEXPECTED_MESSAGE: +            str = "UM"; +            break; +        case SSL3_AD_BAD_RECORD_MAC: +            str = "BM"; +            break; +        case SSL3_AD_DECOMPRESSION_FAILURE: +            str = "DF"; +            break; +        case SSL3_AD_HANDSHAKE_FAILURE: +            str = "HF"; +            break; +        case SSL3_AD_NO_CERTIFICATE: +            str = "NC"; +            break; +        case SSL3_AD_BAD_CERTIFICATE: +            str = "BC"; +            break; +        case SSL3_AD_UNSUPPORTED_CERTIFICATE: +            str = "UC"; +            break; +        case SSL3_AD_CERTIFICATE_REVOKED: +            str = "CR"; +            break; +        case SSL3_AD_CERTIFICATE_EXPIRED: +            str = "CE"; +            break; +        case SSL3_AD_CERTIFICATE_UNKNOWN: +            str = "CU"; +            break; +        case SSL3_AD_ILLEGAL_PARAMETER: +            str = "IP"; +            break; +        case TLS1_AD_DECRYPTION_FAILED: +            str = "DC"; +            break; +        case TLS1_AD_RECORD_OVERFLOW: +            str = "RO"; +            break; +        case TLS1_AD_UNKNOWN_CA: +            str = "CA"; +            break; +        case TLS1_AD_ACCESS_DENIED: +            str = "AD"; +            break; +        case TLS1_AD_DECODE_ERROR: +            str = "DE"; +            break; +        case TLS1_AD_DECRYPT_ERROR: +            str = "CY"; +            break; +        case TLS1_AD_EXPORT_RESTRICTION: +            str = "ER"; +            break; +        case TLS1_AD_PROTOCOL_VERSION: +            str = "PV"; +            break; +        case TLS1_AD_INSUFFICIENT_SECURITY: +            str = "IS"; +            break; +        case TLS1_AD_INTERNAL_ERROR: +            str = "IE"; +            break; +        case TLS1_AD_USER_CANCELLED: +            str = "US"; +            break; +        case TLS1_AD_NO_RENEGOTIATION: +            str = "NR"; +            break; +        case TLS1_AD_UNSUPPORTED_EXTENSION: +            str = "UE"; +            break; +        case TLS1_AD_CERTIFICATE_UNOBTAINABLE: +            str = "CO"; +            break; +        case TLS1_AD_UNRECOGNIZED_NAME: +            str = "UN"; +            break; +        case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: +            str = "BR"; +            break; +        case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: +            str = "BH"; +            break; +        case TLS1_AD_UNKNOWN_PSK_IDENTITY: +            str = "UP"; +            break; +        default: +            str = "UK"; +            break; +    } + +    return str; +} + +/** + * @brief get alert description long string + */ +const char* SSL_alert_desc_string_long(int value) +{ +    const char *str; + +    switch (value & 0xff) +    { +        case SSL3_AD_CLOSE_NOTIFY: +            str = "close notify"; +            break; +        case SSL3_AD_UNEXPECTED_MESSAGE: +            str = "unexpected_message"; +            break; +        case SSL3_AD_BAD_RECORD_MAC: +            str = "bad record mac"; +            break; +        case SSL3_AD_DECOMPRESSION_FAILURE: +            str = "decompression failure"; +            break; +        case SSL3_AD_HANDSHAKE_FAILURE: +            str = "handshake failure"; +            break; +        case SSL3_AD_NO_CERTIFICATE: +            str = "no certificate"; +            break; +        case SSL3_AD_BAD_CERTIFICATE: +            str = "bad certificate"; +            break; +        case SSL3_AD_UNSUPPORTED_CERTIFICATE: +            str = "unsupported certificate"; +            break; +        case SSL3_AD_CERTIFICATE_REVOKED: +            str = "certificate revoked"; +            break; +        case SSL3_AD_CERTIFICATE_EXPIRED: +            str = "certificate expired"; +            break; +        case SSL3_AD_CERTIFICATE_UNKNOWN: +            str = "certificate unknown"; +            break; +        case SSL3_AD_ILLEGAL_PARAMETER: +            str = "illegal parameter"; +            break; +        case TLS1_AD_DECRYPTION_FAILED: +            str = "decryption failed"; +            break; +        case TLS1_AD_RECORD_OVERFLOW: +            str = "record overflow"; +            break; +        case TLS1_AD_UNKNOWN_CA: +            str = "unknown CA"; +            break; +        case TLS1_AD_ACCESS_DENIED: +            str = "access denied"; +            break; +        case TLS1_AD_DECODE_ERROR: +            str = "decode error"; +            break; +        case TLS1_AD_DECRYPT_ERROR: +            str = "decrypt error"; +            break; +        case TLS1_AD_EXPORT_RESTRICTION: +            str = "export restriction"; +            break; +        case TLS1_AD_PROTOCOL_VERSION: +            str = "protocol version"; +            break; +        case TLS1_AD_INSUFFICIENT_SECURITY: +            str = "insufficient security"; +            break; +        case TLS1_AD_INTERNAL_ERROR: +            str = "internal error"; +            break; +        case TLS1_AD_USER_CANCELLED: +            str = "user canceled"; +            break; +        case TLS1_AD_NO_RENEGOTIATION: +            str = "no renegotiation"; +            break; +        case TLS1_AD_UNSUPPORTED_EXTENSION: +            str = "unsupported extension"; +            break; +        case TLS1_AD_CERTIFICATE_UNOBTAINABLE: +            str = "certificate unobtainable"; +            break; +        case TLS1_AD_UNRECOGNIZED_NAME: +            str = "unrecognized name"; +            break; +        case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: +            str = "bad certificate status response"; +            break; +        case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: +            str = "bad certificate hash value"; +            break; +        case TLS1_AD_UNKNOWN_PSK_IDENTITY: +            str = "unknown PSK identity"; +            break; +        default: +            str = "unknown"; +            break; +    } + +    return str; +} + +/** + * @brief get alert type string + */ +const char *SSL_alert_type_string(int value) +{ +    const char *str; + +    switch (value >> 8) +    { +    case SSL3_AL_WARNING: +        str = "W"; +        break; +    case SSL3_AL_FATAL: +        str = "F"; +        break; +    default: +        str = "U"; +        break; +    } + +    return str; +} + +/** + * @brief get alert type long string + */ +const char *SSL_alert_type_string_long(int value) +{ +    const char *str; + +    switch (value >> 8) +    { +        case SSL3_AL_WARNING: +            str = "warning"; +            break; +        case SSL3_AL_FATAL: +            str = "fatal"; +            break; +        default: +            str = "unknown"; +            break; +    } + +    return str; +} + +/** + * @brief get the state string where SSL is reading + */ +const char *SSL_rstate_string(SSL *ssl) +{ +    const char *str; + +    SSL_ASSERT2(ssl); + +    switch (ssl->rlayer.rstate) +    { +        case SSL_ST_READ_HEADER: +            str = "RH"; +            break; +        case SSL_ST_READ_BODY: +            str = "RB"; +            break; +        case SSL_ST_READ_DONE: +            str = "RD"; +            break; +        default: +            str = "unknown"; +            break; +    } + +    return str; +} + +/** + * @brief get the statement long string where SSL is reading + */ +const char *SSL_rstate_string_long(SSL *ssl) +{ +    const char *str = "unknown"; + +    SSL_ASSERT2(ssl); + +    switch (ssl->rlayer.rstate) +    { +        case SSL_ST_READ_HEADER: +            str = "read header"; +            break; +        case SSL_ST_READ_BODY: +            str = "read body"; +            break; +        case SSL_ST_READ_DONE: +            str = "read done"; +            break; +        default: +            break; +    } + +    return str; +} + +/** + * @brief get SSL statement string + */ +char *SSL_state_string(const SSL *ssl) +{ +    char *str = "UNKWN "; + +    SSL_ASSERT2(ssl); + +    if (ossl_statem_in_error(ssl)) +        str = "SSLERR"; +    else +    { +        switch (SSL_get_state(ssl)) +        { +            case TLS_ST_BEFORE: +                str = "PINIT "; +                break; +            case TLS_ST_OK: +                str =  "SSLOK "; +                break; +            case TLS_ST_CW_CLNT_HELLO: +                str = "TWCH"; +                break; +            case TLS_ST_CR_SRVR_HELLO: +                str = "TRSH"; +                break; +            case TLS_ST_CR_CERT: +                str = "TRSC"; +                break; +            case TLS_ST_CR_KEY_EXCH: +                str = "TRSKE"; +                break; +            case TLS_ST_CR_CERT_REQ: +                str = "TRCR"; +                break; +            case TLS_ST_CR_SRVR_DONE: +                str = "TRSD"; +                break; +            case TLS_ST_CW_CERT: +                str = "TWCC"; +                break; +            case TLS_ST_CW_KEY_EXCH: +                str = "TWCKE"; +                break; +            case TLS_ST_CW_CERT_VRFY: +                str = "TWCV"; +                break; +            case TLS_ST_SW_CHANGE: +            case TLS_ST_CW_CHANGE: +                str = "TWCCS"; +                break; +            case TLS_ST_SW_FINISHED: +            case TLS_ST_CW_FINISHED: +                str = "TWFIN"; +                break; +            case TLS_ST_SR_CHANGE: +            case TLS_ST_CR_CHANGE: +                str = "TRCCS"; +                break; +            case TLS_ST_SR_FINISHED: +            case TLS_ST_CR_FINISHED: +                str = "TRFIN"; +                break; +            case TLS_ST_SW_HELLO_REQ: +                str = "TWHR"; +                break; +            case TLS_ST_SR_CLNT_HELLO: +                str = "TRCH"; +                break; +            case TLS_ST_SW_SRVR_HELLO: +                str = "TWSH"; +                break; +            case TLS_ST_SW_CERT: +                str = "TWSC"; +                break; +            case TLS_ST_SW_KEY_EXCH: +                str = "TWSKE"; +                break; +            case TLS_ST_SW_CERT_REQ: +                str = "TWCR"; +                break; +            case TLS_ST_SW_SRVR_DONE: +                str = "TWSD"; +                break; +            case TLS_ST_SR_CERT: +                str = "TRCC"; +                break; +            case TLS_ST_SR_KEY_EXCH: +                str = "TRCKE"; +                break; +            case TLS_ST_SR_CERT_VRFY: +                str = "TRCV"; +                break; +            case DTLS_ST_CR_HELLO_VERIFY_REQUEST: +                str = "DRCHV"; +                break; +            case DTLS_ST_SW_HELLO_VERIFY_REQUEST: +                str = "DWCHV"; +                break; +            default: +                break; +        } +    } + +    return str; +} + +/** + * @brief get SSL statement long string + */ +char *SSL_state_string_long(const SSL *ssl) +{ +    char *str = "UNKWN "; + +    SSL_ASSERT2(ssl); + +    if (ossl_statem_in_error(ssl)) +        str = "SSLERR"; +    else +    { +        switch (SSL_get_state(ssl)) +        { +            case TLS_ST_BEFORE: +                str = "before SSL initialization"; +                break; +            case TLS_ST_OK: +                str = "SSL negotiation finished successfully"; +                break; +            case TLS_ST_CW_CLNT_HELLO: +                str = "SSLv3/TLS write client hello"; +                break; +            case TLS_ST_CR_SRVR_HELLO: +                str = "SSLv3/TLS read server hello"; +                break; +            case TLS_ST_CR_CERT: +                str = "SSLv3/TLS read server certificate"; +                break; +            case TLS_ST_CR_KEY_EXCH: +                str = "SSLv3/TLS read server key exchange"; +                break; +            case TLS_ST_CR_CERT_REQ: +                str = "SSLv3/TLS read server certificate request"; +                break; +            case TLS_ST_CR_SESSION_TICKET: +                str = "SSLv3/TLS read server session ticket"; +                break; +            case TLS_ST_CR_SRVR_DONE: +                str = "SSLv3/TLS read server done"; +                break; +            case TLS_ST_CW_CERT: +                str = "SSLv3/TLS write client certificate"; +                break; +            case TLS_ST_CW_KEY_EXCH: +                str = "SSLv3/TLS write client key exchange"; +                break; +            case TLS_ST_CW_CERT_VRFY: +                str = "SSLv3/TLS write certificate verify"; +                break; +            case TLS_ST_CW_CHANGE: +            case TLS_ST_SW_CHANGE: +                str = "SSLv3/TLS write change cipher spec"; +                break; +            case TLS_ST_CW_FINISHED: +            case TLS_ST_SW_FINISHED: +                str = "SSLv3/TLS write finished"; +                break; +            case TLS_ST_CR_CHANGE: +            case TLS_ST_SR_CHANGE: +                str = "SSLv3/TLS read change cipher spec"; +                break; +            case TLS_ST_CR_FINISHED: +            case TLS_ST_SR_FINISHED: +                str = "SSLv3/TLS read finished"; +                break; +            case TLS_ST_SR_CLNT_HELLO: +                str = "SSLv3/TLS read client hello"; +                break; +            case TLS_ST_SW_HELLO_REQ: +                str = "SSLv3/TLS write hello request"; +                break; +            case TLS_ST_SW_SRVR_HELLO: +                str = "SSLv3/TLS write server hello"; +                break; +            case TLS_ST_SW_CERT: +                str = "SSLv3/TLS write certificate"; +                break; +            case TLS_ST_SW_KEY_EXCH: +                str = "SSLv3/TLS write key exchange"; +                break; +            case TLS_ST_SW_CERT_REQ: +                str = "SSLv3/TLS write certificate request"; +                break; +            case TLS_ST_SW_SESSION_TICKET: +                str = "SSLv3/TLS write session ticket"; +                break; +            case TLS_ST_SW_SRVR_DONE: +                str = "SSLv3/TLS write server done"; +                break; +            case TLS_ST_SR_CERT: +                str = "SSLv3/TLS read client certificate"; +                break; +            case TLS_ST_SR_KEY_EXCH: +                str = "SSLv3/TLS read client key exchange"; +                break; +            case TLS_ST_SR_CERT_VRFY: +                str = "SSLv3/TLS read certificate verify"; +                break; +            case DTLS_ST_CR_HELLO_VERIFY_REQUEST: +                str = "DTLS1 read hello verify request"; +                break; +            case DTLS_ST_SW_HELLO_VERIFY_REQUEST: +                str = "DTLS1 write hello verify request"; +                break; +            default: +                break; +        } +    } + +    return str; +} + +/** + * @brief set the SSL context read buffer length + */ +void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len) +{ +    SSL_ASSERT3(ctx); + +    ctx->read_buffer_len = len; +} + +/** + * @brief set the SSL read buffer length + */ +void SSL_set_default_read_buffer_len(SSL *ssl, size_t len) +{ +    SSL_ASSERT3(ssl); +    SSL_ASSERT3(len); + +    SSL_METHOD_CALL(set_bufflen, ssl, len); +} + +/** + * @brief set the SSL information callback function + */ +void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)) +{ +    SSL_ASSERT3(ssl); + +    ssl->info_callback = cb; +} + +/** + * @brief add SSL context reference count by '1' + */ +int SSL_CTX_up_ref(SSL_CTX *ctx) +{ +    SSL_ASSERT1(ctx); + +    /** +     * no support multi-thread SSL here +     */ +    ctx->references++; + +    return 1; +} + +/** + * @brief set the SSL security level + */ +void SSL_set_security_level(SSL *ssl, int level) +{ +    SSL_ASSERT3(ssl); + +    ssl->cert->sec_level = level; +} + +/** + * @brief get the SSL security level + */ +int SSL_get_security_level(const SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    return ssl->cert->sec_level; +} + +/** + * @brief get the SSL verifying mode of the SSL context + */ +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) +{ +    SSL_ASSERT1(ctx); + +    return ctx->verify_mode; +} + +/** + * @brief set the session timeout time + */ +long SSL_CTX_set_timeout(SSL_CTX *ctx, long t) +{ +    long l; + +    SSL_ASSERT1(ctx); + +    l = ctx->session_timeout; +    ctx->session_timeout = t; + +    return l; +} + +/** + * @brief get the session timeout time + */ +long SSL_CTX_get_timeout(const SSL_CTX *ctx) +{ +    SSL_ASSERT1(ctx); + +    return ctx->session_timeout; +} + +/** + * @brief set the SSL if we can read as many as data + */ +void SSL_set_read_ahead(SSL *ssl, int yes) +{ +    SSL_ASSERT3(ssl); + +    ssl->rlayer.read_ahead = yes; +} + +/** + * @brief set the SSL context if we can read as many as data + */ +void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) +{ +    SSL_ASSERT3(ctx); + +    ctx->read_ahead = yes; +} + +/** + * @brief get the SSL ahead signal if we can read as many as data + */ +int SSL_get_read_ahead(const SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    return ssl->rlayer.read_ahead; +} + +/** + * @brief get the SSL context ahead signal if we can read as many as data + */ +long SSL_CTX_get_read_ahead(SSL_CTX *ctx) +{ +    SSL_ASSERT1(ctx); + +    return ctx->read_ahead; +} + +/** + * @brief check if the SSL context can read as many as data + */ +long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx) +{ +    SSL_ASSERT1(ctx); + +    return ctx->read_ahead; +} + +/** + * @brief set SSL session time + */ +long SSL_set_time(SSL *ssl, long t) +{ +    SSL_ASSERT1(ssl); + +    ssl->session->time = t; + +    return t; +} + +/** + * @brief set SSL session timeout time + */ +long SSL_set_timeout(SSL *ssl, long t) +{ +    SSL_ASSERT1(ssl); + +    ssl->session->timeout = t; + +    return t; +} + +/** + * @brief get the verifying result of the SSL certification + */ +long SSL_get_verify_result(const SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    return SSL_METHOD_CALL(get_verify_result, ssl); +} + +/** + * @brief get the SSL verifying depth of the SSL context + */ +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) +{ +    SSL_ASSERT1(ctx); + +    return ctx->param.depth; +} + +/** + * @brief set the SSL verify depth of the SSL context + */ +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) +{ +    SSL_ASSERT3(ctx); + +    ctx->param.depth = depth; +} + +/** + * @brief get the SSL verifying depth of the SSL + */ +int SSL_get_verify_depth(const SSL *ssl) +{ +    SSL_ASSERT1(ssl); + +    return ssl->param.depth; +} + +/** + * @brief set the SSL verify depth of the SSL + */ +void SSL_set_verify_depth(SSL *ssl, int depth) +{ +    SSL_ASSERT3(ssl); + +    ssl->param.depth = depth; +} + +/** + * @brief set the SSL context verifying of the SSL context + */ +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) +{ +    SSL_ASSERT3(ctx); + +    ctx->verify_mode = mode; +    ctx->default_verify_callback = verify_callback; +} + +/** + * @brief set the SSL verifying of the SSL context + */ +void SSL_set_verify(SSL *ssl, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) +{ +    SSL_ASSERT3(ssl); + +    ssl->verify_mode = mode; +    ssl->verify_callback = verify_callback; +} + +void ERR_error_string_n(unsigned long e, char *buf, size_t len) +{ +	lws_strncpy(buf, "unknown", len); +} + +void ERR_free_strings(void) +{ +} + +char *ERR_error_string(unsigned long e, char *buf) +{ +	if (!buf) +		return "unknown"; + +	switch(e) { +		case X509_V_ERR_INVALID_CA: +			strcpy(buf, "CA is not trusted"); +			break; +		case X509_V_ERR_HOSTNAME_MISMATCH: +			strcpy(buf, "Hostname mismatch"); +			break; +		case X509_V_ERR_CA_KEY_TOO_SMALL: +			strcpy(buf, "CA key too small"); +			break; +		case X509_V_ERR_CA_MD_TOO_WEAK: +			strcpy(buf, "MD key too weak"); +			break; +		case X509_V_ERR_CERT_NOT_YET_VALID: +			strcpy(buf, "Cert from the future"); +			break; +		case X509_V_ERR_CERT_HAS_EXPIRED: +			strcpy(buf, "Cert expired"); +			break; +		default: +			strcpy(buf, "unknown"); +			break; +	} + +	return buf; +} + +void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) +{ +	return NULL; +} + +/* + * Openssl wants the valid protocol names supplied like this: + * + * (unsigned char *)"\x02h2\x08http/1.1", 6 + 9 + * + * Mbedtls wants this: + * + * Pointer to a NULL-terminated list of supported protocols, in decreasing + * preference order. The pointer to the list is recorded by the library for + * later reference as required, so the lifetime of the table must be at least + * as long as the lifetime of the SSL configuration structure. + * + * So accept the OpenSSL style and convert to mbedtls style + */ + +struct alpn_ctx { +	unsigned char data[23]; +	unsigned char len; +}; + +static void +_openssl_alpn_to_mbedtls(struct alpn_ctx *ac, char ***palpn_protos) +{ +	unsigned char *p = ac->data, *q; +	unsigned char len; +	char **alpn_protos; +	int count = 0; + +	/* find out how many entries he gave us */ + +	len = *p++; +	while (p - ac->data < ac->len) { +		if (len--) { +			p++; +			continue; +		} +		count++; +		len = *p++; +		if (!len) +			break; +	} + +	if (!len) +		count++; + +	if (!count) +		return; + +	/* allocate space for count + 1 pointers and the data afterwards */ + +	alpn_protos = ssl_mem_zalloc((count + 1) * sizeof(char *) + ac->len + 1); +	if (!alpn_protos) +		return; + +	*palpn_protos = alpn_protos; + +	/* convert to mbedtls format */ + +	q = (unsigned char *)alpn_protos + (count + 1) * sizeof(char *); +	p = ac->data; +	count = 0; + +	len = *p++; +	alpn_protos[count] = (char *)q; +	while (p - ac->data < ac->len) { +		if (len--) { +			*q++ = *p++; +			continue; +		} +		*q++ = '\0'; +		count++; +		len = *p++; +		alpn_protos[count] = (char *)q; +		if (!len) +			break; +	} +	if (!len) { +		*q++ = '\0'; +		count++; +		len = *p++; +		alpn_protos[count] = (char *)q; +	} +	alpn_protos[count] = NULL; /* last pointer ends list with NULL */ +} + +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, next_proto_cb cb, void *arg) +{ +	struct alpn_ctx *ac = arg; + +	ctx->alpn_cb = cb; + +	_openssl_alpn_to_mbedtls(ac, (char ***)&ctx->alpn_protos); +} + +void SSL_set_alpn_select_cb(SSL *ssl, void *arg) +{ +	struct alpn_ctx *ac = arg; + +	_openssl_alpn_to_mbedtls(ac, (char ***)&ssl->alpn_protos); + +	_ssl_set_alpn_list(ssl); +} diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_methods.c b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_methods.c new file mode 100644 index 0000000000..0002360846 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_methods.c @@ -0,0 +1,81 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ssl_methods.h" +#include "ssl_pm.h" + +/** + * TLS method function collection + */ +IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func, +        ssl_pm_new, ssl_pm_free, +        ssl_pm_handshake, ssl_pm_shutdown, ssl_pm_clear, +        ssl_pm_read, ssl_pm_send, ssl_pm_pending, +        ssl_pm_set_fd, ssl_pm_get_fd, +        ssl_pm_set_bufflen, +        ssl_pm_get_verify_result, +        ssl_pm_get_state); + +/** + * TLS or SSL client method collection + */ +IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 0, TLS_method_func, TLS_client_method); + +IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 0, TLS_method_func, TLSv1_2_client_method); + +IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 0, TLS_method_func, TLSv1_1_client_method); + +IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_client_method); + +IMPLEMENT_SSL_METHOD(SSL3_VERSION, 0, TLS_method_func, SSLv3_client_method); + +/** + * TLS or SSL server method collection + */ +IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 1, TLS_method_func, TLS_server_method); + +IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 1, TLS_method_func, TLSv1_1_server_method); + +IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 1, TLS_method_func, TLSv1_2_server_method); + +IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_server_method); + +IMPLEMENT_SSL_METHOD(SSL3_VERSION, 1, TLS_method_func, SSLv3_server_method); + +/** + * TLS or SSL method collection + */ +IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, -1, TLS_method_func, TLS_method); + +IMPLEMENT_SSL_METHOD(TLS1_2_VERSION, -1, TLS_method_func, TLSv1_2_method); + +IMPLEMENT_SSL_METHOD(TLS1_1_VERSION, -1, TLS_method_func, TLSv1_1_method); + +IMPLEMENT_SSL_METHOD(TLS1_VERSION, -1, TLS_method_func, TLSv1_method); + +IMPLEMENT_SSL_METHOD(SSL3_VERSION, -1, TLS_method_func, SSLv3_method); + +/** + * @brief get X509 object method + */ +IMPLEMENT_X509_METHOD(X509_method, +            x509_pm_new, x509_pm_free, +            x509_pm_load, x509_pm_show_info); + +/** + * @brief get private key object method + */ +IMPLEMENT_PKEY_METHOD(EVP_PKEY_method, +            pkey_pm_new, pkey_pm_free, +            pkey_pm_load); diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_pkey.c b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_pkey.c new file mode 100644 index 0000000000..567a33e2c2 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_pkey.c @@ -0,0 +1,239 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ssl_pkey.h" +#include "ssl_methods.h" +#include "ssl_dbg.h" +#include "ssl_port.h" + +/** + * @brief create a private key object according to input private key + */ +EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk) +{ +    int ret; +    EVP_PKEY *pkey; + +    pkey = ssl_mem_zalloc(sizeof(EVP_PKEY)); +    if (!pkey) { +        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "no enough memory > (pkey)"); +        goto no_mem; +    } + +    if (ipk) { +        pkey->method = ipk->method; +    } else { +        pkey->method = EVP_PKEY_method(); +    } + +    ret = EVP_PKEY_METHOD_CALL(new, pkey, ipk); +    if (ret) { +        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_METHOD_CALL(new) return %d", ret); +        goto failed; +    } + +    return pkey; + +failed: +    ssl_mem_free(pkey); +no_mem: +    return NULL; +} + +/** + * @brief create a private key object + */ +EVP_PKEY* EVP_PKEY_new(void) +{ +    return __EVP_PKEY_new(NULL); +} + +/** + * @brief free a private key object + */ +void EVP_PKEY_free(EVP_PKEY *pkey) +{ +    SSL_ASSERT3(pkey); + +    EVP_PKEY_METHOD_CALL(free, pkey); + +    ssl_mem_free(pkey); +} + +/** + * @brief load a character key context into system context. If '*a' is pointed to the + *        private key, then load key into it. Or create a new private key object + */ +EVP_PKEY *d2i_PrivateKey(int type, +                         EVP_PKEY **a, +                         const unsigned char **pp, +                         long length) +{ +    int m = 0; +    int ret; +    EVP_PKEY *pkey; + +    SSL_ASSERT2(pp); +    SSL_ASSERT2(*pp); +    SSL_ASSERT2(length); + +    if (a && *a) { +        pkey = *a; +    } else { +        pkey = EVP_PKEY_new();; +        if (!pkey) { +            SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_new() return NULL"); +            goto failed1; +        } + +        m = 1; +    } + +    ret = EVP_PKEY_METHOD_CALL(load, pkey, *pp, length); +    if (ret) { +        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_METHOD_CALL(load) return %d", ret); +        goto failed2; +    } + +    if (a) +        *a = pkey; + +    return pkey; + +failed2: +    if (m) +        EVP_PKEY_free(pkey); +failed1: +    return NULL; +} + +/** + * @brief set the SSL context private key + */ +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) +{ +    SSL_ASSERT1(ctx); +    SSL_ASSERT1(pkey); + +    if (ctx->cert->pkey == pkey) +        return 1; + +    if (ctx->cert->pkey) +        EVP_PKEY_free(ctx->cert->pkey); + +    ctx->cert->pkey = pkey; + +    return 1; +} + +/** + * @brief set the SSL private key + */ +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) +{ +    SSL_ASSERT1(ssl); +    SSL_ASSERT1(pkey); + +    if (ssl->cert->pkey == pkey) +        return 1; + +    if (ssl->cert->pkey) +        EVP_PKEY_free(ssl->cert->pkey); + +    ssl->cert->pkey = pkey; + +    return 1; +} + +/** + * @brief load private key into the SSL context + */ +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, +                                const unsigned char *d, long len) +{ +    int ret; +    EVP_PKEY *pk; + +    pk = d2i_PrivateKey(0, NULL, &d, len); +    if (!pk) { +        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL"); +        goto failed1; +    } + +    ret = SSL_CTX_use_PrivateKey(ctx, pk); +    if (!ret) { +        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_CTX_use_PrivateKey() return %d", ret); +        goto failed2; +    } + +    return 1; + +failed2: +    EVP_PKEY_free(pk); +failed1: +    return 0; +} + +/** + * @brief load private key into the SSL + */ +int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, +                                const unsigned char *d, long len) +{ +    int ret; +    EVP_PKEY *pk; + +    pk = d2i_PrivateKey(0, NULL, &d, len); +    if (!pk) { +        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL"); +        goto failed1; +    } + +    ret = SSL_use_PrivateKey(ssl, pk); +    if (!ret) { +        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_use_PrivateKey() return %d", ret); +        goto failed2; +    } + +    return 1; + +failed2: +    EVP_PKEY_free(pk); +failed1: +    return 0; +} + +/** + * @brief load the private key file into SSL context + */ +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) +{ +    return 0; +} + +/** + * @brief load the private key file into SSL + */ +int SSL_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) +{ +    return 0; +} + +/** + * @brief load the RSA ASN1 private key into SSL context + */ +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len) +{ +    return SSL_CTX_use_PrivateKey_ASN1(0, ctx, d, len); +} diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_stack.c b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_stack.c new file mode 100644 index 0000000000..da836daf9c --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_stack.c @@ -0,0 +1,74 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ssl_stack.h" +#include "ssl_dbg.h" +#include "ssl_port.h" + +#ifndef CONFIG_MIN_NODES +    #define MIN_NODES 4 +#else +    #define MIN_NODES CONFIG_MIN_NODES +#endif + +/** + * @brief create a openssl stack object + */ +OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c) +{ +    OPENSSL_STACK *stack; +    char **data; + +    stack = ssl_mem_zalloc(sizeof(OPENSSL_STACK)); +    if (!stack) { +        SSL_DEBUG(SSL_STACK_ERROR_LEVEL, "no enough memory > (stack)"); +        goto no_mem1; +    } + +    data = ssl_mem_zalloc(sizeof(*data) * MIN_NODES); +    if (!data) { +        SSL_DEBUG(SSL_STACK_ERROR_LEVEL, "no enough memory > (data)"); +        goto no_mem2; +    } + +    stack->data = data; +    stack->num_alloc = MIN_NODES; +    stack->c = c; + +    return stack; + +no_mem2: +    ssl_mem_free(stack); +no_mem1: +    return NULL; +} + +/** + * @brief create a NULL function openssl stack object + */ +OPENSSL_STACK *OPENSSL_sk_new_null(void) +{ +    return OPENSSL_sk_new((OPENSSL_sk_compfunc)NULL); +} + +/** + * @brief free openssl stack object + */ +void OPENSSL_sk_free(OPENSSL_STACK *stack) +{ +    SSL_ASSERT3(stack); + +    ssl_mem_free(stack->data); +    ssl_mem_free(stack); +} diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_x509.c b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_x509.c new file mode 100644 index 0000000000..ed79150831 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/library/ssl_x509.c @@ -0,0 +1,354 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ssl_x509.h" +#include "ssl_methods.h" +#include "ssl_dbg.h" +#include "ssl_port.h" + +#include <assert.h> + +/** + * @brief show X509 certification information + */ +int __X509_show_info(X509 *x) +{ +    return X509_METHOD_CALL(show_info, x); +} + +/** + * @brief create a X509 certification object according to input X509 certification + */ +X509* __X509_new(X509 *ix) +{ +    int ret; +    X509 *x; + +    x = ssl_mem_zalloc(sizeof(X509)); +    if (!x) { +        SSL_DEBUG(SSL_X509_ERROR_LEVEL, "no enough memory > (x)"); +        goto no_mem; +    } + +    if (ix) +        x->method = ix->method; +    else +        x->method = X509_method(); + +    ret = X509_METHOD_CALL(new, x, ix); +    if (ret) { +        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_METHOD_CALL(new) return %d", ret); +        goto failed; +    } + +    return x; + +failed: +    ssl_mem_free(x); +no_mem: +    return NULL; +} + +/** + * @brief create a X509 certification object + */ +X509* X509_new(void) +{ +    return __X509_new(NULL); +} + +/** + * @brief free a X509 certification object + */ +void X509_free(X509 *x) +{ +    SSL_ASSERT3(x); + +    X509_METHOD_CALL(free, x); + +    ssl_mem_free(x); +}; + +/** + * @brief load a character certification context into system context. If '*cert' is pointed to the + *        certification, then load certification into it. Or create a new X509 certification object + */ +X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) +{ +    int m = 0; +    int ret; +    X509 *x; + +    SSL_ASSERT2(buffer); +    SSL_ASSERT2(len); + +    if (cert && *cert) { +        x = *cert; +    } else { +        x = X509_new(); +        if (!x) { +            SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_new() return NULL"); +            goto failed1; +        } +        m = 1; +    } + +    ret = X509_METHOD_CALL(load, x, buffer, len); +    if (ret) { +        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_METHOD_CALL(load) return %d", ret); +        goto failed2; +    } + +    return x; + +failed2: +    if (m) +        X509_free(x); +failed1: +    return NULL; +} + +/** + * @brief return SSL X509 verify parameters + */ + +X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) +{ +	return &ssl->param; +} + +/** + * @brief set X509 host verification flags + */ + +int X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, +				    unsigned long flags) +{ +	/* flags not supported yet */ +	return 0; +} + +/** + * @brief clear X509 host verification flags + */ + +int X509_VERIFY_PARAM_clear_hostflags(X509_VERIFY_PARAM *param, +				      unsigned long flags) +{ +	/* flags not supported yet */ +	return 0; +} + +/** + * @brief set SSL context client CA certification + */ +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) +{ +    SSL_ASSERT1(ctx); +    SSL_ASSERT1(x); +    assert(ctx); +    if (ctx->client_CA == x) +        return 1; + +    X509_free(ctx->client_CA); + +    ctx->client_CA = x; + +    return 1; +} + +/** + * @brief add CA client certification into the SSL + */ +int SSL_CTX_add_client_CA_ASN1(SSL_CTX *ctx, int len, +                const unsigned char *d) +{ +	X509 *x; + +	x = d2i_X509(NULL, d, len); +	if (!x) { +		SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL"); +		return 0; +	} +    SSL_ASSERT1(ctx); + +    X509_free(ctx->client_CA); + +    ctx->client_CA = x; + +    return 1; +} + +/** + * @brief add CA client certification into the SSL + */ +int SSL_add_client_CA(SSL *ssl, X509 *x) +{ +    SSL_ASSERT1(ssl); +    SSL_ASSERT1(x); + +    if (ssl->client_CA == x) +        return 1; + +    X509_free(ssl->client_CA); + +    ssl->client_CA = x; + +    return 1; +} + +/** + * @brief set the SSL context certification + */ +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) +{ +    SSL_ASSERT1(ctx); +    SSL_ASSERT1(x); + +    if (ctx->cert->x509 == x) +        return 1; + +    X509_free(ctx->cert->x509); + +    ctx->cert->x509 = x; + +    return 1; +} + +/** + * @brief set the SSL certification + */ +int SSL_use_certificate(SSL *ssl, X509 *x) +{ +    SSL_ASSERT1(ssl); +    SSL_ASSERT1(x); + +    if (ssl->cert->x509 == x) +        return 1; + +    X509_free(ssl->cert->x509); + +    ssl->cert->x509 = x; + +    return 1; +} + +/** + * @brief get the SSL certification point + */ +X509 *SSL_get_certificate(const SSL *ssl) +{ +    SSL_ASSERT2(ssl); + +    return ssl->cert->x509; +} + +/** + * @brief load certification into the SSL context + */ +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, +                                 const unsigned char *d) +{ +    int ret; +    X509 *x; + +    x = d2i_X509(NULL, d, len); +    if (!x) { +        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL"); +        goto failed1; +    } + +    ret = SSL_CTX_use_certificate(ctx, x); +    if (!ret) { +        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_CTX_use_certificate() return %d", ret); +        goto failed2; +    } + +    return 1; + +failed2: +    X509_free(x); +failed1: +    return 0; +} + +/** + * @brief load certification into the SSL + */ +int SSL_use_certificate_ASN1(SSL *ssl, int len, +                             const unsigned char *d) +{ +    int ret; +    X509 *x; + +    x = d2i_X509(NULL, d, len); +    if (!x) { +        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL"); +        goto failed1; +    } + +    ret = SSL_use_certificate(ssl, x); +    if (!ret) { +        SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_use_certificate() return %d", ret); +        goto failed2; +    } + +    return 1; + +failed2: +    X509_free(x); +failed1: +    return 0; +} + +/** + * @brief load the certification file into SSL context + */ +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) +{ +    return 0; +} + +/** + * @brief load the certification file into SSL + */ +int SSL_use_certificate_file(SSL *ssl, const char *file, int type) +{ +    return 0; +} + +/** + * @brief get peer certification + */ +X509 *SSL_get_peer_certificate(const SSL *ssl) +{ +    SSL_ASSERT2(ssl); + +    return ssl->session->peer; +} + +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) +{ +	return X509_V_ERR_UNSPECIFIED; +} + +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) +{ +	return 0; +} + +const char *X509_verify_cert_error_string(long n) +{ +	return "unknown"; +} diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/platform/ssl_pm.c b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/platform/ssl_pm.c new file mode 100755 index 0000000000..4716c1ff56 --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/platform/ssl_pm.c @@ -0,0 +1,907 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ssl_pm.h" +#include "ssl_port.h" +#include "ssl_dbg.h" + +/* mbedtls include */ +#include "mbedtls/platform.h" +#include "mbedtls/net_sockets.h" +#include "mbedtls/debug.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/error.h" +#include "mbedtls/certs.h" + +#include <libwebsockets.h> + +#define X509_INFO_STRING_LENGTH 8192 + +struct ssl_pm +{ +    /* local socket file description */ +    mbedtls_net_context fd; +    /* remote client socket file description */ +    mbedtls_net_context cl_fd; + +    mbedtls_ssl_config conf; + +    mbedtls_ctr_drbg_context ctr_drbg; + +    mbedtls_ssl_context ssl; + +    mbedtls_entropy_context entropy; + +    SSL *owner; +}; + +struct x509_pm +{ +    mbedtls_x509_crt *x509_crt; + +    mbedtls_x509_crt *ex_crt; +}; + +struct pkey_pm +{ +    mbedtls_pk_context *pkey; + +    mbedtls_pk_context *ex_pkey; +}; + +unsigned int max_content_len; + +/*********************************************************************************************/ +/************************************ SSL arch interface *************************************/ + +//#ifdef CONFIG_OPENSSL_LOWLEVEL_DEBUG + +/* mbedtls debug level */ +#define MBEDTLS_DEBUG_LEVEL 4 + +/** + * @brief mbedtls debug function + */ +static void ssl_platform_debug(void *ctx, int level, +                     const char *file, int line, +                     const char *str) +{ +    /* Shorten 'file' from the whole file path to just the filename + +       This is a bit wasteful because the macros are compiled in with +       the full _FILE_ path in each case. +    */ +//    char *file_sep = rindex(file, '/'); +  //  if(file_sep) +    //    file = file_sep + 1; + +    printf("%s:%d %s", file, line, str); +} +//#endif + +/** + * @brief create SSL low-level object + */ +int ssl_pm_new(SSL *ssl) +{ +    struct ssl_pm *ssl_pm; +    int ret; + +    const unsigned char pers[] = "OpenSSL PM"; +    size_t pers_len = sizeof(pers); + +    int endpoint; +    int version; + +    const SSL_METHOD *method = ssl->method; + +    ssl_pm = ssl_mem_zalloc(sizeof(struct ssl_pm)); +    if (!ssl_pm) { +        SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (ssl_pm)"); +        goto no_mem; +    } + +    ssl_pm->owner = ssl; + +    if (!ssl->ctx->read_buffer_len) +	    ssl->ctx->read_buffer_len = 2048; + +    max_content_len = ssl->ctx->read_buffer_len; +    // printf("ssl->ctx->read_buffer_len = %d ++++++++++++++++++++\n", ssl->ctx->read_buffer_len); + +    mbedtls_net_init(&ssl_pm->fd); +    mbedtls_net_init(&ssl_pm->cl_fd); + +    mbedtls_ssl_config_init(&ssl_pm->conf); +    mbedtls_ctr_drbg_init(&ssl_pm->ctr_drbg); +    mbedtls_entropy_init(&ssl_pm->entropy); +    mbedtls_ssl_init(&ssl_pm->ssl); + +    ret = mbedtls_ctr_drbg_seed(&ssl_pm->ctr_drbg, mbedtls_entropy_func, &ssl_pm->entropy, pers, pers_len); +    if (ret) { +        SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ctr_drbg_seed() return -0x%x", -ret); +        goto mbedtls_err1; +    } + +    if (method->endpoint) { +        endpoint = MBEDTLS_SSL_IS_SERVER; +    } else { +        endpoint = MBEDTLS_SSL_IS_CLIENT; +    } +    ret = mbedtls_ssl_config_defaults(&ssl_pm->conf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); +    if (ret) { +        SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_config_defaults() return -0x%x", -ret); +        goto mbedtls_err2; +    } + +    if (TLS_ANY_VERSION != ssl->version) { +        if (TLS1_2_VERSION == ssl->version) +            version = MBEDTLS_SSL_MINOR_VERSION_3; +        else if (TLS1_1_VERSION == ssl->version) +            version = MBEDTLS_SSL_MINOR_VERSION_2; +        else if (TLS1_VERSION == ssl->version) +            version = MBEDTLS_SSL_MINOR_VERSION_1; +        else +            version = MBEDTLS_SSL_MINOR_VERSION_0; + +        mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version); +        mbedtls_ssl_conf_min_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version); +    } else { +        mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); +        mbedtls_ssl_conf_min_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0); +    } + +    mbedtls_ssl_conf_rng(&ssl_pm->conf, mbedtls_ctr_drbg_random, &ssl_pm->ctr_drbg); + +//#ifdef CONFIG_OPENSSL_LOWLEVEL_DEBUG + //   mbedtls_debug_set_threshold(MBEDTLS_DEBUG_LEVEL); +//    mbedtls_ssl_conf_dbg(&ssl_pm->conf, ssl_platform_debug, NULL); +//#else +    mbedtls_ssl_conf_dbg(&ssl_pm->conf, ssl_platform_debug, NULL); +//#endif + +    ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf); +    if (ret) { +        SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_setup() return -0x%x", -ret); +        goto mbedtls_err2; +    } + +    mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd, mbedtls_net_send, mbedtls_net_recv, NULL); + +    ssl->ssl_pm = ssl_pm; + +    return 0; + +mbedtls_err2: +    mbedtls_ssl_config_free(&ssl_pm->conf); +    mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); +mbedtls_err1: +    mbedtls_entropy_free(&ssl_pm->entropy); +    ssl_mem_free(ssl_pm); +no_mem: +    return -1; +} + +/** + * @brief free SSL low-level object + */ +void ssl_pm_free(SSL *ssl) +{ +    struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + +    mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); +    mbedtls_entropy_free(&ssl_pm->entropy); +    mbedtls_ssl_config_free(&ssl_pm->conf); +    mbedtls_ssl_free(&ssl_pm->ssl); + +    ssl_mem_free(ssl_pm); +    ssl->ssl_pm = NULL; +} + +/** + * @brief reload SSL low-level certification object + */ +static int ssl_pm_reload_crt(SSL *ssl) +{ +    int ret; +    int mode; +    struct ssl_pm *ssl_pm = ssl->ssl_pm; +    struct x509_pm *ca_pm = (struct x509_pm *)ssl->client_CA->x509_pm; + +    struct pkey_pm *pkey_pm = (struct pkey_pm *)ssl->cert->pkey->pkey_pm; +    struct x509_pm *crt_pm = (struct x509_pm *)ssl->cert->x509->x509_pm; + +    if (ssl->verify_mode == SSL_VERIFY_PEER) +        mode = MBEDTLS_SSL_VERIFY_OPTIONAL; +    else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT) +        mode = MBEDTLS_SSL_VERIFY_OPTIONAL; +    else if (ssl->verify_mode == SSL_VERIFY_CLIENT_ONCE) +        mode = MBEDTLS_SSL_VERIFY_UNSET; +    else +        mode = MBEDTLS_SSL_VERIFY_NONE; + +    mbedtls_ssl_conf_authmode(&ssl_pm->conf, mode); + +    if (ca_pm->x509_crt) { +        mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->x509_crt, NULL); +    } else if (ca_pm->ex_crt) { +        mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->ex_crt, NULL); +    } + +    if (crt_pm->x509_crt && pkey_pm->pkey) { +        ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, crt_pm->x509_crt, pkey_pm->pkey); +    } else if (crt_pm->ex_crt && pkey_pm->ex_pkey) { +        ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, crt_pm->ex_crt, pkey_pm->ex_pkey); +    } else { +        ret = 0; +    } + +    if (ret) { +        SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_conf_own_cert() return -0x%x", -ret); +        ret = -1; +    } + +    return ret; +} + +/* + * Perform the mbedtls SSL handshake instead of mbedtls_ssl_handshake. + * We can add debug here. + */ +static int mbedtls_handshake( mbedtls_ssl_context *ssl ) +{ +    int ret = 0; + +    while (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { +        ret = mbedtls_ssl_handshake_step(ssl); + +        lwsl_info("%s: ssl ret -%x state %d\n", __func__, -ret, ssl->state); + +        if (ret != 0) +            break; +    } + +    return ret; +} + +#include <errno.h> + +int ssl_pm_handshake(SSL *ssl) +{ +    int ret; +    struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + +    ssl->err = 0; +    errno = 0; + +    ret = ssl_pm_reload_crt(ssl); +    if (ret) { +	    printf("%s: cert reload failed\n", __func__); +        return 0; +    } + +    if (ssl_pm->ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER) { +	    ssl_speed_up_enter(); + +	   /* mbedtls return codes +	    * 0 = successful, or MBEDTLS_ERR_SSL_WANT_READ/WRITE +	    * anything else = death +	    */ +	    ret = mbedtls_handshake(&ssl_pm->ssl); +	    ssl_speed_up_exit(); +    } else +	    ret = 0; + +    /* +     * OpenSSL return codes: +     *   0 = did not complete, but may be retried +     *   1 = successfully completed +     *   <0 = death +     */ +    if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { +	    ssl->err = ret; +        SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_handshake() return -0x%x", -ret); +        return 0; /* OpenSSL: did not complete but may be retried */ +    } + +    if (ret == 0) { /* successful */ +        struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm; + +        x509_pm->ex_crt = (mbedtls_x509_crt *)mbedtls_ssl_get_peer_cert(&ssl_pm->ssl); +        return 1; /* openssl successful */ +    } + +    if (errno == 11) { +	    ssl->err = ret == MBEDTLS_ERR_SSL_WANT_READ; + +	    return 0; +    } + +    printf("%s: mbedtls_ssl_handshake() returned -0x%x\n", __func__, -ret); + +    /* it's had it */ + +    ssl->err = SSL_ERROR_SYSCALL; + +    return -1; /* openssl death */ +} + +mbedtls_x509_crt * +ssl_ctx_get_mbedtls_x509_crt(SSL_CTX *ssl_ctx) +{ +	struct x509_pm *x509_pm = (struct x509_pm *)ssl_ctx->cert->x509->x509_pm; + +	if (!x509_pm) +		return NULL; + +	return x509_pm->x509_crt; +} + +mbedtls_x509_crt * +ssl_get_peer_mbedtls_x509_crt(SSL *ssl) +{ +	struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm; + +	if (!x509_pm) +		return NULL; + +	return x509_pm->ex_crt; +} + +int ssl_pm_shutdown(SSL *ssl) +{ +    int ret; +    struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + +    ret = mbedtls_ssl_close_notify(&ssl_pm->ssl); +    if (ret) { +        SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_close_notify() return -0x%x", -ret); +        if (ret == MBEDTLS_ERR_NET_CONN_RESET) +		ssl->err = SSL_ERROR_SYSCALL; +	 ret = -1; /* OpenSSL: "Call SSL_get_error with the return value to find the reason */ +    } else { +        struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm; + +        x509_pm->ex_crt = NULL; +        ret = 1; /* OpenSSL: "The shutdown was successfully completed" +		     ...0 means retry */ +    } + +    return ret; +} + +int ssl_pm_clear(SSL *ssl) +{ +    return ssl_pm_shutdown(ssl); +} + + +int ssl_pm_read(SSL *ssl, void *buffer, int len) +{ +    int ret; +    struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + +    ret = mbedtls_ssl_read(&ssl_pm->ssl, buffer, len); +    if (ret < 0) { +	 //   lwsl_notice("%s: mbedtls_ssl_read says -0x%x\n", __func__, -ret); +        SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_read() return -0x%x", -ret); +        if (ret == MBEDTLS_ERR_NET_CONN_RESET || +            ret <= MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) /* fatal errors */ +		ssl->err = SSL_ERROR_SYSCALL; +        ret = -1; +    } + +    return ret; +} + +/* + * This returns -1, or the length sent. + * If -1, then you need to find out if the error was + * fatal or recoverable using SSL_get_error() + */ +int ssl_pm_send(SSL *ssl, const void *buffer, int len) +{ +    int ret; +    struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + +    ret = mbedtls_ssl_write(&ssl_pm->ssl, buffer, len); +    /* +     * We can get a positive number, which may be less than len... that +     * much was sent successfully and you can call again to send more. +     * +     * We can get a negative mbedtls error code... if WANT_WRITE or WANT_READ, +     * it's nonfatal and means it should be retried as-is.  If something else, +     * it's fatal actually. +     * +     * If this function returns something other than a positive value or +     * MBEDTLS_ERR_SSL_WANT_READ/WRITE, the ssl context becomes unusable, and +     * you should either free it or call mbedtls_ssl_session_reset() on it +     * before re-using it for a new connection; the current connection must +     * be closed. +     * +     * When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ, it must be +     * called later with the same arguments, until it returns a positive value. +     */ + +    if (ret < 0) { +	    SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_write() return -0x%x", -ret); +	switch (ret) { +	case MBEDTLS_ERR_NET_SEND_FAILED: +	case MBEDTLS_ERR_NET_CONN_RESET: +		ssl->err = SSL_ERROR_SYSCALL; +		break; +	case MBEDTLS_ERR_SSL_WANT_WRITE: +		ssl->err = SSL_ERROR_WANT_WRITE; +		break; +	case MBEDTLS_ERR_SSL_WANT_READ: +		ssl->err = SSL_ERROR_WANT_READ; +		break; +	default: +		break; +	} + +	ret = -1; +    } + +    return ret; +} + +int ssl_pm_pending(const SSL *ssl) +{ +    struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + +    return mbedtls_ssl_get_bytes_avail(&ssl_pm->ssl); +} + +void ssl_pm_set_fd(SSL *ssl, int fd, int mode) +{ +    struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + +    ssl_pm->fd.fd = fd; +} + +int ssl_pm_get_fd(const SSL *ssl, int mode) +{ +    struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + +    return ssl_pm->fd.fd; +} + +OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl) +{ +    OSSL_HANDSHAKE_STATE state; + +    struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + +    switch (ssl_pm->ssl.state) +    { +        case MBEDTLS_SSL_CLIENT_HELLO: +            state = TLS_ST_CW_CLNT_HELLO; +            break; +        case MBEDTLS_SSL_SERVER_HELLO: +            state = TLS_ST_SW_SRVR_HELLO; +            break; +        case MBEDTLS_SSL_SERVER_CERTIFICATE: +            state = TLS_ST_SW_CERT; +            break; +        case MBEDTLS_SSL_SERVER_HELLO_DONE: +            state = TLS_ST_SW_SRVR_DONE; +            break; +        case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: +            state = TLS_ST_CW_KEY_EXCH; +            break; +        case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: +            state = TLS_ST_CW_CHANGE; +            break; +        case MBEDTLS_SSL_CLIENT_FINISHED: +            state = TLS_ST_CW_FINISHED; +            break; +        case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: +            state = TLS_ST_SW_CHANGE; +            break; +        case MBEDTLS_SSL_SERVER_FINISHED: +            state = TLS_ST_SW_FINISHED; +            break; +        case MBEDTLS_SSL_CLIENT_CERTIFICATE: +            state = TLS_ST_CW_CERT; +            break; +        case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: +            state = TLS_ST_SR_KEY_EXCH; +            break; +        case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET: +            state = TLS_ST_SW_SESSION_TICKET; +            break; +        case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT: +            state = TLS_ST_SW_CERT_REQ; +            break; +        case MBEDTLS_SSL_HANDSHAKE_OVER: +            state = TLS_ST_OK; +            break; +        default : +            state = TLS_ST_BEFORE; +            break; +    } + +    return state; +} + +int x509_pm_show_info(X509 *x) +{ +    int ret; +    char *buf; +    mbedtls_x509_crt *x509_crt; +    struct x509_pm *x509_pm = x->x509_pm; + +    if (x509_pm->x509_crt) +        x509_crt = x509_pm->x509_crt; +    else if (x509_pm->ex_crt) +        x509_crt = x509_pm->ex_crt; +    else +        x509_crt = NULL; + +    if (!x509_crt) +        return -1; + +    buf = ssl_mem_malloc(X509_INFO_STRING_LENGTH); +    if (!buf) { +        SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (buf)"); +        goto no_mem; +    } + +    ret = mbedtls_x509_crt_info(buf, X509_INFO_STRING_LENGTH - 1, "", x509_crt); +    if (ret <= 0) { +        SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_x509_crt_info() return -0x%x", -ret); +        goto mbedtls_err1; +    } + +    buf[ret] = 0; + +    ssl_mem_free(buf); + +    SSL_DEBUG(SSL_DEBUG_ON, "%s", buf); + +    return 0; + +mbedtls_err1: +    ssl_mem_free(buf); +no_mem: +    return -1; +} + +int x509_pm_new(X509 *x, X509 *m_x) +{ +    struct x509_pm *x509_pm; + +    x509_pm = ssl_mem_zalloc(sizeof(struct x509_pm)); +    if (!x509_pm) { +        SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (x509_pm)"); +        goto failed1; +    } + +    x->x509_pm = x509_pm; + +    if (m_x) { +        struct x509_pm *m_x509_pm = (struct x509_pm *)m_x->x509_pm; + +        x509_pm->ex_crt = m_x509_pm->x509_crt; +    } + +    return 0; + +failed1: +    return -1; +} + +void x509_pm_free(X509 *x) +{ +    struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; + +    if (x509_pm->x509_crt) { +        mbedtls_x509_crt_free(x509_pm->x509_crt); + +        ssl_mem_free(x509_pm->x509_crt); +        x509_pm->x509_crt = NULL; +    } + +    ssl_mem_free(x->x509_pm); +    x->x509_pm = NULL; +} + +int x509_pm_load(X509 *x, const unsigned char *buffer, int len) +{ +    int ret; +    unsigned char *load_buf; +    struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; + +	if (x509_pm->x509_crt) +        mbedtls_x509_crt_free(x509_pm->x509_crt); + +    if (!x509_pm->x509_crt) { +        x509_pm->x509_crt = ssl_mem_malloc(sizeof(mbedtls_x509_crt)); +        if (!x509_pm->x509_crt) { +            SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (x509_pm->x509_crt)"); +            goto no_mem; +        } +    } + +    mbedtls_x509_crt_init(x509_pm->x509_crt); +    if (buffer[0] != 0x30) { +	    load_buf = ssl_mem_malloc(len + 1); +	    if (!load_buf) { +		SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (load_buf)"); +		goto failed; +	    } + +	    ssl_memcpy(load_buf, buffer, len); +	    load_buf[len] = '\0'; + +	    ret = mbedtls_x509_crt_parse(x509_pm->x509_crt, load_buf, len + 1); +	    ssl_mem_free(load_buf); +    } else { +	    printf("parsing as der\n"); + +	    ret = mbedtls_x509_crt_parse_der(x509_pm->x509_crt, buffer, len); +    } + +    if (ret) { +        printf("mbedtls_x509_crt_parse return -0x%x", -ret); +        goto failed; +    } + +    return 0; + +failed: +    mbedtls_x509_crt_free(x509_pm->x509_crt); +    ssl_mem_free(x509_pm->x509_crt); +    x509_pm->x509_crt = NULL; +no_mem: +    return -1; +} + +int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pkey) +{ +    struct pkey_pm *pkey_pm; + +    pkey_pm = ssl_mem_zalloc(sizeof(struct pkey_pm)); +    if (!pkey_pm) +        return -1; + +    pk->pkey_pm = pkey_pm; + +    if (m_pkey) { +        struct pkey_pm *m_pkey_pm = (struct pkey_pm *)m_pkey->pkey_pm; + +        pkey_pm->ex_pkey = m_pkey_pm->pkey; +    } + +    return 0; +} + +void pkey_pm_free(EVP_PKEY *pk) +{ +    struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm; + +    if (pkey_pm->pkey) { +        mbedtls_pk_free(pkey_pm->pkey); + +        ssl_mem_free(pkey_pm->pkey); +        pkey_pm->pkey = NULL; +    } + +    ssl_mem_free(pk->pkey_pm); +    pk->pkey_pm = NULL; +} + +int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len) +{ +    int ret; +    unsigned char *load_buf; +    struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm; + +    if (pkey_pm->pkey) +        mbedtls_pk_free(pkey_pm->pkey); + +    if (!pkey_pm->pkey) { +        pkey_pm->pkey = ssl_mem_malloc(sizeof(mbedtls_pk_context)); +        if (!pkey_pm->pkey) { +            SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (pkey_pm->pkey)"); +            goto no_mem; +        } +    } + +    load_buf = ssl_mem_malloc(len + 1); +    if (!load_buf) { +        SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (load_buf)"); +        goto failed; +    } + +    ssl_memcpy(load_buf, buffer, len); +    load_buf[len] = '\0'; + +    mbedtls_pk_init(pkey_pm->pkey); + +    ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, len + 1, NULL, 0); +    ssl_mem_free(load_buf); + +    if (ret) { +        SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_pk_parse_key return -0x%x", -ret); +        goto failed; +    } + +    return 0; + +failed: +    mbedtls_pk_free(pkey_pm->pkey); +    ssl_mem_free(pkey_pm->pkey); +    pkey_pm->pkey = NULL; +no_mem: +    return -1; +} + + + +void ssl_pm_set_bufflen(SSL *ssl, int len) +{ +    max_content_len = len; +} + +long ssl_pm_get_verify_result(const SSL *ssl) +{ +	uint32_t ret; +	long verify_result; +	struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + +	ret = mbedtls_ssl_get_verify_result(&ssl_pm->ssl); +	if (!ret) +		return X509_V_OK; + +	if (ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED || +		(ret & MBEDTLS_X509_BADCRL_NOT_TRUSTED)) +		verify_result = X509_V_ERR_INVALID_CA; + +	else if (ret & MBEDTLS_X509_BADCERT_CN_MISMATCH) +		verify_result = X509_V_ERR_HOSTNAME_MISMATCH; + +	else if ((ret & MBEDTLS_X509_BADCERT_BAD_KEY) || +		(ret & MBEDTLS_X509_BADCRL_BAD_KEY)) +		verify_result = X509_V_ERR_CA_KEY_TOO_SMALL; + +	else if ((ret & MBEDTLS_X509_BADCERT_BAD_MD) || +		(ret & MBEDTLS_X509_BADCRL_BAD_MD)) +		verify_result = X509_V_ERR_CA_MD_TOO_WEAK; + +	else if ((ret & MBEDTLS_X509_BADCERT_FUTURE) || +		(ret & MBEDTLS_X509_BADCRL_FUTURE)) +		verify_result = X509_V_ERR_CERT_NOT_YET_VALID; + +	else if ((ret & MBEDTLS_X509_BADCERT_EXPIRED) || +		(ret & MBEDTLS_X509_BADCRL_EXPIRED)) +		verify_result = X509_V_ERR_CERT_HAS_EXPIRED; + +	else +		verify_result = X509_V_ERR_UNSPECIFIED; + +	SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, +		  "mbedtls_ssl_get_verify_result() return 0x%x", ret); + +	return verify_result; +} + +/** + * @brief set expected hostname on peer cert CN + */ + +int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, +                                const char *name, size_t namelen) +{ +	SSL *ssl = (SSL *)((char *)param - offsetof(SSL, param)); +	struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; +	char *name_cstr = NULL; + +	if (namelen) { +		name_cstr = malloc(namelen + 1); +		if (!name_cstr) +			return 0; +		memcpy(name_cstr, name, namelen); +		name_cstr[namelen] = '\0'; +		name = name_cstr; +	} + +	mbedtls_ssl_set_hostname(&ssl_pm->ssl, name); + +	if (namelen) +		free(name_cstr); + +	return 1; +} + +void _ssl_set_alpn_list(const SSL *ssl) +{ +	if (ssl->alpn_protos) { +		if (mbedtls_ssl_conf_alpn_protocols(&((struct ssl_pm *)(ssl->ssl_pm))->conf, ssl->alpn_protos)) +			fprintf(stderr, "mbedtls_ssl_conf_alpn_protocols failed\n"); + +		return; +	} +	if (!ssl->ctx->alpn_protos) +		return; +	if (mbedtls_ssl_conf_alpn_protocols(&((struct ssl_pm *)(ssl->ssl_pm))->conf, ssl->ctx->alpn_protos)) +		fprintf(stderr, "mbedtls_ssl_conf_alpn_protocols failed\n"); +} + +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, +                            unsigned int *len) +{ +	const char *alp = mbedtls_ssl_get_alpn_protocol(&((struct ssl_pm *)(ssl->ssl_pm))->ssl); + +	*data = (const unsigned char *)alp; +	if (alp) +		*len = strlen(alp); +	else +		*len = 0; +} + +int SSL_set_sni_callback(SSL *ssl, int(*cb)(void *, mbedtls_ssl_context *, +			 const unsigned char *, size_t), void *param) +{ +	struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + +	mbedtls_ssl_conf_sni(&ssl_pm->conf, cb, param); + +	return 0; +} + +SSL *SSL_SSL_from_mbedtls_ssl_context(mbedtls_ssl_context *msc) +{ +	struct ssl_pm *ssl_pm = (struct ssl_pm *)((char *)msc - offsetof(struct ssl_pm, ssl)); + +	return ssl_pm->owner; +} + +#include "ssl_cert.h" + +void SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) +{ +	struct ssl_pm *ssl_pm = ssl->ssl_pm; +	struct x509_pm *x509_pm = (struct x509_pm *)ctx->cert->x509->x509_pm; +	struct x509_pm *x509_pm_ca = (struct x509_pm *)ctx->client_CA->x509_pm; + +	struct pkey_pm *pkey_pm = (struct pkey_pm *)ctx->cert->pkey->pkey_pm; +	int mode; + +	if (ssl->cert) +		ssl_cert_free(ssl->cert); +	ssl->ctx = ctx; +	ssl->cert = __ssl_cert_new(ctx->cert); + +	if (ctx->verify_mode == SSL_VERIFY_PEER) +		mode = MBEDTLS_SSL_VERIFY_OPTIONAL; +	else if (ctx->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT) +		mode = MBEDTLS_SSL_VERIFY_OPTIONAL; +	else if (ctx->verify_mode == SSL_VERIFY_CLIENT_ONCE) +		mode = MBEDTLS_SSL_VERIFY_UNSET; +	else +	        mode = MBEDTLS_SSL_VERIFY_NONE; + +	    // printf("ssl: %p, client ca x509_crt %p, mbedtls mode %d\n", ssl, x509_pm_ca->x509_crt, mode); + +	/* apply new ctx cert to ssl */ + +	ssl->verify_mode = ctx->verify_mode; + +	mbedtls_ssl_set_hs_ca_chain(&ssl_pm->ssl, x509_pm_ca->x509_crt, NULL); +	mbedtls_ssl_set_hs_own_cert(&ssl_pm->ssl, x509_pm->x509_crt, pkey_pm->pkey); +	mbedtls_ssl_set_hs_authmode(&ssl_pm->ssl, mode); +} diff --git a/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/platform/ssl_port.c b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/platform/ssl_port.c new file mode 100644 index 0000000000..8c7a31338b --- /dev/null +++ b/thirdparty/libwebsockets/lib/tls/mbedtls/wrapper/platform/ssl_port.c @@ -0,0 +1,29 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +//     http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ssl_port.h" + +/*********************************************************************************************/ +/********************************* SSL general interface *************************************/ + +void *ssl_mem_zalloc(size_t size) +{ +    void *p = malloc(size); + +    if (p) +        memset(p, 0, size); + +    return p; +} + |