From 44c466c0ea077a28fa138edfdaed400c2b3bd416 Mon Sep 17 00:00:00 2001 From: dongheng Date: Tue, 20 Sep 2016 16:58:46 +0800 Subject: [PATCH] components/openssl: add base function version --- components/openssl/Makefile | 50 + components/openssl/include/internal/ssl3.h | 22 + .../openssl/include/internal/ssl_cert.h | 11 + .../openssl/include/internal/ssl_code.h | 95 + components/openssl/include/internal/ssl_dbg.h | 33 + components/openssl/include/internal/ssl_lib.h | 11 + .../openssl/include/internal/ssl_methods.h | 46 + .../openssl/include/internal/ssl_pkey.h | 11 + components/openssl/include/internal/ssl_rsa.h | 14 + .../openssl/include/internal/ssl_types.h | 190 ++ .../openssl/include/internal/ssl_x509.h | 12 + components/openssl/include/internal/tls1.h | 33 + components/openssl/include/openssl/ssl.h | 31 +- components/openssl/include/platform/ssl_pm.h | 41 + components/openssl/library/Makefile | 46 + components/openssl/library/ssl_cert.c | 28 + components/openssl/library/ssl_lib.c | 1622 +++++++++++++++++ components/openssl/library/ssl_methods.c | 43 + components/openssl/library/ssl_pkey.c | 50 + components/openssl/library/ssl_rsa.c | 70 + components/openssl/library/ssl_x509.c | 54 + components/openssl/platform/Makefile | 46 + components/openssl/platform/ssl_pm.c | 422 +++++ 23 files changed, 2976 insertions(+), 5 deletions(-) create mode 100644 components/openssl/Makefile create mode 100644 components/openssl/include/internal/ssl3.h create mode 100644 components/openssl/include/internal/ssl_cert.h create mode 100644 components/openssl/include/internal/ssl_code.h create mode 100644 components/openssl/include/internal/ssl_dbg.h create mode 100644 components/openssl/include/internal/ssl_lib.h create mode 100644 components/openssl/include/internal/ssl_methods.h create mode 100644 components/openssl/include/internal/ssl_pkey.h create mode 100644 components/openssl/include/internal/ssl_rsa.h create mode 100644 components/openssl/include/internal/ssl_types.h create mode 100644 components/openssl/include/internal/ssl_x509.h create mode 100644 components/openssl/include/internal/tls1.h create mode 100644 components/openssl/include/platform/ssl_pm.h create mode 100644 components/openssl/library/Makefile create mode 100644 components/openssl/library/ssl_cert.c create mode 100644 components/openssl/library/ssl_lib.c create mode 100644 components/openssl/library/ssl_methods.c create mode 100644 components/openssl/library/ssl_pkey.c create mode 100644 components/openssl/library/ssl_rsa.c create mode 100644 components/openssl/library/ssl_x509.c create mode 100644 components/openssl/platform/Makefile create mode 100644 components/openssl/platform/ssl_pm.c diff --git a/components/openssl/Makefile b/components/openssl/Makefile new file mode 100644 index 0000000000..bdd8a0e932 --- /dev/null +++ b/components/openssl/Makefile @@ -0,0 +1,50 @@ + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +UP_EXTRACT_DIR = .. +GEN_LIBS = libopenssl.a +COMPONENTS_libopenssl = library/liblibrary.a platform/libplatform.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include -I $(PDIR)include/platform -I $(PDIR)include/internal +INCLUDES += -I ./inlcude +INCLUDES += -I $(SDK_PATH)/include/openssl/internal +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/components/openssl/include/internal/ssl3.h b/components/openssl/include/internal/ssl3.h new file mode 100644 index 0000000000..d7c254563b --- /dev/null +++ b/components/openssl/include/internal/ssl3.h @@ -0,0 +1,22 @@ +#ifndef _SSL3_H_ +#define _SSL3_H_ + +# 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 + +#endif diff --git a/components/openssl/include/internal/ssl_cert.h b/components/openssl/include/internal/ssl_cert.h new file mode 100644 index 0000000000..e0b3ea75dc --- /dev/null +++ b/components/openssl/include/internal/ssl_cert.h @@ -0,0 +1,11 @@ +#ifndef _SSL_CERT_H_ +#define _SSL_CERT_H_ + +#include "ssl_pkey.h" +#include "ssl_x509.h" + +CERT *ssl_cert_new(void); + +void ssl_cert_free(CERT *c); + +#endif diff --git a/components/openssl/include/internal/ssl_code.h b/components/openssl/include/internal/ssl_code.h new file mode 100644 index 0000000000..d45abff680 --- /dev/null +++ b/components/openssl/include/internal/ssl_code.h @@ -0,0 +1,95 @@ +#ifndef _SSL_CODE_H_ +#define _SSL_CODE_H_ + +#include "ssl3.h" +#include "tls1.h" + +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ +# define SSL_SENT_SHUTDOWN 1 +# define SSL_RECEIVED_SHUTDOWN 2 + +/* + * 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; + +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; + +#endif diff --git a/components/openssl/include/internal/ssl_dbg.h b/components/openssl/include/internal/ssl_dbg.h new file mode 100644 index 0000000000..436d33132f --- /dev/null +++ b/components/openssl/include/internal/ssl_dbg.h @@ -0,0 +1,33 @@ +#ifndef _SSL_DEBUG_H_ +#define _SSL_DEBUG_H_ + +#define SSL_DEBUG_ENBALE 0 +#define SSL_DEBUG_LEVEL 0 +#define SSL_ASSERT_ENABLE 1 +#define SSL_DEBUG_LOCATION_ENABLE 1 + +#if SSL_DEBUG_ENBALE + #define SSL_PRINT os_printf +#else + #define SSL_PRINT(...) +#endif + +#if SSL_DEBUG_LOCATION_ENABLE + #define SSL_DEBUG_LOCATION() SSL_PRINT("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__) +#else + #define SSL_DEBUG_LOCATION() +#endif + +#if SSL_ASSERT_ENABLE + #define SSL_ASSERT(s) { if (!(s)) { SSL_DEBUG_LOCATION(); } } +#else + #define SSL_ASSERT(s) +#endif + +#define SSL_ERR(err, go, ...) { SSL_DEBUG_LOCATION(); SSL_PRINT(__VA_ARGS__); ret = err; goto go; } + +#define SSL_RET(go, ...) { SSL_DEBUG_LOCATION(); SSL_PRINT(__VA_ARGS__); goto go; } + +#define SSL_DEBUG(level, ...) { if (level > SSL_DEBUG_LEVEL) {SSL_PRINT(__VA_ARGS__);} } + +#endif diff --git a/components/openssl/include/internal/ssl_lib.h b/components/openssl/include/internal/ssl_lib.h new file mode 100644 index 0000000000..d95d219556 --- /dev/null +++ b/components/openssl/include/internal/ssl_lib.h @@ -0,0 +1,11 @@ +#ifndef _SSL_LIB_H_ +#define _SSL_LIB_H_ + +#include "ssl_types.h" + +#define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +#define SSL_want_read(s) (SSL_want(s) == SSL_READING) +#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) +#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_WRITING) + +#endif diff --git a/components/openssl/include/internal/ssl_methods.h b/components/openssl/include/internal/ssl_methods.h new file mode 100644 index 0000000000..e2806f177a --- /dev/null +++ b/components/openssl/include/internal/ssl_methods.h @@ -0,0 +1,46 @@ +#ifndef _SSL_METHODS_H_ +#define _SSL_METHODS_H_ + +#define IMPLEMENT_TLS_METHOD_FUNC(func_name, \ + new, free, \ + handshake, shutdown, clear, \ + read, send, pending, \ + set_fd, get_fd, \ + set_bufflen, \ + get_state) \ + static const SSL_METHOD_FUNC func_name = { \ + new, \ + free, \ + handshake, \ + shutdown, \ + clear, \ + read, \ + send, \ + pending, \ + set_fd, \ + get_fd, \ + set_bufflen, \ + get_state \ + }; + +#define IMPLEMENT_TLS_METHOD(ver, mode, fun, func_name) \ + const SSL_METHOD* func_name(void) { \ + static const SSL_METHOD func_name##_data = { \ + 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 = { \ + ver, \ + mode, \ + &(fun), \ + }; \ + return &func_name##_data; \ + } + +#endif diff --git a/components/openssl/include/internal/ssl_pkey.h b/components/openssl/include/internal/ssl_pkey.h new file mode 100644 index 0000000000..cc870e18ed --- /dev/null +++ b/components/openssl/include/internal/ssl_pkey.h @@ -0,0 +1,11 @@ +#ifndef _SSL_PKEY_H_ +#define _SSL_PKEY_H_ + +#include "ssl_types.h" + +EVP_PKEY *d2i_PrivateKey(int type, + EVP_PKEY **a, + const unsigned char **pp, + long length); + +#endif diff --git a/components/openssl/include/internal/ssl_rsa.h b/components/openssl/include/internal/ssl_rsa.h new file mode 100644 index 0000000000..7530bde734 --- /dev/null +++ b/components/openssl/include/internal/ssl_rsa.h @@ -0,0 +1,14 @@ +#ifndef _SSL_RSA_H_ +#define _SSL_RSA_H_ + +#include "ssl_lib.h" + +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d); + +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, + const unsigned char *d, long len); + +#endif diff --git a/components/openssl/include/internal/ssl_types.h b/components/openssl/include/internal/ssl_types.h new file mode 100644 index 0000000000..19eb6cb165 --- /dev/null +++ b/components/openssl/include/internal/ssl_types.h @@ -0,0 +1,190 @@ +#ifndef _SSL_TYPES_H_ +#define _SSL_TYPES_H_ + +#include "ssl_code.h" +#include + +typedef void SSL_CIPHER; + +typedef void X509_STORE_CTX; +typedef void X509_NAME; +typedef void X509_STORE; + +typedef void RSA; + +typedef void STACK; +typedef void BIO; + +#define STACK_OF(x) x + +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 evp_pkey_st; +typedef struct evp_pkey_st EVP_PKEY; + +struct evp_pkey_st { + + void *pkey_pm; +}; + +struct x509_st { + + /* X509 certification platform private point */ + void *x509_pm; +}; + +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; +}; + +struct ssl_ctx_st +{ + int version; + + int references; + + unsigned long options; + + #if 0 + struct alpn_protocols alpn_protocol; + #endif + + const SSL_METHOD *method; + + CERT *cert; + + X509 *client_CA; + + int verify_mode; + + long session_timeout; + + int read_ahead; +}; + +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; + + SSL_CTX *ctx; + + const SSL_METHOD *method; + + RECORD_LAYER rlayer; + + /* where we are */ + OSSL_STATEM statem; + + SSL_SESSION session; + + int rwstate; + + 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); + + OSSL_HANDSHAKE_STATE (*ssl_get_state)(const SSL *ssl); +}; + +typedef int (*next_proto_cb)(SSL *ssl, unsigned char **out, + unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg); + +#endif diff --git a/components/openssl/include/internal/ssl_x509.h b/components/openssl/include/internal/ssl_x509.h new file mode 100644 index 0000000000..28a7baf513 --- /dev/null +++ b/components/openssl/include/internal/ssl_x509.h @@ -0,0 +1,12 @@ +#ifndef _SSL_X509_H_ +#define _SSL_X509_H_ + +#include "ssl_types.h" + +X509* sk_X509_NAME_new_null(void); + +X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); + +void X509_free(X509 *cert); + +#endif diff --git a/components/openssl/include/internal/tls1.h b/components/openssl/include/internal/tls1.h new file mode 100644 index 0000000000..70de22bb5b --- /dev/null +++ b/components/openssl/include/internal/tls1.h @@ -0,0 +1,33 @@ +#ifndef _TLS1_H_ +#define _TLS1_H_ + +# 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 + +#endif diff --git a/components/openssl/include/openssl/ssl.h b/components/openssl/include/openssl/ssl.h index b7b784fe71..89cb5bb9f7 100644 --- a/components/openssl/include/openssl/ssl.h +++ b/components/openssl/include/openssl/ssl.h @@ -1,7 +1,7 @@ #ifndef HEADER_SSL_H #define HEADER_SSL_H -#include "ssl_types.h" +#include "internal/ssl_types.h" /* { @@ -186,6 +186,15 @@ const SSL_METHOD* SSLv3_client_method(void); */ const SSL_METHOD* TLSv1_1_client_method(void); +/* + * TLSv1_1_client_method - 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); + /* * SSLv23_server_method - create the target SSL context server method @@ -205,6 +214,15 @@ const SSL_METHOD* SSLv23_server_method(void); */ const SSL_METHOD* TLSv1_1_server_method(void); +/* + * TLSv1_1_server_method - 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); + /* * TLSv1_server_method - create the target SSL context server method * @@ -774,7 +792,7 @@ int SSL_get_wfd(const SSL *ssl); * SSL_set_read_ahead - set the SSL if we can read as many as data * * @param ssl - SSL point - * @param yes - enbale the function + * @param yes - enable the function * * @return none */ @@ -813,7 +831,9 @@ long SSL_CTX_get_read_ahead(SSL_CTX *ctx); * * @param ssl - SSL point * - * @return SSL context ahead signal + * @return + * 1 : there are bytes to be read + * 0 : no data */ int SSL_has_pending(const SSL *ssl); @@ -840,7 +860,7 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);//loads the certificate x int * 1 : OK * 0 : failed */ -int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, unsigned char *d); +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); /* * SSL_CTX_use_certificate_file - load the certification file into SSL context @@ -879,7 +899,7 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); * 1 : OK * 0 : failed */ -int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, unsigned char *d, long len);//adds the private key of type pk stored at memory location d (length len) to ctx +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 /* * SSL_CTX_use_certificate_file - load the private key file into SSL context @@ -1648,4 +1668,5 @@ const char *SSL_get_psk_identity_hint(SSL *ssl); */ const char *SSL_get_psk_identity(SSL *ssl); + #endif diff --git a/components/openssl/include/platform/ssl_pm.h b/components/openssl/include/platform/ssl_pm.h new file mode 100644 index 0000000000..c75ae95af5 --- /dev/null +++ b/components/openssl/include/platform/ssl_pm.h @@ -0,0 +1,41 @@ +#ifndef _SSL_PM_H_ +#define _SSL_PM_H_ + +#include "ssl_types.h" +#include "esp_common.h" + +void* ssl_zalloc(size_t size); +void *ssl_malloc(size_t size); +void ssl_free(void *p); +void* ssl_memcpy(void *to, const void *from, size_t size); + +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); + +void* x509_pm_new(void); +void x509_pm_free(void *pm); +int x509_pm_load_crt(void *pm, const unsigned char *buffer, int len); +void x509_pm_unload_crt(void *pm); +void x509_pm_start_ca(void *ssl, void *pm); + +void* pkey_pm_new(void); +void pkey_pm_free(void *pm); +int pkey_pm_load_crt(void *pm, const unsigned char *buffer, int len); +void pkey_pm_unload_crt(void *pm); + +#endif diff --git a/components/openssl/library/Makefile b/components/openssl/library/Makefile new file mode 100644 index 0000000000..10f4067c64 --- /dev/null +++ b/components/openssl/library/Makefile @@ -0,0 +1,46 @@ + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +GEN_LIBS = liblibrary.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/components/openssl/library/ssl_cert.c b/components/openssl/library/ssl_cert.c new file mode 100644 index 0000000000..10f723bfcb --- /dev/null +++ b/components/openssl/library/ssl_cert.c @@ -0,0 +1,28 @@ +#include "ssl_cert.h" +#include "ssl_pm.h" + +CERT *ssl_cert_new(void) +{ + return ssl_zalloc(sizeof(CERT)); +} + +void ssl_cert_free(CERT *c) +{ + if (c->x509) + X509_free(c->x509); + + if (c->pkey) + EVP_PKEY_free(c->pkey); + + ssl_free(c); +} + +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(x); + + ctx->client_CA = x; + + return 1; +} diff --git a/components/openssl/library/ssl_lib.c b/components/openssl/library/ssl_lib.c new file mode 100644 index 0000000000..ad78f3961a --- /dev/null +++ b/components/openssl/library/ssl_lib.c @@ -0,0 +1,1622 @@ +#include "ssl_lib.h" +#include "ssl_pkey.h" +#include "ssl_cert.h" +#include "ssl_dbg.h" +#include "ssl_pm.h" + +#define SSL_SEND_DATA_MAX_LENGTH 1460 + +static int ossl_statem_in_error(const SSL *ssl) +{ + if (ssl->statem.state == MSG_FLOW_ERROR) + return 1; + + return 0; +} + +/* + * SSL_get_error - 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) +{ + int ret = SSL_ERROR_SYSCALL; + + SSL_ASSERT(ssl); + + if (ret_code > 0) + ret = SSL_ERROR_NONE; + else if (ret_code < 0) + { + if (SSL_want_read(ssl)) + ret = SSL_ERROR_WANT_READ; + else if (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; +} + +/* + * SSL_get_state - get the SSL state + * + * @param ssl - SSL point + * + * @return SSL state + */ +OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl) +{ + OSSL_HANDSHAKE_STATE state; + + SSL_ASSERT(ssl); + + state = ssl->method->func->ssl_get_state(ssl); + + return state; +} + +/* + * SSL_CTX_new - create a SSL context + * + * @param method - the SSL context configuration file + * + * @return the context point, if create failed return NULL + */ +SSL_CTX* SSL_CTX_new(const SSL_METHOD *method) +{ + int ret; + SSL_CTX *ctx; + CERT *cert; + X509 *client_ca; + + if (!method) SSL_RET(go_failed1, "method\n"); + + client_ca = sk_X509_NAME_new_null(); + if (!client_ca) + SSL_ERR(-2, go_failed1, "ssl_ctx_new:ctx:[%d]\n", ret); + + cert = ssl_cert_new(); + if (!cert) + SSL_ERR(-2, go_failed2, "ssl_ctx_new:ctx:[%d]\n", ret); + + ctx = (SSL_CTX *)ssl_zalloc(sizeof(SSL_CTX)); + if (!ctx) + SSL_ERR(-2, go_failed3, "ssl_ctx_new:ctx:[%d]\n", ret); + + ctx->method = method; + ctx->cert = cert; + ctx->client_CA = client_ca; + + ctx->version = method->version; + + return ctx; + +go_failed3: + ssl_cert_free(cert); +go_failed2: + X509_free(client_ca); +go_failed1: + return NULL; +} + +/* + * SSL_CTX_free - free a SSL context + * + * @param method - the SSL context point + * + * @return none + */ +void SSL_CTX_free(SSL_CTX* ctx) +{ + SSL_ASSERT(ctx); + + ssl_cert_free(ctx->cert); + + X509_free(ctx->client_CA); + + ssl_free(ctx); +} + +/* + * SSL_CTX_set_ssl_version - set the SSL context version + * + * @param ctx - SSL context point + * @param meth - SSL method point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(meth); + + ctx->method = meth; + + return 1; +} + +/* + * SSL_CTX_get_ssl_method - 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) +{ + SSL_ASSERT(ctx); + + return ctx->method; +} + +/* + * SSL_new - create a SSL + * + * @param ctx - the SSL context point + * + * @return the SSL point or NULL if failed + */ +SSL *SSL_new(SSL_CTX *ctx) +{ + int ret; + void *ssl_pm; + SSL *ssl; + + if (!ctx) + SSL_RET(failed1, "ctx:NULL\n"); + + ssl = (SSL *)ssl_zalloc(sizeof(SSL)); + if (!ssl) + SSL_RET(failed1, "ssl_zalloc\n"); + + ssl->ctx = ctx; + ssl->method = ctx->method; + + ssl->version = ctx->version; + ssl->options = ctx->options; + + ret = ssl->method->func->ssl_new(ssl); + if (ret) + SSL_RET(failed2, "ssl_new\n"); + + return ssl; + +failed2: + ssl_free(ssl); +failed1: + return NULL; +} + +/* + * SSL_free - free the SSL + * + * @param ssl - the SSL point + * + * @return none + */ +void SSL_free(SSL *ssl) +{ + SSL_ASSERT(ssl); + + ssl->method->func->ssl_free(ssl); + + ssl_free(ssl); +} + +/* + * SSL_do_handshake - perform the SSL handshake + * + * @param ssl - SSL point + * + * @return + * 1 : OK + * 0 : failed + * -1 : a error catch + */ +int SSL_do_handshake(SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + ret = ssl->method->func->ssl_handshake(ssl); + + return ret; +} + +/* + * SSL_connect - connect to the remote SSL server + * + * @param ssl - the SSL point + * + * @return + * 1 : OK + * -1 : failed + */ +int SSL_connect(SSL *ssl) +{ + SSL_ASSERT(ssl); + + return SSL_do_handshake(ssl); +} + +/* + * SSL_accept - accept the remote connection + * + * @param ssl - the SSL point + * + * @return + * 1 : OK + * -1 : failed + */ +int SSL_accept(SSL *ssl) +{ + SSL_ASSERT(ssl); + + return SSL_do_handshake(ssl); +} + +/* + * SSL_shutdown - shutdown the connection + * + * @param ssl - the SSL point + * + * @return + * 1 : OK + * 0 : shutdown is not finished + * -1 : an error catch + */ +int SSL_shutdown(SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + if (SSL_get_state(ssl) != TLS_ST_OK) return 0; + + ret = ssl->method->func->ssl_shutdown(ssl); + + return ret; +} + +/* + * SSL_clear - reset the SSL + * + * @param ssl - SSL point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_clear(SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + ret = SSL_shutdown(ssl); + if (1 != ret) + SSL_ERR(0, go_failed1, "SSL_shutdown\n"); + + ssl->method->func->ssl_free(ssl); + + ret = ssl->method->func->ssl_new(ssl); + if (!ret) + SSL_ERR(0, go_failed1, "ssl_new\n"); + + return 1; + +go_failed1: + return ret; +} + +/* + * SSL_read - 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 + * > 0 : OK, and return received data bytes + * = 0 : connection is closed + * < 0 : an error catch + */ +int SSL_read(SSL *ssl, void *buffer, int len) +{ + int ret; + + SSL_ASSERT(ssl); + SSL_ASSERT(buffer); + SSL_ASSERT(len); + + ret = ssl->method->func->ssl_read(ssl, buffer, len); + + return ret; +} + +/* + * SSL_write - 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 + * > 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) +{ + int ret; + int send_bytes; + const unsigned char *pbuf; + + SSL_ASSERT(ssl); + SSL_ASSERT(buffer); + SSL_ASSERT(len); + + send_bytes = len; + pbuf = (const unsigned char *)buffer; + + do { + int bytes; + + if (send_bytes > SSL_SEND_DATA_MAX_LENGTH) + bytes = SSL_SEND_DATA_MAX_LENGTH; + else + bytes = send_bytes; + + ret = ssl->method->func->ssl_send(ssl, buffer, len); + if (ret > 0) { + pbuf += ret; + send_bytes -= ret; + } + } while (ret > 0 && send_bytes); + + send_bytes = len - send_bytes; + if (send_bytes >= 0) + ret = send_bytes; + else + ret = -1; + + return ret; +} + +/* + * SSL_get_SSL_CTX - get SSL context of the SSL + * + * @param ssl - SSL point + * + * @return SSL context + */ +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->ctx; +} + +/* + * SSL_CTX_get_ssl_method - get the SSL current method + * + * @param ssl - SSL point + * + * @return the SSL current method + */ +const SSL_METHOD *SSL_get_ssl_method(SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->method; +} + +/* + * SSL_set_ssl_method - set the SSL method + * + * @param ssl - SSL point + * @param meth - SSL method point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method) +{ + int ret; + + SSL_ASSERT(ssl); + SSL_ASSERT(method); + + if (ssl->version != method->version) { + + ret = SSL_shutdown(ssl); + if (1 != ret) + SSL_ERR(0, go_failed1, "SSL_shutdown\n"); + + ssl->method->func->ssl_free(ssl); + + ssl->method = method; + + ret = ssl->method->func->ssl_new(ssl); + if (!ret) + SSL_ERR(0, go_failed1, "ssl_new\n"); + } else { + ssl->method = method; + } + + + return 1; + +go_failed1: + return ret; +} + +/* + * SSL_get_shutdown - get SSL shutdown mode + * + * @param ssl - SSL point + * + * @return shutdown mode + */ +int SSL_get_shutdown(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->shutdown; +} + +/* + * SSL_set_quiet_shutdown - set SSL shutdown mode + * + * @param ssl - SSL point + * @param mode - shutdown mode + * + * @return none + */ +void SSL_set_shutdown(SSL *ssl, int mode) +{ + SSL_ASSERT(ssl); + + ssl->shutdown = mode; +} + + +/* + * SSL_pending - get the number of the bytes to be read + * + * @param ssl - SSL point + * + * @return number of the bytes + */ +int SSL_pending(const SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + ret = ssl->method->func->ssl_pending(ssl); + + return ret; +} + +/* + * SSL_has_pending - 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) +{ + int ret; + + SSL_ASSERT(ssl); + + if (SSL_pending(ssl)) + ret = 1; + else + ret = 0; + + return ret; +} + +/* + * SSL_CTX_clear_options - 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) +{ + return ctx->options &= ~op; +} + +/* + * SSL_CTX_clear_options - 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) +{ + return ctx->options; +} + +/* + * SSL_CTX_set_option - set the option of the SSL context + * + * @param ctx - the SSL context + * + * @return the SSL context option + * + */ +unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt) +{ + return ctx->options |= opt; +} + +/* + * SSL_clear_options - clear SSL option + * + * @param ssl - SSL point + * @param op - clear option + * + * @return SSL option + */ +unsigned long SSL_clear_options(SSL *ssl, unsigned long op) +{ + SSL_ASSERT(ssl); + + return ssl->options & ~op; +} + +/* + * SSL_clear_options - get SSL option + * + * @param ssl - SSL point + * + * @return SSL option + */ +unsigned long SSL_get_options(SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->options; +} + +/* + * SSL_clear_options - clear SSL option + * + * @param ssl - SSL point + * @param op - setting option + * + * @return SSL option + */ +unsigned long SSL_set_options(SSL *ssl, unsigned long op) +{ + SSL_ASSERT(ssl); + + return ssl->options |= op; +} + +/* + * SSL_get_fd - get the socket handle of the SSL + * + * @param ssl - SSL point + * + * @return + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_fd(const SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + ret = ssl->method->func->ssl_get_fd(ssl, 0); + + return ret; +} + +/* + * SSL_get_rfd - get the read only socket handle of the SSL + * + * @param ssl - SSL point + * + * @return + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_rfd(const SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + ret = ssl->method->func->ssl_get_fd(ssl, 0); + + return ret; +} + +/* + * SSL_get_wfd - get the write only socket handle of the SSL + * + * @param ssl - SSL point + * + * @return + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_wfd(const SSL *ssl) +{ + int ret; + + SSL_ASSERT(ssl); + + ret = ssl->method->func->ssl_get_fd(ssl, 0); + + return ret; +} + +/* + * SSL_set_fd - bind the socket file description into the SSL + * + * @param ssl - the SSL point + * @param fd - socket handle + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_set_fd(SSL *ssl, int fd) +{ + int ret; + + SSL_ASSERT(ssl); + SSL_ASSERT(fd >= 0); + + ssl->method->func->ssl_set_fd(ssl, fd, 0); + + return 1; +} + +/* + * SSL_set_fd - bind the read only socket file description into the SSL + * + * @param ssl - the SSL point + * @param fd - socket handle + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_set_rfd(SSL *ssl, int fd) +{ + int ret; + + SSL_ASSERT(ssl); + SSL_ASSERT(fd >= 0); + + ssl->method->func->ssl_set_fd(ssl, fd, 0); + + return 1; +} + +/* + * SSL_set_fd - bind the write only socket file description into the SSL + * + * @param ssl - the SSL point + * @param fd - socket handle + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_set_wfd(SSL *ssl, int fd) +{ + int ret; + + SSL_ASSERT(ssl); + SSL_ASSERT(fd >= 0); + + ssl->method->func->ssl_set_fd(ssl, fd, 0); + + return 1; +} + +/* + * SSL_version - get SSL version + * + * @param ssl - SSL point + * + * @return SSL version + */ +int SSL_version(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->version; +} + +/* + * ssl_protocol_to_string - get the SSL version string + * + * @param version - the SSL version + * + * @return 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; +} + +/* + * SSL_get_version - get the SSL current version + * + * @param ssl - SSL point + * + * @return the version string + */ +const char *SSL_get_version(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl_protocol_to_string(SSL_version(ssl)); +} + +/* + * SSL_alert_desc_string - get alert description string + * + * @param value - alert value + * + * @return 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; +} + +/* + * SSL_alert_desc_string - get alert description long string + * + * @param value - alert value + * + * @return 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; +} + +/* + * SSL_alert_type_string - get alert type string + * + * @param value - alert value + * + * @return 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; +} + +/* + * SSL_alert_type_string_long - get alert type long string + * + * @param value - alert value + * + * @return 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; +} + +/* + * SSL_rstate_string - get the state string where SSL is reading + * + * @param ssl - SSL point + * + * @return state string + */ +const char *SSL_rstate_string(SSL *ssl) +{ + const char *str; + + SSL_ASSERT(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; +} + +/* + * SSL_rstate_string_long - 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) +{ + const char *str = "unknown"; + + SSL_ASSERT(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; +} + +/* + * SSL_state_string - get SSL statement string + * + * @param ssl - SSL point + * + * @return SSL statement string + */ +char *SSL_state_string(const SSL *ssl) +{ + char *str = "UNKWN "; + + SSL_ASSERT(ssl); + + if (ossl_state_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; +} + +/* + * SSL_state_string_long - get SSL statement long string + * + * @param ssl - SSL point + * + * @return SSL statement long string + */ +char *SSL_state_string_long(const SSL *ssl) +{ + char *str = "UNKWN "; + + SSL_ASSERT(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; +} + +/* + * SSL_CTX_set_default_read_buffer_len - 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) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(len); + + ctx->method->func->ssl_set_bufflen(NULL, len); +} + +/* + * SSL_set_default_read_buffer_len - 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) +{ + SSL_ASSERT(ssl); + SSL_ASSERT(len); + + ssl->method->func->ssl_set_bufflen(ssl, len); +} + +/* + * SSL_set_info_callback - 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)) +{ + SSL_ASSERT(ssl); + + ssl->info_callback = cb; +} + +/* + * SSL_CTX_up_ref - add SSL context reference count by '1' + * + * @param ctx - SSL context point + * + * @return + * 1 : OK + * 0 : failed + */ +int SSL_CTX_up_ref(SSL_CTX *ctx) +{ + SSL_ASSERT(ctx); + + /* no support multi-thread SSL here */ + ctx->references++; + + return 1; +} + +/* + * SSL_set_security_level - set the SSL security level + * + * @param ssl - SSL point + * @param level - security level + * + * @return none + */ +void SSL_set_security_level(SSL *ssl, int level) +{ + SSL_ASSERT(ssl); + + ssl->cert->sec_level = level; +} + +/* + * SSL_get_security_level - get the SSL security level + * + * @param ssl - SSL point + * + * @return security level + */ +int SSL_get_security_level(const SSL *ssl) +{ + SSL_ASSERT(ssl); + + return ssl->cert->sec_level; +} + +/* + * SSL_CTX_get_verify_mode - 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) +{ + SSL_ASSERT(ctx); + + return ctx->verify_mode; +} + +/* + * SSL_CTX_set_timeout - 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) +{ + long l; + + SSL_ASSERT(ctx); + + l = ctx->session_timeout; + ctx->session_timeout = t; + + return l; +} + +/* + * SSL_CTX_get_timeout - get the session timeout time + * + * @param ctx - SSL context point + * + * @return current session timeout time + */ +long SSL_CTX_get_timeout(const SSL_CTX *ctx) +{ + SSL_ASSERT(ctx); + + return ctx->session_timeout; +} + +/* + * SSL_set_read_ahead - 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 *ssl, int yes) +{ + SSL_ASSERT(ssl); + + ssl->rlayer.read_ahead = yes; +} + +/* + * SSL_set_read_ahead - set the SSL context if we can read as many as data + * + * @param ctx - SSL context point + * @param yes - enable the function + * + * @return none + */ +void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) +{ + SSL_ASSERT(ctx); + + ctx->read_ahead = yes; +} + +/* + * SSL_set_read_ahead - 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) +{ + SSL_ASSERT(ssl); + + return ssl->rlayer.read_ahead; +} + +/* + * SSL_set_read_ahead - 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) +{ + SSL_ASSERT(ctx); + + return ctx->read_ahead; +} + +/* + * SSL_CTX_get_ciphers - check if the SSL context can read as many as data + * + * @param ctx - SSL context point + * + * @return + * 1 : Yes + * 0 : No + */ +long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx) +{ + SSL_ASSERT(ctx); + + return ctx->read_ahead; +} + +/* + * SSL_set_time - set SSL session time + * + * @param ssl - SSL point + * @param t - session time + * + * @return session time + */ +long SSL_set_time(SSL *ssl, long t) +{ + SSL_ASSERT(ssl); + + ssl->session.time = t; + + return t; +} + +/* + * SSL_set_time - set SSL session timeout time + * + * @param ssl - SSL point + * @param t - session timeout time + * + * @return session timeout time + */ +long SSL_set_timeout(SSL *ssl, long t) +{ + SSL_ASSERT(ssl); + + ssl->session.timeout = t; + + return t; +} diff --git a/components/openssl/library/ssl_methods.c b/components/openssl/library/ssl_methods.c new file mode 100644 index 0000000000..502262f7e9 --- /dev/null +++ b/components/openssl/library/ssl_methods.c @@ -0,0 +1,43 @@ +#include "ssl_lib.h" +#include "ssl_methods.h" +#include "ssl_pm.h" + +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_state); + +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); + + +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); + + +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); diff --git a/components/openssl/library/ssl_pkey.c b/components/openssl/library/ssl_pkey.c new file mode 100644 index 0000000000..2a170716c0 --- /dev/null +++ b/components/openssl/library/ssl_pkey.c @@ -0,0 +1,50 @@ +#include "ssl_lib.h" +#include "ssl_pkey.h" +#include "ssl_dbg.h" +#include "ssl_pm.h" + +EVP_PKEY *d2i_PrivateKey(int type, + EVP_PKEY **a, + const unsigned char **pp, + long length) +{ + EVP_PKEY *pkey; + void *pkey_pm; + int ret; + + SSL_ASSERT(pp); + SSL_ASSERT(*pp); + SSL_ASSERT(length); + + pkey = ssl_malloc(sizeof(EVP_PKEY)); + if (!pkey) + SSL_RET(failed1, "ssl_malloc\n"); + + pkey_pm = pkey_pm_new(); + if (!pkey_pm) + SSL_RET(failed2, "pkey_pm_new\n"); + + ret = pkey_pm_load_crt(pkey_pm, *pp, length); + if (ret) + SSL_RET(failed3, "pkey_pm_load_crt\n"); + + pkey->pkey_pm = pkey_pm; + if (a) + *a = pkey; + + return pkey; + +failed3: + pkey_pm_free(pkey_pm); +failed2: + ssl_free(pkey); +failed1: + return NULL; +} + +void EVP_PKEY_free(EVP_PKEY *x) +{ + pkey_pm_unload_crt(x->pkey_pm); + pkey_pm_free(x->pkey_pm); + ssl_free(x); +} diff --git a/components/openssl/library/ssl_rsa.c b/components/openssl/library/ssl_rsa.c new file mode 100644 index 0000000000..9088f67f57 --- /dev/null +++ b/components/openssl/library/ssl_rsa.c @@ -0,0 +1,70 @@ +#include "ssl_lib.h" +#include "ssl_rsa.h" +#include "ssl_pkey.h" +#include "ssl_x509.h" +#include "ssl_dbg.h" +#include "ssl_pm.h" + +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(x); + + ctx->cert->x509 = x; + + return 1; +} + +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d) +{ + int ret; + X509 *cert; + + cert = d2i_X509(NULL, d, len); + if (!cert) + SSL_RET(failed1, "d2i_X509\n"); + + ret = SSL_CTX_use_certificate(ctx, cert); + if (!ret) + SSL_RET(failed2, "SSL_CTX_use_certificate\n"); + + return 1; + +failed2: + X509_free(cert); +failed1: + return 0; +} + +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) +{ + SSL_ASSERT(ctx); + SSL_ASSERT(pkey); + + ctx->cert->pkey = pkey; + + return 1; +} + +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, + const unsigned char *d, long len) +{ + int ret; + EVP_PKEY *pkey; + + pkey = d2i_PrivateKey(0, NULL, &d, len); + if (!pkey) + SSL_RET(failed1, "d2i_PrivateKey\n"); + + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + if (!ret) + SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n"); + + return 1; + +failed2: + EVP_PKEY_free(pkey); +failed1: + return 0; +} diff --git a/components/openssl/library/ssl_x509.c b/components/openssl/library/ssl_x509.c new file mode 100644 index 0000000000..23aa00681e --- /dev/null +++ b/components/openssl/library/ssl_x509.c @@ -0,0 +1,54 @@ +#include "ssl_x509.h" +#include "ssl_dbg.h" +#include "ssl_pm.h" + +X509* sk_X509_NAME_new_null(void) +{ + return ssl_malloc(sizeof(X509)); +} + +X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) +{ + X509 *x509_crt; + void *x509_pm; + int ret; + + SSL_ASSERT(cert); + SSL_ASSERT(buffer); + SSL_ASSERT(len); + + x509_crt = sk_X509_NAME_new_null(); + if (!x509_crt) + SSL_RET(failed1, ""); + + x509_pm = x509_pm_new(); + if (!x509_pm) + SSL_RET(failed2, ""); + + ret = x509_pm_load_crt(x509_pm, buffer, len); + if (ret) + SSL_RET(failed3, ""); + + x509_crt->x509_pm = x509_pm; + if (cert) + *cert = x509_crt; + + return x509_crt; + +failed3: + x509_pm_free(x509_pm); +failed2: + ssl_free(x509_crt); +failed1: + return NULL; +} + +void X509_free(X509 *cert) +{ + if (cert->x509_pm) { + x509_pm_unload_crt(cert->x509_pm); + x509_pm_free(cert->x509_pm); + } + ssl_free(cert); +}; + diff --git a/components/openssl/platform/Makefile b/components/openssl/platform/Makefile new file mode 100644 index 0000000000..749b4787ca --- /dev/null +++ b/components/openssl/platform/Makefile @@ -0,0 +1,46 @@ + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +GEN_LIBS = libplatform.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/components/openssl/platform/ssl_pm.c b/components/openssl/platform/ssl_pm.c new file mode 100644 index 0000000000..831420180c --- /dev/null +++ b/components/openssl/platform/ssl_pm.c @@ -0,0 +1,422 @@ +#include "ssl_pm.h" +#include "ssl_dbg.h" + +/* mbedtls include */ +#include "mbedtls/platform.h" +#include "mbedtls/net.h" +#include "mbedtls/debug.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/error.h" +#include "mbedtls/certs.h" + +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; +}; + +struct x509_pm +{ + mbedtls_x509_crt x509_crt; +}; + +struct pkey_pm +{ + mbedtls_pk_context pkey; +}; + + +unsigned int max_content_len; + + +/*********************************************************************************************/ +/********************************* SSL general interface *************************************/ + +void* ssl_zalloc(size_t size) +{ + void *p = malloc(size); + + if (p) + memset(p, 0, size); + + return p; +} + +void *ssl_malloc(size_t size) +{ + return zalloc(size); +} + +void ssl_free(void *p) +{ + free(p); +} + +void* ssl_memcpy(void *to, const void *from, size_t size) +{ + return memcpy(to, from, size); +} + +void ssl_speed_up_enter(void) +{ + +} + +void ssl_speed_up_exit(void) +{ + +} + +/*********************************************************************************************/ +/************************************ SSL arch interface *************************************/ + +int ssl_pm_new(SSL *ssl) +{ + struct ssl_pm *ssl_pm; + int ret; + + char *pers; + int endpoint; + + SSL_CTX *ctx = ssl->ctx; + const SSL_METHOD *method = ssl->method; + + ssl_pm = malloc(sizeof(struct ssl_pm)); + if (!ssl_pm) + return -1; + + if (method->endpoint) { + pers = "server"; + endpoint = MBEDTLS_SSL_IS_SERVER; + } else { + pers = "client"; + endpoint = MBEDTLS_SSL_IS_CLIENT; + } + + //max_content_len = 4096; + + 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, (const unsigned char *)pers, strlen(pers)); + if (ret) + SSL_ERR(ret, failed1, "mbedtls_ctr_drbg_seed:[-0x%x]\n", -ret); + + ret = mbedtls_ssl_config_defaults(&ssl_pm->conf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); + if (ret) + SSL_ERR(ret, failed2, "mbedtls_ssl_config_defaults:[-0x%x]\n", -ret); + + mbedtls_ssl_conf_rng(&ssl_pm->conf, mbedtls_ctr_drbg_random, &ssl_pm->ctr_drbg); + mbedtls_ssl_conf_dbg(&ssl_pm->conf, NULL, NULL); + + if (ctx->client_CA->x509_pm) { + struct x509_pm *x509_pm = (struct x509_pm *)ctx->client_CA->x509_pm; + + mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, &x509_pm->x509_crt, NULL); + mbedtls_ssl_conf_authmode(&ssl_pm->conf, MBEDTLS_SSL_VERIFY_REQUIRED); + } else { + mbedtls_ssl_conf_authmode(&ssl_pm->conf, MBEDTLS_SSL_VERIFY_NONE); + } + if (ctx->cert->x509 && + ctx->cert->pkey) { + struct x509_pm *x509_pm = (struct x509_pm *)ctx->cert->x509->x509_pm; + struct pkey_pm *pkey_pm = (struct pkey_pm *)ctx->cert->pkey->pkey_pm; + + ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, &x509_pm->x509_crt, &pkey_pm->pkey); + if (ret) + SSL_ERR(ret, failed4, "mbedtls_ssl_conf_own_cert:[%d]\n", ret); + } + + ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf); + if (ret) + SSL_ERR(ret, failed4, "mbedtls_ssl_setup:[-0x%x]\n", -ret); + + mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd, mbedtls_net_send, mbedtls_net_recv, NULL); + + ssl->ssl_pm = ssl_pm; + + return 0; + +failed4: + mbedtls_ssl_config_free(&ssl_pm->conf); +failed3: + mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); +failed2: + mbedtls_entropy_free(&ssl_pm->entropy); +failed1: + return -1; +} + +void ssl_pm_free(SSL *ssl) +{ + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + mbedtls_ssl_config_free(&ssl_pm->conf); + mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); + mbedtls_entropy_free(&ssl_pm->entropy); + mbedtls_ssl_free(&ssl_pm->ssl); + + mbedtls_net_free(&ssl_pm->fd); + mbedtls_net_free(&ssl_pm->cl_fd); +} + +int ssl_pm_handshake(SSL *ssl) +{ + int ret, mbed_ret; + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + ssl_speed_up_enter(); + while((mbed_ret = mbedtls_ssl_handshake(&ssl_pm->ssl)) != 0) { + if (mbed_ret != MBEDTLS_ERR_SSL_WANT_READ && mbed_ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + break; + } + } + ssl_speed_up_exit(); + + if (!mbed_ret) + ret = 1; + else { + ret = 0; + SSL_DEBUG(1, "mbedtls_ssl_handshake [-0x%x]\n", -mbed_ret); + } + + return ret; +} + +int ssl_pm_shutdown(SSL *ssl) +{ + int ret, mbed_ret; + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + mbed_ret = mbedtls_ssl_close_notify(&ssl_pm->ssl); + if (!mbed_ret) + ret = 0; + else + ret = -1; + + 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, mbed_ret; + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + mbed_ret = mbedtls_ssl_read(&ssl_pm->ssl, buffer, len); + if (mbed_ret < 0) + ret = -1; + else if (mbed_ret == 0) + ret = 0; + else + ret = mbed_ret; + + return ret; +} + +int ssl_pm_send(SSL *ssl, const void *buffer, int len) +{ + int ret, mbed_ret; + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + mbed_ret = mbedtls_ssl_write(&ssl_pm->ssl, buffer, len); + if (mbed_ret < 0) + ret = -1; + else if (mbed_ret == 0) + ret = 0; + else + ret = mbed_ret; + + 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; +} + +void* x509_pm_new(void) +{ + return ssl_malloc(sizeof(struct x509_pm)); +} + +void x509_pm_free(void *pm) +{ + ssl_free(pm); +} + +int x509_pm_load_crt(void *pm, const unsigned char *buffer, int len) +{ + int ret; + unsigned char *load_buf; + struct x509_pm *x509_pm = (struct x509_pm *)pm; + + load_buf = ssl_malloc(len + 1); + if (!load_buf) + SSL_RET(failed1, ""); + + ssl_memcpy(load_buf, buffer, len); + load_buf[len] = '\0'; + + mbedtls_x509_crt_init(&x509_pm->x509_crt); + ret = mbedtls_x509_crt_parse(&x509_pm->x509_crt, load_buf, len); + ssl_free(load_buf); + + if (ret) + SSL_RET(failed1, ""); + + return 0; + +failed1: + return -1; +} + +void x509_pm_unload_crt(void *pm) +{ + struct x509_pm *x509_pm = (struct x509_pm *)pm; + + mbedtls_x509_crt_free(&x509_pm->x509_crt); +} + +void* pkey_pm_new(void) +{ + return ssl_malloc(sizeof(struct pkey_pm)); +} + +void pkey_pm_free(void *pm) +{ + ssl_free(pm); +} + +int pkey_pm_load_crt(void *pm, const unsigned char *buffer, int len) +{ + int ret; + unsigned char *load_buf; + struct pkey_pm *pkey_pm = (struct pkey_pm *)pm; + + load_buf = ssl_malloc(len + 1); + if (!load_buf) + SSL_RET(failed1, ""); + + 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, NULL, 0); + ssl_free(load_buf); + + if (ret) + SSL_RET(failed1, ""); + + return 0; + +failed1: + return -1; +} + +void pkey_pm_unload_crt(void *pm) +{ + struct pkey_pm *pkey_pm = (struct pkey_pm *)pm; + + mbedtls_pk_free(&pkey_pm->pkey); +} + +void ssl_pm_set_bufflen(SSL *ssl, int len) +{ + max_content_len = len; +}