feat(ssl): remove AX-TLS

Also open source, we recommend that customers use mbedTLS.
This commit is contained in:
dongheng
2019-05-23 11:05:54 +08:00
parent 1b42f75df8
commit a06729a33b
36 changed files with 0 additions and 13611 deletions

View File

@ -19,10 +19,6 @@ set(COMPONENT_SRCDIRS
mbedtls/port/openssl/source/platform
mbedtls/mbedtls/library
mbedtls/port/esp8266)
else()
set(COMPONENT_ADD_INCLUDEDIRS axtls/include)
set(COMPONENT_SRCDIRS axtls/source/ssl axtls/source/crypto)
endif()
endif()

View File

@ -10,8 +10,6 @@ choice SSL_LIBRARY_CHOOSE
config SSL_USING_MBEDTLS
bool "mbedTLS"
config SSL_USING_AXTLS
bool "axTLS"
config SSL_USING_WOLFSSL
bool "wolfSSL (License info in wolfssl subdirectory README)"
endchoice

View File

@ -1,99 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BIGINT_HEADER
#define BIGINT_HEADER
#include "ssl/ssl_crypto.h"
BI_CTX *bi_initialize(void);
void bi_terminate(BI_CTX *ctx);
void bi_permanent(bigint *bi);
void bi_depermanent(bigint *bi);
void bi_clear_cache(BI_CTX *ctx);
void bi_free(BI_CTX *ctx, bigint *bi);
bigint *bi_copy(bigint *bi);
bigint *bi_clone(BI_CTX *ctx, const bigint *bi);
void bi_export(BI_CTX *ctx, bigint *bi, uint8_t *data, int size);
bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int len);
bigint *int_to_bi(BI_CTX *ctx, comp i);
/* the functions that actually do something interesting */
bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib);
bigint *bi_subtract(BI_CTX *ctx, bigint *bia,
bigint *bib, int *is_negative);
bigint *bi_divide(BI_CTX *ctx, bigint *bia, bigint *bim, int is_mod);
bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib);
bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp);
bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp);
int bi_compare(bigint *bia, bigint *bib);
void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset);
void bi_free_mod(BI_CTX *ctx, int mod_offset);
#ifdef CONFIG_SSL_FULL_MODE
void bi_print(const char *label, bigint *bi);
bigint *bi_str_import(BI_CTX *ctx, const char *data);
#endif
/**
* @def bi_mod
* Find the residue of B. bi_set_mod() must be called before hand.
*/
#define bi_mod(A, B) bi_divide(A, B, ctx->bi_mod[ctx->mod_offset], 1)
/**
* bi_residue() is technically the same as bi_mod(), but it uses the
* appropriate reduction technique (which is bi_mod() when doing classical
* reduction).
*/
#if defined(CONFIG_BIGINT_MONTGOMERY)
#define bi_residue(A, B) bi_mont(A, B)
bigint *bi_mont(BI_CTX *ctx, bigint *bixy);
#elif defined(CONFIG_BIGINT_BARRETT)
#define bi_residue(A, B) bi_barrett(A, B)
bigint *bi_barrett(BI_CTX *ctx, bigint *bi);
#else /* if defined(CONFIG_BIGINT_CLASSICAL) */
#define bi_residue(A, B) bi_mod(A, B)
#endif
#ifdef CONFIG_BIGINT_SQUARE
bigint *bi_square(BI_CTX *ctx, bigint *bi);
#else
#define bi_square(A, B) bi_multiply(A, bi_copy(B), B)
#endif
#ifdef CONFIG_BIGINT_CRT
bigint *bi_crt(BI_CTX *ctx, bigint *bi,
bigint *dP, bigint *dQ,
bigint *p, bigint *q,
bigint *qInv);
#endif
#endif

View File

@ -1,131 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BIGINT_IMPL_HEADER
#define BIGINT_IMPL_HEADER
/* Maintain a number of precomputed variables when doing reduction */
#define BIGINT_M_OFFSET 0 /**< Normal modulo offset. */
#ifdef CONFIG_BIGINT_CRT
#define BIGINT_P_OFFSET 1 /**< p modulo offset. */
#define BIGINT_Q_OFFSET 2 /**< q module offset. */
#define BIGINT_NUM_MODS 3 /**< The number of modulus constants used. */
#else
#define BIGINT_NUM_MODS 1
#endif
/* Architecture specific functions for big ints */
#if defined(CONFIG_INTEGER_8BIT)
#define COMP_RADIX 256U /**< Max component + 1 */
#define COMP_MAX 0xFFFFU/**< (Max dbl comp -1) */
#define COMP_BIT_SIZE 8 /**< Number of bits in a component. */
#define COMP_BYTE_SIZE 1 /**< Number of bytes in a component. */
#define COMP_NUM_NIBBLES 2 /**< Used For diagnostics only. */
typedef uint8_t comp; /**< A single precision component. */
typedef uint16_t long_comp; /**< A double precision component. */
typedef int16_t slong_comp; /**< A signed double precision component. */
#elif defined(CONFIG_INTEGER_16BIT)
#define COMP_RADIX 65536U /**< Max component + 1 */
#define COMP_MAX 0xFFFFFFFFU/**< (Max dbl comp -1) */
#define COMP_BIT_SIZE 16 /**< Number of bits in a component. */
#define COMP_BYTE_SIZE 2 /**< Number of bytes in a component. */
#define COMP_NUM_NIBBLES 4 /**< Used For diagnostics only. */
typedef uint16_t comp; /**< A single precision component. */
typedef uint32_t long_comp; /**< A double precision component. */
typedef int32_t slong_comp; /**< A signed double precision component. */
#else /* regular 32 bit */
#ifdef WIN32
#define COMP_RADIX 4294967296i64
#define COMP_MAX 0xFFFFFFFFFFFFFFFFui64
#else
#define COMP_RADIX 4294967296ULL /**< Max component + 1 */
#define COMP_MAX 0xFFFFFFFFFFFFFFFFULL/**< (Max dbl comp -1) */
#endif
#define COMP_BIT_SIZE 32 /**< Number of bits in a component. */
#define COMP_BYTE_SIZE 4 /**< Number of bytes in a component. */
#define COMP_NUM_NIBBLES 8 /**< Used For diagnostics only. */
typedef uint32_t comp; /**< A single precision component. */
typedef uint64_t long_comp; /**< A double precision component. */
typedef int64_t slong_comp; /**< A signed double precision component. */
#endif
/**
* @struct _bigint
* @brief A big integer basic object
*/
struct _bigint
{
struct _bigint* next; /**< The next bigint in the cache. */
short size; /**< The number of components in this bigint. */
short max_comps; /**< The heapsize allocated for this bigint */
int refs; /**< An internal reference count. */
comp* comps; /**< A ptr to the actual component data */
};
typedef struct _bigint bigint; /**< An alias for _bigint */
/**
* Maintains the state of the cache, and a number of variables used in
* reduction.
*/
typedef struct /**< A big integer "session" context. */
{
bigint *active_list; /**< Bigints currently used. */
bigint *free_list; /**< Bigints not used. */
bigint *bi_radix; /**< The radix used. */
bigint *bi_mod[BIGINT_NUM_MODS]; /**< modulus */
#if defined(CONFIG_BIGINT_MONTGOMERY)
bigint *bi_RR_mod_m[BIGINT_NUM_MODS]; /**< R^2 mod m */
bigint *bi_R_mod_m[BIGINT_NUM_MODS]; /**< R mod m */
comp N0_dash[BIGINT_NUM_MODS];
#elif defined(CONFIG_BIGINT_BARRETT)
bigint *bi_mu[BIGINT_NUM_MODS]; /**< Storage for mu */
#endif
bigint *bi_normalised_mod[BIGINT_NUM_MODS]; /**< Normalised mod storage. */
bigint **g; /**< Used by sliding-window. */
int window; /**< The size of the sliding window */
int active_count; /**< Number of active bigints. */
int free_count; /**< Number of free bigints. */
#ifdef CONFIG_BIGINT_MONTGOMERY
uint8_t use_classical; /**< Use classical reduction. */
#endif
uint8_t mod_offset; /**< The mod offset we are using */
} BI_CTX;
#ifndef WIN32
#define max(a,b) ((a)>(b)?(a):(b)) /**< Find the maximum of 2 numbers. */
#define min(a,b) ((a)<(b)?(a):(b)) /**< Find the minimum of 2 numbers. */
#endif
#define PERMANENT 0x7FFF55AA /**< A magic number for permanents. */
#endif

View File

@ -1,100 +0,0 @@
/*
* ssl_compat-1.0.h
*
* Created on: Sep 7, 2015
* Author: liuhan
*/
#ifndef SSL_COMPAT_1_0_H_
#define SSL_COMPAT_1_0_H_
#include "ssl/ssl_platform.h"
/*encapsulation the function based on the espressif platform*/
#define SSL_library_init(a) esp_ssl_library_init(a)
#define SSL_new(a) esp_ssl_new(a)
#define SSL_set_fd(a,b) esp_ssl_set_fd(a,b)
#define SSL_free(a) esp_ssl_free(a)
#define SSL_connect(a) esp_ssl_connect(a)
#define SSL_accept(a) esp_ssl_accept(a)
#define SSL_read(a,b,c) esp_ssl_read(a,b,c)
#define SSL_write(a,b,c) esp_ssl_write(a,b,c)
#define SSL_get_peer_certificate(a) esp_ssl_get_peer_certificate(a)
#define SSL_get_verify_result(a) esp_ssl_get_verify_result(a)
#define SSL_get_error(a,b) esp_ssl_get_error(a,b)
#define SSL_pending(a) esp_ssl_pending(a)
#define SSL_fragment_length_negotiation(a,b) esp_ssl_fragment_length_negotiation(a,b)
#define SSL_CTX_new(a) esp_ssl_CTX_new(a)
#define SSL_CTX_set_option(a,b) esp_ssl_CTX_set_option(a,b)
#define SSL_CTX_free(a) esp_ssl_CTX_free(a)
#define SSL_CTX_load_verify_locations(a,b,c) esp_ssl_CTX_load_verify_locations(a,b,c)
#define SSL_CTX_set_default_verify_paths(a) esp_ssl_CTX_set_default_verify_paths(a)
#define SSL_CTX_use_certificate_chain_file(a,b) esp_ssl_CTX_use_certificate_chain_file(a,b)
#define SSL_CTX_use_PrivateKey_file(a,b,c) esp_ssl_CTX_use_PrivateKey_file(a,b,c)
#define SSL_CTX_check_private_key(a) esp_ssl_CTX_check_private_key(a)
#define SSL_CTX_set_verify(a,b,c) esp_ssl_CTX_set_verify(a)
#define SSL_CTX_set_verify_depth(a,b) esp_ssl_CTX_set_verify_depth(a)
#define SSL_CTX_set_client_cert_cb esp_ssl_CTX_set_client_cert_cb
#define SSL_CTX_set_mode(a) esp_ssl_CTX_set_mode(a)
#define X509_free(a) esp_X509_free(a)
#define X509_STORE_CTX_get_current_cert(a) esp_X509_store_ctx_get_current_cert(a)
#define X509_NAME_oneline(a,b,c) esp_X509_NAME_oneline(a,b,c)
#define X509_get_issuer_name(a) esp_X509_get_issuer_name(a)
#define X509_get_subject_name(a) esp_X509_get_subject_name(a)
#define X509_STORE_CTX_get_error_depth(a) esp_X509_STORE_CTX_get_error_depth(a)
#define X509_STORE_CTX_get_error(a) esp_X509_STORE_CTX_get_error(a)
#define X509_verify_cert_error_string(a) esp_X509_verify_cert_error_string(a)
#define EVP_sha1(a) esp_EVP_sha1(a)
#define EVP_DigestInit(a,b) esp_EVP_DigestInit(a,b)
#define EVP_DigestUpdate(a,b,c) esp_EVP_DigestUpdate(a,b,c)
#define EVP_DigestFinal(a,b,c) esp_EVP_DigestFinal(a,b,c)
#define EVP_cleanup(a) esp_EVP_cleanup(a)
#define ERR_get_error(a) esp_ERR_get_error(a)
#define ERR_error_string_n(a,b,c) esp_ERR_error_string_n(a,b,c)
#define ERR_error_string(a,b) esp_ERR_error_string(a,b)
#define ERR_free_strings(a) esp_ERR_free_strings(a)
#define strerror(a) esp_ERR_strerror(a)
#define CRYPTO_cleanup_all_ex_data(a) esp_CRYPTO_cleanup_all_ex_data(a)
#define base64_encode(a,b,c,d,e) esp_base64_encode(a,b,c,d,e)
#define TLSv1_client_method(a) esp_TLSv1_client_method(a)
//#if TLSv1_1__method
#define TLSv1_1_client_method(a) esp_TLSv1_1_client_method(a)
//#endif
#define SSLv3_client_method(a) esp_SSLv3_client_method(a)
#define SSLv23_client_method(a) esp_SSLv23_client_method(a)
#define TLSv1_server_method(a) esp_TLSv1_server_method(a)
//#if TLSv1_1__method
#define TLSv1_1_server_method(a) esp_TLSv1_1_server_method(a)
//#endif
#define SSLv3_server_method(a) esp_SSLv3_server_method(a)
#define SSLv23_server_method(a) esp_SSLv23_server_method(a)
/*encapsulation the protocol based on the espressif platform*/
#define SSL_ERROR_NONE ESP_SSL_ERROR_NONE
#define SSL_ERROR_WANT_WRITE ESP_SSL_ERROR_WANT_WRITE
#define SSL_ERROR_WANT_READ ESP_SSL_ERROR_WANT_READ
#define SSL_ERROR_WANT_X509_LOOKUP ESP_SSL_ERROR_WANT_X509_LOOKUP
#define SSL_ERROR_SYSCALL ESP_SSL_ERROR_SYSCALL
#define SSL_ERROR_ZERO_RETURN ESP_SSL_ERROR_ZERO_RETURN
#define SSL_ERROR_SSL ESP_SSL_ERROR_SSL
#define SSL_FILETYPE_PEM ESP_SSL_FILETYPE_PEM
#define SSL_VERIFY_PEER ESP_SSL_VERIFY_PEER
#define EVP_MAX_MD_SIZE ESP_EVP_MAX_MD_SIZE
#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT ESP_SSL_VERIFY_FAIL_IF_NO_PEER_CERT
#define SSL_MODE_ENABLE_PARTIAL_WRITE ESP_SSL_MODE_ENABLE_PARTIAL_WRITE
#define SSL_VERIFY_NONE ESP_SSL_VERIFY_NONE
#define SSL_ERROR_WANT_CONNECT ESP_SSL_ERROR_WANT_CONNECT
#define SSL_ERROR_WANT_ACCEPT ESP_SSL_ERROR_WANT_ACCEPT
/*encapsulation the protocol based on the different platform*/
#endif /* SSL_COMPAT_1_0_H_ */

View File

@ -1,147 +0,0 @@
/*
* Automatically generated header file: don't edit
*/
#define HAVE_DOT_CONFIG 1
#undef CONFIG_PLATFORM_LINUX
#define CONFIG_PLATFORM_CYGWIN 1
#undef CONFIG_PLATFORM_WIN32
/*
* General Configuration
*/
#define PREFIX "/usr/local"
#define CONFIG_DEBUG 1
#undef CONFIG_STRIP_UNWANTED_SECTIONS
#undef CONFIG_VISUAL_STUDIO_7_0
#undef CONFIG_VISUAL_STUDIO_8_0
#undef CONFIG_VISUAL_STUDIO_10_0
#define CONFIG_VISUAL_STUDIO_7_0_BASE ""
#define CONFIG_VISUAL_STUDIO_8_0_BASE ""
#define CONFIG_VISUAL_STUDIO_10_0_BASE ""
#define CONFIG_EXTRA_CFLAGS_OPTIONS ""
#define CONFIG_EXTRA_LDFLAGS_OPTIONS ""
/*
* SSL Library
*/
#undef CONFIG_SSL_SERVER_ONLY
#undef CONFIG_SSL_CERT_VERIFICATION
#undef CONFIG_SSL_ENABLE_CLIENT
#define CONFIG_SSL_FULL_MODE 1
#undef CONFIG_SSL_SKELETON_MODE
#undef CONFIG_SSL_PROT_LOW
#define CONFIG_SSL_PROT_MEDIUM 1
#undef CONFIG_SSL_PROT_HIGH
#define CONFIG_SSL_USE_DEFAULT_KEY
#define CONFIG_SSL_PRIVATE_KEY_LOCATION ""
#define CONFIG_SSL_PRIVATE_KEY_PASSWORD ""
#define CONFIG_SSL_X509_CERT_LOCATION ""
#undef CONFIG_SSL_GENERATE_X509_CERT
#define CONFIG_SSL_X509_COMMON_NAME ""
#define CONFIG_SSL_X509_ORGANIZATION_NAME ""
#define CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME ""
#undef CONFIG_SSL_ENABLE_V23_HANDSHAKE
#define CONFIG_SSL_HAS_PEM 1
#undef CONFIG_SSL_USE_PKCS12
#define CONFIG_SSL_EXPIRY_TIME 24
#define CONFIG_X509_MAX_CA_CERTS 3
#define CONFIG_SSL_MAX_CERTS 3
#define CONFIG_SSL_CTX_MUTEXING 1
#define CONFIG_USE_DEV_URANDOM 1
#undef CONFIG_WIN32_USE_CRYPTO_LIB
#undef CONFIG_OPENSSL_COMPATIBLE
#undef CONFIG_PERFORMANCE_TESTING
#define CONFIG_SSL_TEST 1
#undef CONFIG_AXTLSWRAP
#define CONFIG_AXHTTPD 1
/*add by LiuH for debug at 2015.06.11*/
#define CONFIG_SSL_DISPLAY_MODE 0
/* Mutexing definitions */
#if defined(CONFIG_SSL_CTX_MUTEXING)
#include "lwip/sys.h"
#include "arch/sys_arch.h"
#define SSL_CTX_MUTEX_TYPE sys_mutex_t
#define SSL_CTX_MUTEX_INIT(A) sys_mutex_new(&A)
#define SSL_CTX_MUTEX_DESTROY(A) sys_mutex_free(&A)
#define SSL_CTX_LOCK(A) sys_mutex_lock(&A)
#define SSL_CTX_UNLOCK(A) sys_mutex_unlock(&A)
#else /* no mutexing */
#define SSL_CTX_MUTEX_INIT(A)
#define SSL_CTX_MUTEX_DESTROY(A)
#define SSL_CTX_LOCK(A)
#define SSL_CTX_UNLOCK(A)
#endif
/*
* Axhttpd Configuration
*/
#undef CONFIG_HTTP_STATIC_BUILD
#define CONFIG_HTTP_PORT 80
#define CONFIG_HTTP_HTTPS_PORT 443
#define CONFIG_HTTP_SESSION_CACHE_SIZE 5
#define CONFIG_HTTP_WEBROOT "../www"
#define CONFIG_HTTP_TIMEOUT 300
/*
* CGI
*/
#undef CONFIG_HTTP_HAS_CGI
#define CONFIG_HTTP_CGI_EXTENSIONS ".lua,.lp,.php"
#define CONFIG_HTTP_ENABLE_LUA 1
#define CONFIG_HTTP_LUA_PREFIX "/usr"
#undef CONFIG_HTTP_BUILD_LUA
#define CONFIG_HTTP_CGI_LAUNCHER "/usr/bin/cgi"
#define CONFIG_HTTP_DIRECTORIES 1
#define CONFIG_HTTP_HAS_AUTHORIZATION 1
#undef CONFIG_HTTP_HAS_IPV6
#undef CONFIG_HTTP_ENABLE_DIFFERENT_USER
#define CONFIG_HTTP_USER ""
#define CONFIG_HTTP_VERBOSE 0
#undef CONFIG_HTTP_IS_DAEMON
/*
* Language Bindings
*/
#undef CONFIG_BINDINGS
#undef CONFIG_CSHARP_BINDINGS
#undef CONFIG_VBNET_BINDINGS
#define CONFIG_DOT_NET_FRAMEWORK_BASE ""
#undef CONFIG_JAVA_BINDINGS
#define CONFIG_JAVA_HOME ""
#undef CONFIG_PERL_BINDINGS
#define CONFIG_PERL_CORE ""
#define CONFIG_PERL_LIB ""
#undef CONFIG_LUA_BINDINGS
#define CONFIG_LUA_CORE ""
/*
* Samples
*/
#define CONFIG_SAMPLES 1
#define CONFIG_C_SAMPLES 1
#undef CONFIG_CSHARP_SAMPLES
#undef CONFIG_VBNET_SAMPLES
#undef CONFIG_JAVA_SAMPLES
#undef CONFIG_PERL_SAMPLES
#undef CONFIG_LUA_SAMPLES
/*
* BigInt Options
*/
#undef CONFIG_BIGINT_CLASSICAL
#undef CONFIG_BIGINT_MONTGOMERY
#define CONFIG_BIGINT_BARRETT 1
#define CONFIG_BIGINT_CRT 1
#undef CONFIG_BIGINT_KARATSUBA
#define MUL_KARATSUBA_THRESH
#define SQU_KARATSUBA_THRESH
#define CONFIG_BIGINT_SLIDING_WINDOW 1
#define CONFIG_BIGINT_SQUARE 1
#define CONFIG_BIGINT_CHECK_ON 1
#define CONFIG_INTEGER_32BIT 1
#undef CONFIG_INTEGER_16BIT
#undef CONFIG_INTEGER_8BIT

View File

@ -1,266 +0,0 @@
/*
* Copyright (c) 2007-2015, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file crypto.h
*/
#ifndef HEADER_CRYPTO_H
#define HEADER_CRYPTO_H
#ifdef __cplusplus
extern "C" {
#endif
#include "ssl/ssl_config.h"
#include "ssl/ssl_bigint_impl.h"
#include "ssl/ssl_bigint.h"
#ifndef STDCALL
#define STDCALL
#endif
#ifndef EXP_FUNC
#define EXP_FUNC
#endif
/* enable features based on a 'super-set' capbaility. */
#if defined(CONFIG_SSL_FULL_MODE)
#define CONFIG_SSL_ENABLE_CLIENT
#define CONFIG_SSL_CERT_VERIFICATION
#elif defined(CONFIG_SSL_ENABLE_CLIENT)
#define CONFIG_SSL_CERT_VERIFICATION
#endif
/**************************************************************************
* AES declarations
**************************************************************************/
#define AES_MAXROUNDS 14
#define AES_BLOCKSIZE 16
#define AES_IV_SIZE 16
typedef struct aes_key_st
{
uint16_t rounds;
uint16_t key_size;
uint32_t ks[(AES_MAXROUNDS+1)*8];
uint8_t iv[AES_IV_SIZE];
} AES_CTX;
typedef enum
{
AES_MODE_128,
AES_MODE_256
} AES_MODE;
void AES_set_key(AES_CTX *ctx, const uint8_t *key,
const uint8_t *iv, AES_MODE mode);
void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg,
uint8_t *out, int length);
void AES_cbc_decrypt(AES_CTX *ks, const uint8_t *in, uint8_t *out, int length);
void AES_convert_key(AES_CTX *ctx);
/**************************************************************************
* RC4 declarations
**************************************************************************/
typedef struct
{
uint8_t x, y, m[256];
} RC4_CTX;
void RC4_setup(RC4_CTX *s, const uint8_t *key, int length);
void RC4_crypt(RC4_CTX *s, const uint8_t *msg, uint8_t *data, int length);
/**************************************************************************
* SHA1 declarations
**************************************************************************/
#define SHA1_SIZE 20
/*
* This structure will hold context information for the SHA-1
* hashing operation
*/
typedef struct
{
uint32_t Intermediate_Hash[SHA1_SIZE/4]; /* Message Digest */
uint32_t Length_Low; /* Message length in bits */
uint32_t Length_High; /* Message length in bits */
uint16_t Message_Block_Index; /* Index into message block array */
uint8_t Message_Block[64]; /* 512-bit message blocks */
} SHA1_CTX;
void SHA1_Init(SHA1_CTX *);
void SHA1_Update(SHA1_CTX *, const uint8_t * msg, int len);
void SHA1_Final(uint8_t *digest, SHA1_CTX *);
/**************************************************************************
* SHA256 declarations
**************************************************************************/
#define SHA256_SIZE 32
typedef struct
{
uint32_t total[2];
uint32_t state[8];
uint8_t buffer[64];
} SHA256_CTX;
void SHA256_Init(SHA256_CTX *c);
void SHA256_Update(SHA256_CTX *, const uint8_t *input, int len);
void SHA256_Final(uint8_t *digest, SHA256_CTX *);
/**************************************************************************
* SHA512 declarations
**************************************************************************/
#define SHA512_SIZE 64
typedef struct
{
union
{
uint64_t h[8];
uint8_t digest[64];
} h_dig;
union
{
uint64_t w[80];
uint8_t buffer[128];
} w_buf;
size_t size;
uint64_t totalSize;
} SHA512_CTX;
void SHA512_Init(SHA512_CTX *c);
void SHA512_Update(SHA512_CTX *, const uint8_t *input, int len);
void SHA512_Final(uint8_t *digest, SHA512_CTX *);
/**************************************************************************
* SHA384 declarations
**************************************************************************/
#define SHA384_SIZE 48
typedef SHA512_CTX SHA384_CTX;
void SHA384_Init(SHA384_CTX *c);
void SHA384_Update(SHA384_CTX *, const uint8_t *input, int len);
void SHA384_Final(uint8_t *digest, SHA384_CTX *);
/**************************************************************************
* MD5 declarations
**************************************************************************/
#define MD5_SIZE 16
typedef struct
{
uint32_t state[4]; /* state (ABCD) */
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
uint8_t buffer[64]; /* input buffer */
} MD5_CTX;
EXP_FUNC void STDCALL MD5_Init(MD5_CTX *);
EXP_FUNC void STDCALL MD5_Update(MD5_CTX *, const uint8_t *msg, int len);
EXP_FUNC void STDCALL MD5_Final(uint8_t *digest, MD5_CTX *);
/**************************************************************************
* HMAC declarations
**************************************************************************/
void ssl_hmac_md5(const uint8_t *msg, int length, const uint8_t *key,
int key_len, uint8_t *digest);// fix hmac_md5 to ssl_hmac_md5, discriminate ieee80211
void ssl_hmac_sha1(const uint8_t *msg, int length, const uint8_t *key,
int key_len, uint8_t *digest);// fix hmac_md5 to ssl_hmac_sha1, discriminate ieee80211
/**************************************************************************
* RSA declarations
**************************************************************************/
typedef struct
{
bigint *m; /* modulus */
bigint *e; /* public exponent */
bigint *d; /* private exponent */
#ifdef CONFIG_BIGINT_CRT
bigint *p; /* p as in m = pq */
bigint *q; /* q as in m = pq */
bigint *dP; /* d mod (p-1) */
bigint *dQ; /* d mod (q-1) */
bigint *qInv; /* q^-1 mod p */
#endif
int num_octets;
BI_CTX *bi_ctx;
} RSA_CTX;
void RSA_priv_key_new(RSA_CTX **rsa_ctx,
const uint8_t *modulus, int mod_len,
const uint8_t *pub_exp, int pub_len,
const uint8_t *priv_exp, int priv_len
#ifdef CONFIG_BIGINT_CRT
, const uint8_t *p, int p_len,
const uint8_t *q, int q_len,
const uint8_t *dP, int dP_len,
const uint8_t *dQ, int dQ_len,
const uint8_t *qInv, int qInv_len
#endif
);
void RSA_pub_key_new(RSA_CTX **rsa_ctx,
const uint8_t *modulus, int mod_len,
const uint8_t *pub_exp, int pub_len);
void RSA_free(RSA_CTX *ctx);
int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
int out_len, int is_decryption);
bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg);
#if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT)
bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
bigint *modulus, bigint *pub_exp);
bigint *RSA_public(const RSA_CTX * c, bigint *bi_msg);
int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
uint8_t *out_data, int is_signing);
void RSA_print(const RSA_CTX *ctx);
#endif
/**************************************************************************
* RNG declarations
**************************************************************************/
EXP_FUNC void STDCALL RNG_initialize(void);
EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size);
EXP_FUNC void STDCALL RNG_terminate(void);
EXP_FUNC int STDCALL get_random(int num_rand_bytes, uint8_t *rand_data);
int get_random_NZ(int num_rand_bytes, uint8_t *rand_data);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,177 +0,0 @@
/*
* Copyright (c) 2007-2015, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file crypto_misc.h
*/
#ifndef HEADER_CRYPTO_MISC_H
#define HEADER_CRYPTO_MISC_H
#ifdef __cplusplus
extern "C" {
#endif
#include "ssl/ssl_crypto.h"
#include "ssl/ssl_bigint.h"
/**************************************************************************
* X509 declarations
**************************************************************************/
#define X509_OK 0
#define X509_NOT_OK -1
#define X509_VFY_ERROR_NO_TRUSTED_CERT -2
#define X509_VFY_ERROR_BAD_SIGNATURE -3
#define X509_VFY_ERROR_NOT_YET_VALID -4
#define X509_VFY_ERROR_EXPIRED -5
#define X509_VFY_ERROR_SELF_SIGNED -6
#define X509_VFY_ERROR_INVALID_CHAIN -7
#define X509_VFY_ERROR_UNSUPPORTED_DIGEST -8
#define X509_INVALID_PRIV_KEY -9
#define X509_MAX_CERTS -10
/*
* The Distinguished Name
*/
#define X509_NUM_DN_TYPES 3
#define X509_COMMON_NAME 0
#define X509_ORGANIZATION 1
#define X509_ORGANIZATIONAL_UNIT 2
struct _x509_ctx
{
char *ca_cert_dn[X509_NUM_DN_TYPES];
char *cert_dn[X509_NUM_DN_TYPES];
char **subject_alt_dnsnames;
time_t not_before;
time_t not_after;
uint8_t *signature;
uint16_t sig_len;
uint8_t sig_type;
RSA_CTX *rsa_ctx;
bigint *digest;
struct _x509_ctx *next;
};
typedef struct _x509_ctx X509_CTX;
#ifdef CONFIG_SSL_CERT_VERIFICATION
typedef struct
{
X509_CTX *cert[CONFIG_X509_MAX_CA_CERTS];
} CA_CERT_CTX;
#endif
int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx);
void x509_free(X509_CTX *x509_ctx);
#ifdef CONFIG_SSL_CERT_VERIFICATION
int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert);
#endif
#ifdef CONFIG_SSL_FULL_MODE
void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx);
const char * x509_display_error(int error);
#endif
/**************************************************************************
* ASN1 declarations
**************************************************************************/
#define ASN1_INTEGER 0x02
#define ASN1_BIT_STRING 0x03
#define ASN1_OCTET_STRING 0x04
#define ASN1_NULL 0x05
#define ASN1_PRINTABLE_STR2 0x0C
#define ASN1_OID 0x06
#define ASN1_PRINTABLE_STR2 0x0C
#define ASN1_PRINTABLE_STR 0x13
#define ASN1_TELETEX_STR 0x14
#define ASN1_IA5_STR 0x16
#define ASN1_UTC_TIME 0x17
#define ASN1_GENERALIZED_TIME 0x18
#define ASN1_UNICODE_STR 0x1e
#define ASN1_SEQUENCE 0x30
#define ASN1_CONTEXT_DNSNAME 0x82
#define ASN1_SET 0x31
#define ASN1_V3_DATA 0xa3
#define ASN1_IMPLICIT_TAG 0x80
#define ASN1_CONTEXT_DNSNAME 0x82
#define ASN1_EXPLICIT_TAG 0xa0
#define ASN1_V3_DATA 0xa3
#define SIG_TYPE_MD2 0x02
#define SIG_TYPE_MD5 0x04
#define SIG_TYPE_SHA1 0x05
#define SIG_TYPE_SHA256 0x0b
#define SIG_TYPE_SHA384 0x0c
#define SIG_TYPE_SHA512 0x0d
uint32_t get_asn1_length(const uint8_t *buf, int *offset);
int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx);
int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type);
int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type);
int asn1_get_int(const uint8_t *buf, int *offset, uint8_t **object);
int asn1_version(const uint8_t *cert, int *offset, X509_CTX *x509_ctx);
int asn1_validity(const uint8_t *cert, int *offset, X509_CTX *x509_ctx);
int asn1_name(const uint8_t *cert, int *offset, char *dn[]);
int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx);
#ifdef CONFIG_SSL_CERT_VERIFICATION
int asn1_signature(const uint8_t *cert, int *offset, X509_CTX *x509_ctx);
int asn1_find_subjectaltname(const uint8_t* cert, int offset);
int asn1_compare_dn(char * const dn1[], char * const dn2[]);
#endif /* CONFIG_SSL_CERT_VERIFICATION */
int asn1_signature_type(const uint8_t *cert,
int *offset, X509_CTX *x509_ctx);
/**************************************************************************
* MISC declarations
**************************************************************************/
#define SALT_SIZE 8
extern const char unsupported_str[];
typedef void (*crypt_func)(void *, const uint8_t *, uint8_t *, int);
typedef void (*hmac_func)(const uint8_t *msg, int length, const uint8_t *key,
int key_len, uint8_t *digest);
int get_file(const char *filename, uint8_t **buf);
#if defined(CONFIG_SSL_FULL_MODE) || defined(WIN32) || defined(CONFIG_DEBUG)
EXP_FUNC void STDCALL print_blob(const char *format, const uint8_t *data, int size, ...);
#else
#define print_blob(...)
#endif
EXP_FUNC int STDCALL base64_decode(const char *in, int len,
uint8_t *out, int *outlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,147 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file os_port.h
*
* Some stuff to minimise the differences between windows and linux/unix
*/
#ifndef HEADER_OS_PORT_H
#define HEADER_OS_PORT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/unistd.h>
#include "rom/ets_sys.h"
#if 0
#define ssl_printf(fmt, args...) printf(fmt,## args)
#else
#define ssl_printf(fmt, args...)
#endif
void *zalloc(size_t n);
uint32_t system_get_data_of_array_8(const uint8_t*, uint8_t);
void system_get_string_from_flash(const char *, char *, size_t n);
#define STDCALL
#define EXP_FUNC
//struct timeval {
// long tv_sec; /* seconds */
// long tv_usec; /* and microseconds */
//};
#define tls_htons(x) ((uint16_t)((((x) & 0xff) << 8) | (((x) >> 8) & 0xff)))
#define tls_ntohs(x) tls_htons(x)
#define tls_htonl(_n) ((uint32_t)( (((_n) & 0xff) << 24) | (((_n) & 0xff00) << 8) | (((_n) >> 8) & 0xff00) | (((_n) >> 24) & 0xff) ))
#define tls_ntohl(x) tls_htonl(x)
#ifndef be16toh
#define be16toh(x) ((uint16_t)tls_ntohs((uint16_t)(x)))
#endif
#ifndef htobe16
#define htobe16(x) ((uint16_t)tls_htons((uint16_t)(x)))
#endif
#ifndef be32toh
#define be32toh(x) ((uint32_t)tls_ntohl((uint32_t)(x)))
#endif
#ifndef htobe32
#define htobe32(x) ((uint32_t)tls_htonl((uint32_t)(x)))
#endif
#ifndef be64toh
static __inline__ uint64_t be64toh(uint64_t __x);
static __inline__ uint64_t be64toh(uint64_t __x) {return (((uint64_t)be32toh(__x & (uint64_t)0xFFFFFFFFULL)) << 32) | ((uint64_t)be32toh((__x & (uint64_t)0xFFFFFFFF00000000ULL) >> 32));}
#define be64toh(x) be64toh(x)
#endif
#ifndef htobe64
#define htobe64(x) be64toh(x)
#endif
#define SSL_MALLOC(size) os_malloc(size)
#define SSL_REALLOC(mem_ref,size) os_realloc(mem_ref, size)
#define SSL_CALLOC(element, size) os_calloc(element, size)
#define SSL_ZALLOC(size) os_zalloc(size)
#define SSL_FREE(mem_ref) os_free(mem_ref)
#if 0
#define FILE_NAME_LENGTH 25
//#define OUTPUT_FILE "leak_info.txt" //¡ä?¡¤??¨²¡ä?D1??¦Ì?D??¡é
//#define SSL_MALLOC(size) xmalloc (size, __FILE__, __LINE__) //??D?¨º¦Ì??malloc?¡écalloco¨ªfree
//#define CALLOC(elements, size) xcalloc (elements, size, __FILE__, __LINE__)
//#define FREE(mem_ref) xfree(mem_ref)
struct _MEM_INFO
{
void *address;
unsigned int size;
char file_name[FILE_NAME_LENGTH];
unsigned int line;
};
typedef struct _MEM_INFO MEM_INFO;
struct _MEM_LEAK {
MEM_INFO mem_info;
struct _MEM_LEAK * next;
};
typedef struct _MEM_LEAK MEM_LEAK;
void add(MEM_INFO alloc_info);
void erase(unsigned pos);
void clear(void);
void * xmalloc(unsigned int size, const char * file, unsigned int line);
void * xcalloc(unsigned int elements, unsigned int size, const char * file, unsigned int line);
void xfree(void * mem_ref);
void add_mem_info (void * mem_ref, unsigned int size, const char * file, unsigned int line);
void remove_mem_info (void * mem_ref);
void report_mem_leak(void);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,53 +0,0 @@
/*
* ssl_platom.h
*
* Created on: Sep 7, 2015
* Author: liuhan
*/
#ifndef SSL_PLATOM_H_
#define SSL_PLATOM_H_
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_ssl.h"
#include "ssl/ssl_tls1.h"
typedef void * (*ssl_func_type_t)(void);
typedef void * (*bio_func_type_t)(void);
typedef struct
{
ssl_func_type_t ssl_func_type;
} PLATOM_CTX;
#define PLATOM_CTX_ATTR ((PLATOM_CTX *)ssl_ctx->bonus_attr)
/*encapsulation the structure based on the espressif platform*/
struct _MD_CTX
{
unsigned char cksum[16]; /* checksum of the data block */
unsigned char state[48]; /* intermediate digest state */
unsigned char buffer[16]; /* data block being processed */
int left; /* amount of data in buffer */
};
typedef struct _MD_CTX EVP_MD_CTX;
typedef unsigned char EVP_MD;
typedef struct _x509_ctx X509;
typedef struct _x509_ctx X509_STORE_CTX;
//typedef struct _SSL SSL;
//typedef struct _SSL_CTX SSL_CTX;
#define ESP_SSL_ERROR_NONE 0
#define ESP_SSL_ERROR_WANT_WRITE 1
#define ESP_SSL_ERROR_WANT_READ 2
#define ESP_SSL_ERROR_WANT_X509_LOOKUP 3
#define ESP_SSL_ERROR_SYSCALL 4
#define ESP_SSL_ERROR_ZERO_RETURN 5
#define ESP_SSL_ERROR_SSL 6
#define ESP_SSL_FILETYPE_PEM 10
#define ESP_SSL_VERIFY_PEER 11
#define ESP_EVP_MAX_MD_SIZE 6
#define ESP_SSL_VERIFY_FAIL_IF_NO_PEER_CERT 4
#endif /* SSL_PLATOM_H_ */

View File

@ -1,500 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @mainpage axTLS API
*
* @image html axolotl.jpg
*
* The axTLS library has features such as:
* - The TLSv1 SSL client/server protocol
* - No requirement to use any openssl libraries.
* - A choice between AES block (128/256 bit) and RC4 (128 bit) stream ciphers.
* - RSA encryption/decryption with variable sized keys (up to 4096 bits).
* - Certificate chaining and peer authentication.
* - Session resumption, session renegotiation.
* - ASN.1, X.509, PKCS#8, PKCS#12 keys/certificates with DER/PEM encoding.
* - Highly configurable compile time options.
* - Portable across many platforms (written in ANSI C), and has language
* bindings in C, C#, VB.NET, Java, Perl and Lua.
* - Partial openssl API compatibility (via a wrapper).
* - A very small footprint (around 50-60kB for the library in 'server-only'
* mode).
* - No dependencies on sockets - can use serial connections for example.
* - A very simple API - ~ 20 functions/methods.
*
* A list of these functions/methods are described below.
*
* @ref c_api
*
* @ref bigint_api
*
* @ref csharp_api
*
* @ref java_api
*/
#ifndef HEADER_SSL_H
#define HEADER_SSL_H
#ifdef __cplusplus
extern "C" {
#endif
//#include <time.h>
typedef long time_t;
/* need to predefine before ssl_lib.h gets to it */
#define SSL_SESSION_ID_SIZE 32
#include "ssl/ssl_tls1.h"
/* The optional parameters that can be given to the client/server SSL engine */
#define SSL_CLIENT_AUTHENTICATION 0x00010000
#define SSL_SERVER_VERIFY_LATER 0x00020000
#define SSL_NO_DEFAULT_KEY 0x00040000
#define SSL_DISPLAY_STATES 0x00080000
#define SSL_DISPLAY_BYTES 0x00100000
#define SSL_DISPLAY_CERTS 0x00200000
#define SSL_DISPLAY_RSA 0x00400000
#define SSL_CONNECT_IN_PARTS 0x00800000
/* errors that can be generated */
#define SSL_OK 0
#define SSL_NOT_OK -1
#define SSL_ERROR_DEAD -2
#define SSL_CLOSE_NOTIFY -3
#define SSL_ERROR_CONN_LOST -256
#define SSL_ERROR_SOCK_SETUP_FAILURE -258
#define SSL_ERROR_INVALID_HANDSHAKE -260
#define SSL_ERROR_INVALID_PROT_MSG -261
#define SSL_ERROR_INVALID_HMAC -262
#define SSL_ERROR_INVALID_VERSION -263
#define SSL_ERROR_INVALID_SESSION -265
#define SSL_ERROR_NO_CIPHER -266
#define SSL_ERROR_BAD_CERTIFICATE -268
#define SSL_ERROR_INVALID_KEY -269
#define SSL_ERROR_FINISHED_INVALID -271
#define SSL_ERROR_NO_CERT_DEFINED -272
#define SSL_ERROR_NO_CLIENT_RENOG -273
#define SSL_ERROR_NOT_SUPPORTED -274
#define SSL_X509_OFFSET -512
#define SSL_X509_ERROR(A) (SSL_X509_OFFSET+A)
/* alert types that are recognized */
#define SSL_ALERT_TYPE_WARNING 1
#define SLL_ALERT_TYPE_FATAL 2
/* these are all the alerts that are recognized */
#define SSL_ALERT_CLOSE_NOTIFY 0
#define SSL_ALERT_UNEXPECTED_MESSAGE 10
#define SSL_ALERT_BAD_RECORD_MAC 20
#define SSL_ALERT_HANDSHAKE_FAILURE 40
#define SSL_ALERT_BAD_CERTIFICATE 42
#define SSL_ALERT_ILLEGAL_PARAMETER 47
#define SSL_ALERT_DECODE_ERROR 50
#define SSL_ALERT_DECRYPT_ERROR 51
#define SSL_ALERT_INVALID_VERSION 70
#define SSL_ALERT_NO_RENEGOTIATION 100
/* The ciphers that are supported */
#define SSL_AES128_SHA 0x2f
#define SSL_AES256_SHA 0x35
#define SSL_RC4_128_SHA 0x05
#define SSL_RC4_128_MD5 0x04
/* build mode ids' */
#define SSL_BUILD_SKELETON_MODE 0x01
#define SSL_BUILD_SERVER_ONLY 0x02
#define SSL_BUILD_ENABLE_VERIFICATION 0x03
#define SSL_BUILD_ENABLE_CLIENT 0x04
#define SSL_BUILD_FULL_MODE 0x05
/* offsets to retrieve configuration information */
#define SSL_BUILD_MODE 0
#define SSL_MAX_CERT_CFG_OFFSET 1
#define SSL_MAX_CA_CERT_CFG_OFFSET 2
#define SSL_HAS_PEM 3
/* default session sizes */
#define SSL_DEFAULT_SVR_SESS 1 //modify 5->1 by lhan
#define SSL_DEFAULT_CLNT_SESS 1
/* X.509/X.520 distinguished name types */
#define SSL_X509_CERT_COMMON_NAME 0
#define SSL_X509_CERT_ORGANIZATION 1
#define SSL_X509_CERT_ORGANIZATIONAL_NAME 2
#define SSL_X509_CA_CERT_COMMON_NAME 3
#define SSL_X509_CA_CERT_ORGANIZATION 4
#define SSL_X509_CA_CERT_ORGANIZATIONAL_NAME 5
/* SSL object loader types */
#define SSL_OBJ_X509_CERT 1
#define SSL_OBJ_X509_CACERT 2
#define SSL_OBJ_RSA_KEY 3
#define SSL_OBJ_PKCS8 4
#define SSL_OBJ_PKCS12 5
/**
* @defgroup c_api Standard C API
* @brief The standard interface in C.
* @{
*/
/**
* @brief Establish a new client/server context.
*
* This function is called before any client/server SSL connections are made.
*
* Each new connection will use the this context's private key and
* certificate chain. If a different certificate chain is required, then a
* different context needs to be be used.
*
* There are two threading models supported - a single thread with one
* SSL_CTX can support any number of SSL connections - and multiple threads can
* support one SSL_CTX object each (the default). But if a single SSL_CTX
* object uses many SSL objects in individual threads, then the
* CONFIG_SSL_CTX_MUTEXING option needs to be configured.
*
* @param options [in] Any particular options. At present the options
* supported are:
* - SSL_SERVER_VERIFY_LATER (client only): Don't stop a handshake if the server
* authentication fails. The certificate can be authenticated later with a
* call to ssl_verify_cert().
* - SSL_CLIENT_AUTHENTICATION (server only): Enforce client authentication
* i.e. each handshake will include a "certificate request" message from the
* server. Only available if verification has been enabled.
* - SSL_DISPLAY_BYTES (full mode build only): Display the byte sequences
* during the handshake.
* - SSL_DISPLAY_STATES (full mode build only): Display the state changes
* during the handshake.
* - SSL_DISPLAY_CERTS (full mode build only): Display the certificates that
* are passed during a handshake.
* - SSL_DISPLAY_RSA (full mode build only): Display the RSA key details that
* are passed during a handshake.
* - SSL_CONNECT_IN_PARTS (client only): To use a non-blocking version of
* ssl_client_new().
* @param num_sessions [in] The number of sessions to be used for session
* caching. If this value is 0, then there is no session caching. This option
* is not used in skeleton mode.
* @return A client/server context.
*/
EXP_FUNC SSL_CTX * STDCALL ssl_ctx_new(uint32_t options, int num_sessions);
/**
* @brief Remove a client/server context.
*
* Frees any used resources used by this context. Each connection will be
* sent a "Close Notify" alert (if possible).
* @param ssl_ctx [in] The client/server context.
*/
EXP_FUNC void STDCALL ssl_ctx_free(SSL_CTX *ssl_ctx);
/**
* @brief (server only) Establish a new SSL connection to an SSL client.
*
* It is up to the application to establish the logical connection (whether it
* is a socket, serial connection etc).
* @param ssl_ctx [in] The server context.
* @param client_fd [in] The client's file descriptor.
* @return An SSL object reference.
*/
EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd);
/**
* @brief (client only) Establish a new SSL connection to an SSL server.
*
* It is up to the application to establish the initial logical connection
* (whether it is a socket, serial connection etc).
*
* This is a normally a blocking call - it will finish when the handshake is
* complete (or has failed). To use in non-blocking mode, set
* SSL_CONNECT_IN_PARTS in ssl_ctx_new().
* @param ssl_ctx [in] The client context.
* @param client_fd [in] The client's file descriptor.
* @param session_id [in] A 32 byte session id for session resumption. This
* can be null if no session resumption is being used or required. This option
* is not used in skeleton mode.
* @param sess_id_size The size of the session id (max 32)
* @return An SSL object reference. Use ssl_handshake_status() to check
* if a handshake succeeded.
*/
EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size);
/**
* @brief Free any used resources on this connection.
* A "Close Notify" message is sent on this connection (if possible). It is up
* to the application to close the socket or file descriptor.
* @param ssl [in] The ssl object reference.
*/
EXP_FUNC void STDCALL ssl_free(SSL *ssl);
/**
* @brief Read the SSL data stream.
* If the socket is non-blocking and data is blocked then SSO_OK will be
* returned.
* @param ssl [in] An SSL object reference.
* @param in_data [out] If the read was successful, a pointer to the read
* buffer will be here. Do NOT ever free this memory as this buffer is used in
* sucessive calls. If the call was unsuccessful, this value will be null.
* @return The number of decrypted bytes:
* - if > 0, then the handshaking is complete and we are returning the number
* of decrypted bytes.
* - SSL_OK if the handshaking stage is successful (but not yet complete).
* - < 0 if an error.
* @see ssl.h for the error code list.
* @note Use in_data before doing any successive ssl calls.
*/
EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data);
/**
* @brief Write to the SSL data stream.
* if the socket is non-blocking and data is blocked then a check is made
* to ensure that all data is sent (i.e. blocked mode is forced).
* @param ssl [in] An SSL obect reference.
* @param out_data [in] The data to be written
* @param out_len [in] The number of bytes to be written.
* @return The number of bytes sent, or if < 0 if an error.
* @see ssl.h for the error code list.
*/
EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len);
/**
* @brief Find an ssl object based on a file descriptor.
*
* Goes through the list of SSL objects maintained in a client/server context
* to look for a file descriptor match.
* @param ssl_ctx [in] The client/server context.
* @param client_fd [in] The file descriptor.
* @return A reference to the SSL object. Returns null if the object could not
* be found.
*/
EXP_FUNC SSL * STDCALL ssl_find(SSL_CTX *ssl_ctx, int client_fd);
/**
* @brief Get the session id for a handshake.
*
* This will be a 32 byte sequence and is available after the first
* handshaking messages are sent.
* @param ssl [in] An SSL object reference.
* @return The session id as a 32 byte sequence.
* @note A SSLv23 handshake may have only 16 valid bytes.
*/
EXP_FUNC const uint8_t * STDCALL ssl_get_session_id(const SSL *ssl);
/**
* @brief Get the session id size for a handshake.
*
* This will normally be 32 but could be 0 (no session id) or something else.
* @param ssl [in] An SSL object reference.
* @return The size of the session id.
*/
EXP_FUNC uint8_t STDCALL ssl_get_session_id_size(const SSL *ssl);
/**
* @brief Return the cipher id (in the SSL form).
* @param ssl [in] An SSL object reference.
* @return The cipher id. This will be one of the following:
* - SSL_AES128_SHA (0x2f)
* - SSL_AES256_SHA (0x35)
* - SSL_RC4_128_SHA (0x05)
* - SSL_RC4_128_MD5 (0x04)
*/
EXP_FUNC uint8_t STDCALL ssl_get_cipher_id(const SSL *ssl);
/**
* @brief Return the status of the handshake.
* @param ssl [in] An SSL object reference.
* @return SSL_OK if the handshake is complete and ok.
* @see ssl.h for the error code list.
*/
EXP_FUNC int STDCALL ssl_handshake_status(const SSL *ssl);
/**
* @brief Retrieve various parameters about the axTLS engine.
* @param offset [in] The configuration offset. It will be one of the following:
* - SSL_BUILD_MODE The build mode. This will be one of the following:
* - SSL_BUILD_SERVER_ONLY (basic server mode)
* - SSL_BUILD_ENABLE_VERIFICATION (server can do client authentication)
* - SSL_BUILD_ENABLE_CLIENT (client/server capabilties)
* - SSL_BUILD_FULL_MODE (client/server with diagnostics)
* - SSL_BUILD_SKELETON_MODE (skeleton mode)
* - SSL_MAX_CERT_CFG_OFFSET The maximum number of certificates allowed.
* - SSL_MAX_CA_CERT_CFG_OFFSET The maximum number of CA certificates allowed.
* - SSL_HAS_PEM 1 if supported
* @return The value of the requested parameter.
*/
EXP_FUNC int STDCALL ssl_get_config(int offset);
/**
* @brief Display why the handshake failed.
*
* This call is only useful in a 'full mode' build. The output is to stdout.
* @param error_code [in] An error code.
* @see ssl.h for the error code list.
*/
//EXP_FUNC void STDCALL ssl_display_error(int error_code);
/**
* @brief Authenticate a received certificate.
*
* This call is usually made by a client after a handshake is complete and the
* context is in SSL_SERVER_VERIFY_LATER mode.
* @param ssl [in] An SSL object reference.
* @return SSL_OK if the certificate is verified.
*/
EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl);
/**
* @brief Retrieve an X.509 distinguished name component.
*
* When a handshake is complete and a certificate has been exchanged, then the
* details of the remote certificate can be retrieved.
*
* This will usually be used by a client to check that the server's common
* name matches the URL.
*
* @param ssl [in] An SSL object reference.
* @param component [in] one of:
* - SSL_X509_CERT_COMMON_NAME
* - SSL_X509_CERT_ORGANIZATION
* - SSL_X509_CERT_ORGANIZATIONAL_NAME
* - SSL_X509_CA_CERT_COMMON_NAME
* - SSL_X509_CA_CERT_ORGANIZATION
* - SSL_X509_CA_CERT_ORGANIZATIONAL_NAME
* @return The appropriate string (or null if not defined)
* @note Verification build mode must be enabled.
*/
EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component);
/**
* @brief Retrieve a Subject Alternative DNSName
*
* When a handshake is complete and a certificate has been exchanged, then the
* details of the remote certificate can be retrieved.
*
* This will usually be used by a client to check that the server's DNS
* name matches the URL.
*
* @param ssl [in] An SSL object reference.
* @param dnsindex [in] The index of the DNS name to retrieve.
* @return The appropriate string (or null if not defined)
* @note Verification build mode must be enabled.
*/
EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl, int dnsindex);
/**
* @brief Force the client to perform its handshake again.
*
* For a client this involves sending another "client hello" message.
* For the server is means sending a "hello request" message.
*
* This is a blocking call on the client (until the handshake completes).
*
* @param ssl [in] An SSL object reference.
* @return SSL_OK if renegotiation instantiation was ok
*/
EXP_FUNC int STDCALL ssl_renegotiate(SSL *ssl);
/**
* @brief Process a file that is in binary DER or ASCII PEM format.
*
* These are temporary objects that are used to load private keys,
* certificates etc into memory.
* @param ssl_ctx [in] The client/server context.
* @param obj_type [in] The format of the file. Can be one of:
* - SSL_OBJ_X509_CERT (no password required)
* - SSL_OBJ_X509_CACERT (no password required)
* - SSL_OBJ_RSA_KEY (AES128/AES256 PEM encryption supported)
* - SSL_OBJ_PKCS8 (RC4-128 encrypted data supported)
* - SSL_OBJ_PKCS12 (RC4-128 encrypted data supported)
*
* PEM files are automatically detected (if supported). The object type is
* also detected, and so is not relevant for these types of files.
* @param filename [in] The location of a file in DER/PEM format.
* @param password [in] The password used. Can be null if not required.
* @return SSL_OK if all ok
* @note Not available in skeleton build mode.
*/
EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type, const char *filename, const char *password);
/**
* @brief Process binary data.
*
* These are temporary objects that are used to load private keys,
* certificates etc into memory.
* @param ssl_ctx [in] The client/server context.
* @param obj_type [in] The format of the memory data.
* @param data [in] The binary data to be loaded.
* @param len [in] The amount of data to be loaded.
* @param password [in] The password used. Can be null if not required.
* @return SSL_OK if all ok
* @see ssl_obj_load for more details on obj_type.
*/
EXP_FUNC int STDCALL ssl_obj_memory_load(SSL_CTX *ssl_ctx, int obj_type, const uint8_t *data, int len, const char *password);
#ifdef CONFIG_SSL_GENERATE_X509_CERT
/**
* @brief Create an X.509 certificate.
*
* This certificate is a self-signed v1 cert with a fixed start/stop validity
* times. It is signed with an internal private key in ssl_ctx.
*
* @param ssl_ctx [in] The client/server context.
* @param options [in] Not used yet.
* @param dn [in] An array of distinguished name strings. The array is defined
* by:
* - SSL_X509_CERT_COMMON_NAME (0)
* - If SSL_X509_CERT_COMMON_NAME is empty or not defined, then the
* hostname will be used.
* - SSL_X509_CERT_ORGANIZATION (1)
* - If SSL_X509_CERT_ORGANIZATION is empty or not defined, then $USERNAME
* will be used.
* - SSL_X509_CERT_ORGANIZATIONAL_NAME (2)
* - SSL_X509_CERT_ORGANIZATIONAL_NAME is optional.
* @param cert_data [out] The certificate as a sequence of bytes.
* @return < 0 if an error, or the size of the certificate in bytes.
* @note cert_data must be freed when there is no more need for it.
*/
EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, uint32_t options, const char * dn[], uint8_t **cert_data);
#endif
/**
* @brief Return the axTLS library version as a string.
*/
EXP_FUNC const char * STDCALL ssl_version(void);
/** @} */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,312 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file tls1.h
*
* @brief The definitions for the TLS library.
*/
#ifndef HEADER_SSL_LIB_H
#define HEADER_SSL_LIB_H
#ifdef __cplusplus
extern "C" {
#endif
#include "ssl/ssl_version.h"
#include "ssl/ssl_config.h"
#include "ssl/ssl_crypto.h"
#include "ssl/ssl_crypto_misc.h"
#define SSL_PROTOCOL_MIN_VERSION 0x31 /* TLS v1.0 */
#define SSL_PROTOCOL_MINOR_VERSION 0x02 /* TLS v1.1 */
#define SSL_PROTOCOL_VERSION_MAX 0x32 /* TLS v1.1 */
#define SSL_PROTOCOL_VERSION1_1 0x32 /* TLS v1.1 */
#define SSL_RANDOM_SIZE 32
#define SSL_SECRET_SIZE 48
#define SSL_FINISHED_HASH_SIZE 12
#define SSL_RECORD_SIZE 5
#define SSL_SERVER_READ 0
#define SSL_SERVER_WRITE 1
#define SSL_CLIENT_READ 2
#define SSL_CLIENT_WRITE 3
#define SSL_HS_HDR_SIZE 4
/* the flags we use while establishing a connection */
#define SSL_NEED_RECORD 0x0001
#define SSL_TX_ENCRYPTED 0x0002
#define SSL_RX_ENCRYPTED 0x0004
#define SSL_SESSION_RESUME 0x0008
#define SSL_IS_CLIENT 0x0010
#define SSL_HAS_CERT_REQ 0x0020
#define SSL_SENT_CLOSE_NOTIFY 0x0040
/* some macros to muck around with flag bits */
#define SET_SSL_FLAG(A) (ssl->flag |= A)
#define CLR_SSL_FLAG(A) (ssl->flag &= ~A)
#define IS_SET_SSL_FLAG(A) (ssl->flag & A)
#define MAX_KEY_BYTE_SIZE 512 /* for a 4096 bit key */
#define RT_MAX_PLAIN_LENGTH 1460
#define RT_EXTRA 1024
#define BM_RECORD_OFFSET 5
#ifdef CONFIG_SSL_SKELETON_MODE
#define NUM_PROTOCOLS 1
#else
#define NUM_PROTOCOLS 4
#endif
#define PARANOIA_CHECK(A, B) if (A < B) { \
ret = SSL_ERROR_INVALID_HANDSHAKE; goto error; }
/*Max Fragment Length Negotiation*/
enum {
SSL_MAX_FRAG_LEN_NONE,
SSL_MAX_FRAG_LEN_512,
SSL_MAX_FRAG_LEN_1024,
SSL_MAX_FRAG_LEN_2048,
SSL_MAX_FRAG_LEN_4096,
SSL_MAX_FRAG_LEN_8192,
SSL_MAX_FRAG_LEN_INVALID
};
/* protocol types */
enum
{
PT_CHANGE_CIPHER_SPEC = 20,
PT_ALERT_PROTOCOL,
PT_HANDSHAKE_PROTOCOL,
PT_APP_PROTOCOL_DATA
};
/* handshaking types */
enum
{
HS_HELLO_REQUEST,
HS_CLIENT_HELLO,
HS_SERVER_HELLO,
HS_CERTIFICATE = 11,
HS_SERVER_KEY_XCHG,
HS_CERT_REQ,
HS_SERVER_HELLO_DONE,
HS_CERT_VERIFY,
HS_CLIENT_KEY_XCHG,
HS_FINISHED = 20
};
typedef struct
{
uint8_t cipher;
uint8_t key_size;
uint8_t iv_size;
uint8_t key_block_size;
uint8_t padding_size;
uint8_t digest_size;
hmac_func hmac;
crypt_func encrypt;
crypt_func decrypt;
} cipher_info_t;
struct _SSLObjLoader
{
uint8_t *buf;
int len;
};
typedef struct _SSLObjLoader SSLObjLoader;
typedef struct
{
time_t conn_time;
uint8_t session_id[SSL_SESSION_ID_SIZE];
uint8_t master_secret[SSL_SECRET_SIZE];
} SSL_SESSION;
typedef struct
{
uint8_t *buf;
int size;
} SSL_CERT;
typedef struct
{
MD5_CTX md5_ctx;
SHA1_CTX sha1_ctx;
uint8_t final_finish_mac[SSL_FINISHED_HASH_SIZE];
uint8_t *key_block;
uint8_t master_secret[SSL_SECRET_SIZE];
uint8_t client_random[SSL_RANDOM_SIZE]; /* client's random sequence */
uint8_t server_random[SSL_RANDOM_SIZE]; /* server's random sequence */
uint16_t bm_proc_index;
} DISPOSABLE_CTX;
struct _SSL
{
uint32_t flag;
uint16_t need_bytes;
uint16_t got_bytes;
uint8_t record_type;
uint8_t cipher;
uint8_t sess_id_size;
uint8_t version;
uint8_t client_version;
int16_t next_state;
int16_t hs_status;
DISPOSABLE_CTX *dc; /* temporary data which we'll get rid of soon */
int client_fd;
const cipher_info_t *cipher_info;
void *encrypt_ctx;
void *decrypt_ctx;
uint8_t *bm_all_data;
uint32_t max_fragme_length;
uint8_t *bm_data;
uint16_t bm_index;
uint16_t bm_read_index;
struct _SSL *next; /* doubly linked list */
struct _SSL *prev;
struct _SSL_CTX *ssl_ctx; /* back reference to a clnt/svr ctx */
#ifndef CONFIG_SSL_SKELETON_MODE
uint16_t session_index;
SSL_SESSION *session;
#endif
#ifdef CONFIG_SSL_CERT_VERIFICATION
X509_CTX *x509_ctx;
#endif
uint8_t session_id[SSL_SESSION_ID_SIZE];
uint8_t client_mac[SHA1_SIZE]; /* for HMAC verification */
uint8_t server_mac[SHA1_SIZE]; /* for HMAC verification */
uint8_t read_sequence[8]; /* 64 bit sequence number */
uint8_t write_sequence[8]; /* 64 bit sequence number */
uint8_t hmac_header[SSL_RECORD_SIZE]; /* rx hmac */
};
typedef struct _SSL SSL;
struct _SSL_CTX
{
uint32_t options;
uint8_t chain_length;
RSA_CTX *rsa_ctx;
#ifdef CONFIG_SSL_CERT_VERIFICATION
CA_CERT_CTX *ca_cert_ctx;
#endif
SSL *head;
SSL *tail;
SSL_CERT certs[CONFIG_SSL_MAX_CERTS];
#ifndef CONFIG_SSL_SKELETON_MODE
uint16_t num_sessions;
SSL_SESSION **ssl_sessions;
#endif
#ifdef CONFIG_SSL_CTX_MUTEXING
SSL_CTX_MUTEX_TYPE mutex;
#endif
//#ifdef CONFIG_OPENSSL_COMPATIBLE
void *bonus_attr;
//#endif
};
typedef struct _SSL_CTX SSL_CTX;
/* backwards compatibility */
typedef struct _SSL_CTX SSLCTX;
extern const uint8_t ssl_prot_prefs[NUM_PROTOCOLS];
SSL *ssl_new(SSL_CTX *ssl_ctx, int client_fd);
void disposable_new(SSL *ssl);
void disposable_free(SSL *ssl);
int send_packet(SSL *ssl, uint8_t protocol,
const uint8_t *in, int length);
int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len);
int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len);
int process_finished(SSL *ssl, uint8_t *buf, int hs_len);
int process_sslv23_client_hello(SSL *ssl);
int send_alert(SSL *ssl, int error_code);
int send_finished(SSL *ssl);
int send_certificate(SSL *ssl);
int basic_read(SSL *ssl, uint8_t **in_data);
int send_change_cipher_spec(SSL *ssl);
void finished_digest(SSL *ssl, const char *label, uint8_t *digest);
void generate_master_secret(SSL *ssl, const uint8_t *premaster_secret);
void add_packet(SSL *ssl, const uint8_t *pkt, int len);
int add_cert(SSL_CTX *ssl_ctx, const uint8_t *buf, int len);
int add_private_key(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj);
void ssl_obj_free(SSLObjLoader *ssl_obj);
int pkcs8_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password);
int pkcs12_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password);
int load_key_certs(SSL_CTX *ssl_ctx);
#ifdef CONFIG_SSL_CERT_VERIFICATION
int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len);
void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx);
#endif
#ifdef CONFIG_SSL_ENABLE_CLIENT
int do_client_connect(SSL *ssl);
#endif
#ifdef CONFIG_SSL_FULL_MODE
//void DISPLAY_STATE(SSL *ssl, int is_send, uint8_t state, int not_ok);
//void DISPLAY_BYTES(SSL *ssl, const char *format,
// const uint8_t *data, int size, ...);
//void DISPLAY_CERT(SSL *ssl, const X509_CTX *x509_ctx);
//void DISPLAY_RSA(SSL *ssl, const RSA_CTX *rsa_ctx);
//void DISPLAY_ALERT(SSL *ssl, int alert);
#else
#define DISPLAY_STATE(A,B,C,D)
#define DISPLAY_CERT(A,B)
#define DISPLAY_RSA(A,B)
#define DISPLAY_ALERT(A, B)
#ifdef WIN32
void DISPLAY_BYTES(SSL *ssl, const char *format,/* win32 has no variadic macros */
const uint8_t *data, int size, ...);
#else
#define DISPLAY_BYTES(A,B,C,D,...)
#endif
#endif
#ifdef CONFIG_SSL_CERT_VERIFICATION
int process_certificate(SSL *ssl, X509_CTX **x509_ctx);
#endif
SSL_SESSION *ssl_session_update(int max_sessions,
SSL_SESSION *ssl_sessions[], SSL *ssl,
const uint8_t *session_id);
void kill_ssl_session(SSL_SESSION **ssl_sessions, SSL *ssl);
/*Max Fragment Length Negotiation*/
bool ssl_fragment_length_negotiation(SSL* ssl, int fragmet_level);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1 +0,0 @@
#define AXTLS_VERSION "1.5.3"

View File

@ -1,283 +0,0 @@
/*
* Copyright (c) 2015, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//#include <string.h>
//#include "os_port.h"
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_crypto.h"
//#include "crypto.h"
#include "lwip/mem.h"
#define GET_UINT32(n,b,i) \
{ \
(n) = ((uint32_t) (b)[(i) ] << 24) \
| ((uint32_t) (b)[(i) + 1] << 16) \
| ((uint32_t) (b)[(i) + 2] << 8) \
| ((uint32_t) (b)[(i) + 3] ); \
}
#define PUT_UINT32(n,b,i) \
{ \
(b)[(i) ] = (uint8_t) ((n) >> 24); \
(b)[(i) + 1] = (uint8_t) ((n) >> 16); \
(b)[(i) + 2] = (uint8_t) ((n) >> 8); \
(b)[(i) + 3] = (uint8_t) ((n) ); \
}
static const uint8_t sha256_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/**
* Initialize the SHA256 context
*/
void SHA256_Init(SHA256_CTX *ctx)
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x6A09E667;
ctx->state[1] = 0xBB67AE85;
ctx->state[2] = 0x3C6EF372;
ctx->state[3] = 0xA54FF53A;
ctx->state[4] = 0x510E527F;
ctx->state[5] = 0x9B05688C;
ctx->state[6] = 0x1F83D9AB;
ctx->state[7] = 0x5BE0CD19;
}
static void SHA256_Process(const uint8_t digest[64], SHA256_CTX *ctx)
{
uint32_t temp1, temp2, W[64];
uint32_t A, B, C, D, E, F, G, H;
GET_UINT32(W[0], digest, 0);
GET_UINT32(W[1], digest, 4);
GET_UINT32(W[2], digest, 8);
GET_UINT32(W[3], digest, 12);
GET_UINT32(W[4], digest, 16);
GET_UINT32(W[5], digest, 20);
GET_UINT32(W[6], digest, 24);
GET_UINT32(W[7], digest, 28);
GET_UINT32(W[8], digest, 32);
GET_UINT32(W[9], digest, 36);
GET_UINT32(W[10], digest, 40);
GET_UINT32(W[11], digest, 44);
GET_UINT32(W[12], digest, 48);
GET_UINT32(W[13], digest, 52);
GET_UINT32(W[14], digest, 56);
GET_UINT32(W[15], digest, 60);
#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
#define F0(x,y,z) ((x & y) | (z & (x | y)))
#define F1(x,y,z) (z ^ (x & (y ^ z)))
#define R(t) \
( \
W[t] = S1(W[t - 2]) + W[t - 7] + \
S0(W[t - 15]) + W[t - 16] \
)
#define P(a,b,c,d,e,f,g,h,x,K) \
{ \
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
temp2 = S2(a) + F0(a,b,c); \
d += temp1; h = temp1 + temp2; \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
E = ctx->state[4];
F = ctx->state[5];
G = ctx->state[6];
H = ctx->state[7];
P(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
P(H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
P(G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
P(F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
P(E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
P(D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
P(C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
P(B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
P(A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
P(H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[4] += E;
ctx->state[5] += F;
ctx->state[6] += G;
ctx->state[7] += H;
}
/**
* Accepts an array of octets as the next portion of the message.
*/
void SHA256_Update(SHA256_CTX *ctx, const uint8_t * msg, int len)
{
uint32_t left = ctx->total[0] & 0x3F;
uint32_t fill = 64 - left;
ctx->total[0] += len;
ctx->total[0] &= 0xFFFFFFFF;
if (ctx->total[0] < len)
ctx->total[1]++;
if (left && len >= fill)
{
memcpy((void *) (ctx->buffer + left), (void *)msg, fill);
SHA256_Process(ctx->buffer, ctx);
len -= fill;
msg += fill;
left = 0;
}
while (len >= 64)
{
SHA256_Process(msg, ctx);
len -= 64;
msg += 64;
}
if (len)
{
memcpy((void *) (ctx->buffer + left), (void *) msg, len);
}
}
/**
* Return the 256-bit message digest into the user's array
*/
void SHA256_Final(uint8_t *digest, SHA256_CTX *ctx)
{
uint32_t last, padn;
uint32_t high, low;
uint8_t msglen[8];
uint8_t *sha256_padding_ram = (uint8_t *)SSL_MALLOC(64);
memcpy(sha256_padding_ram, sha256_padding, 64);
high = (ctx->total[0] >> 29)
| (ctx->total[1] << 3);
low = (ctx->total[0] << 3);
PUT_UINT32(high, msglen, 0);
PUT_UINT32(low, msglen, 4);
last = ctx->total[0] & 0x3F;
padn = (last < 56) ? (56 - last) : (120 - last);
SHA256_Update(ctx, sha256_padding_ram, padn);
SHA256_Update(ctx, msglen, 8);
PUT_UINT32(ctx->state[0], digest, 0);
PUT_UINT32(ctx->state[1], digest, 4);
PUT_UINT32(ctx->state[2], digest, 8);
PUT_UINT32(ctx->state[3], digest, 12);
PUT_UINT32(ctx->state[4], digest, 16);
PUT_UINT32(ctx->state[5], digest, 20);
PUT_UINT32(ctx->state[6], digest, 24);
PUT_UINT32(ctx->state[7], digest, 28);
SSL_FREE(sha256_padding_ram);
}

View File

@ -1,80 +0,0 @@
/*
* Copyright (c) 2015, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//#include <string.h>
//#include "os_port.h"
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_crypto.h"
//#include "crypto.h"
#include "lwip/mem.h"
/**
* Initialize the SHA384 context
*/
void SHA384_Init(SHA384_CTX *ctx)
{
//Set initial hash value
ctx->h_dig.h[0] = 0xCBBB9D5DC1059ED8ULL;
ctx->h_dig.h[1] = 0x629A292A367CD507ULL;
ctx->h_dig.h[2] = 0x9159015A3070DD17ULL;
ctx->h_dig.h[3] = 0x152FECD8F70E5939ULL;
ctx->h_dig.h[4] = 0x67332667FFC00B31ULL;
ctx->h_dig.h[5] = 0x8EB44A8768581511ULL;
ctx->h_dig.h[6] = 0xDB0C2E0D64F98FA7ULL;
ctx->h_dig.h[7] = 0x47B5481DBEFA4FA4ULL;
// Number of bytes in the buffer
ctx->size = 0;
// Total length of the message
ctx->totalSize = 0;
}
/**
* Accepts an array of octets as the next portion of the message.
*/
void SHA384_Update(SHA384_CTX *ctx, const uint8_t * msg, int len)
{
// The function is defined in the exact same manner as SHA-512
SHA512_Update(ctx, msg, len);
}
/**
* Return the 384-bit message digest into the user's array
*/
void SHA384_Final(uint8_t *digest, SHA384_CTX *ctx)
{
// The function is defined in the exact same manner as SHA-512
SHA512_Final(NULL, ctx);
// Copy the resulting digest
if (digest != NULL)
memcpy(digest, ctx->h_dig.digest, SHA384_SIZE);
}

View File

@ -1,229 +0,0 @@
/*
* Copyright (c) 2015, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//#include <string.h>
//#include "os_port.h"
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_crypto.h"
//#include "crypto.h"
#include "lwip/mem.h"
#define SHR64(a, n) ((a) >> (n))
#define ROR64(a, n) (((a) >> (n)) | ((a) << (64 - (n))))
#define CH(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define MAJ(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
#define SIGMA1(x) (ROR64(x, 28) ^ ROR64(x, 34) ^ ROR64(x, 39))
#define SIGMA2(x) (ROR64(x, 14) ^ ROR64(x, 18) ^ ROR64(x, 41))
#define SIGMA3(x) (ROR64(x, 1) ^ ROR64(x, 8) ^ SHR64(x, 7))
#define SIGMA4(x) (ROR64(x, 19) ^ ROR64(x, 61) ^ SHR64(x, 6))
#define MIN(x, y) ((x) < (y) ? x : y)
static const uint8_t padding[128] =
{
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint64_t k[80] =
{
0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL, 0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL, 0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
0xD807AA98A3030242ULL, 0x12835B0145706FBEULL, 0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL, 0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL,
0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL, 0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL,
0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL, 0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL, 0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL,
0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL, 0x06CA6351E003826FULL, 0x142929670A0E6E70ULL,
0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL, 0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL, 0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL,
0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL, 0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL,
0xD192E819D6EF5218ULL, 0xD69906245565A910ULL, 0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL, 0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL,
0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL, 0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL,
0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL, 0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL, 0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL,
0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL, 0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL,
0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL, 0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL, 0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL,
0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL, 0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
};
/**
* Initialize the SHA512 context
*/
void SHA512_Init(SHA512_CTX *ctx)
{
ctx->h_dig.h[0] = 0x6A09E667F3BCC908ULL;
ctx->h_dig.h[1] = 0xBB67AE8584CAA73BULL;
ctx->h_dig.h[2] = 0x3C6EF372FE94F82BULL;
ctx->h_dig.h[3] = 0xA54FF53A5F1D36F1ULL;
ctx->h_dig.h[4] = 0x510E527FADE682D1ULL;
ctx->h_dig.h[5] = 0x9B05688C2B3E6C1FULL;
ctx->h_dig.h[6] = 0x1F83D9ABFB41BD6BULL;
ctx->h_dig.h[7] = 0x5BE0CD19137E2179ULL;
ctx->size = 0;
ctx->totalSize = 0;
}
static void SHA512_Process(SHA512_CTX *ctx)
{
int t;
uint64_t temp1;
uint64_t temp2;
// Initialize the 8 working registers
uint64_t a = ctx->h_dig.h[0];
uint64_t b = ctx->h_dig.h[1];
uint64_t c = ctx->h_dig.h[2];
uint64_t d = ctx->h_dig.h[3];
uint64_t e = ctx->h_dig.h[4];
uint64_t f = ctx->h_dig.h[5];
uint64_t g = ctx->h_dig.h[6];
uint64_t h = ctx->h_dig.h[7];
// Process message in 16-word blocks
uint64_t *w = ctx->w_buf.w;
// Convert from big-endian byte order to host byte order
for (t = 0; t < 16; t++)
w[t] = be64toh(w[t]);
// Prepare the message schedule
for (t = 16; t < 80; t++)
w[t] = SIGMA4(w[t - 2]) + w[t - 7] + SIGMA3(w[t - 15]) + w[t - 16];
// SHA-512 hash computation
for (t = 0; t < 80; t++)
{
// Calculate T1 and T2
temp1 = h + SIGMA2(e) + CH(e, f, g) + k[t] + w[t];
temp2 = SIGMA1(a) + MAJ(a, b, c);
// Update the working registers
h = g;
g = f;
f = e;
e = d + temp1;
d = c;
c = b;
b = a;
a = temp1 + temp2;
}
// Update the hash value
ctx->h_dig.h[0] += a;
ctx->h_dig.h[1] += b;
ctx->h_dig.h[2] += c;
ctx->h_dig.h[3] += d;
ctx->h_dig.h[4] += e;
ctx->h_dig.h[5] += f;
ctx->h_dig.h[6] += g;
ctx->h_dig.h[7] += h;
}
/**
* Accepts an array of octets as the next portion of the message.
*/
void SHA512_Update(SHA512_CTX *ctx, const uint8_t * msg, int len)
{
// Process the incoming data
while (len > 0)
{
// The buffer can hold at most 128 bytes
size_t n = MIN(len, 128 - ctx->size);
// Copy the data to the buffer
memcpy(ctx->w_buf.buffer + ctx->size, msg, n);
// Update the SHA-512 ctx
ctx->size += n;
ctx->totalSize += n;
// Advance the data pointer
msg = (uint8_t *) msg + n;
// Remaining bytes to process
len -= n;
// Process message in 16-word blocks
if (ctx->size == 128)
{
// Transform the 16-word block
SHA512_Process(ctx);
// Empty the buffer
ctx->size = 0;
}
}
}
/**
* Return the 512-bit message digest into the user's array
*/
void SHA512_Final(uint8_t *digest, SHA512_CTX *ctx)
{
int i;
size_t paddingSize;
uint64_t totalSize;
uint8_t *padding_ram = (uint8_t *)SSL_MALLOC(128);
memcpy(padding_ram, padding, 128);
// Length of the original message (before padding)
totalSize = ctx->totalSize * 8;
// Pad the message so that its length is congruent to 112 modulo 128
paddingSize = (ctx->size < 112) ? (112 - ctx->size) :
(128 + 112 - ctx->size);
// Append padding
SHA512_Update(ctx, padding, paddingSize);
// Append the length of the original message
ctx->w_buf.w[14] = 0;
ctx->w_buf.w[15] = be64toh(totalSize);
// Calculate the message digest
SHA512_Process(ctx);
// Convert from host byte order to big-endian byte order
for (i = 0; i < 8; i++)
ctx->h_dig.h[i] = be64toh(ctx->h_dig.h[i]);
// Copy the resulting digest
if (digest != NULL)
memcpy(digest, ctx->h_dig.digest, SHA512_SIZE);
SSL_FREE(padding_ram);
}

View File

@ -1,462 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* AES implementation - this is a small code version. There are much faster
* versions around but they are much larger in size (i.e. they use large
* submix tables).
*/
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_crypto.h"
/* all commented out in skeleton mode */
#ifndef CONFIG_SSL_SKELETON_MODE
#define rot1(x) (((x) << 24) | ((x) >> 8))
#define rot2(x) (((x) << 16) | ((x) >> 16))
#define rot3(x) (((x) << 8) | ((x) >> 24))
/*
* This cute trick does 4 'mul by two' at once. Stolen from
* Dr B. R. Gladman <brg@gladman.uk.net> but I'm sure the u-(u>>7) is
* a standard graphics trick
* The key to this is that we need to xor with 0x1b if the top bit is set.
* a 1xxx xxxx 0xxx 0xxx First we mask the 7bit,
* b 1000 0000 0000 0000 then we shift right by 7 putting the 7bit in 0bit,
* c 0000 0001 0000 0000 we then subtract (c) from (b)
* d 0111 1111 0000 0000 and now we and with our mask
* e 0001 1011 0000 0000
*/
#define mt 0x80808080
#define ml 0x7f7f7f7f
#define mh 0xfefefefe
#define mm 0x1b1b1b1b
#define mul2(x,t) ((t)=((x)&mt), \
((((x)+(x))&mh)^(((t)-((t)>>7))&mm)))
#define inv_mix_col(x,f2,f4,f8,f9) (\
(f2)=mul2(x,f2), \
(f4)=mul2(f2,f4), \
(f8)=mul2(f4,f8), \
(f9)=(x)^(f8), \
(f8)=((f2)^(f4)^(f8)), \
(f2)^=(f9), \
(f4)^=(f9), \
(f8)^=rot3(f2), \
(f8)^=rot2(f4), \
(f8)^rot1(f9))
/*
* AES S-box
*/
static const uint8_t aes_sbox[256] =
{
0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,
0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76,
0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,
0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0,
0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,
0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15,
0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,
0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75,
0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,
0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84,
0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,
0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF,
0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,
0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8,
0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,
0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2,
0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,
0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73,
0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,
0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB,
0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,
0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79,
0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,
0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08,
0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,
0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A,
0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,
0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E,
0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,
0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF,
0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,
0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16,
};
/*
* AES is-box
*/
static const uint8_t aes_isbox[256] =
{
0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,
0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,
0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,
0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,
0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,
0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,
0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,
0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,
0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,
0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,
0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,
0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,
0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,
0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,
0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,
0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
};
static const unsigned char Rcon[30] =
{
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,
0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f,
0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4,
0xb3,0x7d,0xfa,0xef,0xc5,0x91,
};
/* ----- static functions ----- */
static void AES_encrypt(const AES_CTX *ctx, uint32_t *data);
static void AES_decrypt(const AES_CTX *ctx, uint32_t *data);
/* Perform doubling in Galois Field GF(2^8) using the irreducible polynomial
x^8+x^4+x^3+x+1 */
static unsigned char AES_xtime(uint32_t x)
{
return (x&0x80) ? (x<<1)^0x1b : x<<1;
}
/**
* Set up AES with the key/iv and cipher size.
*/
void AES_set_key(AES_CTX *ctx, const uint8_t *key,
const uint8_t *iv, AES_MODE mode)
{
int i, ii;
uint32_t *W, tmp, tmp2;
unsigned char *ip;
int words;
unsigned char *Rcon_ram = (unsigned char *)SSL_MALLOC(32);
switch (mode)
{
case AES_MODE_128:
i = 10;
words = 4;
break;
case AES_MODE_256:
i = 14;
words = 8;
break;
default: /* fail silently */
return;
}
ctx->rounds = i;
ctx->key_size = words;
W = ctx->ks;
for (i = 0; i < words; i+=2)
{
W[i+0]= ((uint32_t)key[ 0]<<24)|
((uint32_t)key[ 1]<<16)|
((uint32_t)key[ 2]<< 8)|
((uint32_t)key[ 3] );
W[i+1]= ((uint32_t)key[ 4]<<24)|
((uint32_t)key[ 5]<<16)|
((uint32_t)key[ 6]<< 8)|
((uint32_t)key[ 7] );
key += 8;
}
// ip = Rcon;
ip = Rcon_ram;
memcpy(ip, Rcon, 32); // align, copy two byte more
ii = 4 * (ctx->rounds+1);
for (i = words; i<ii; i++)
{
tmp = W[i-1];
if ((i % words) == 0)
{
tmp2 =(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp )&0xff)<< 8;
tmp2|=(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp>> 8)&0xff)<<16;
tmp2|=(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp>>16)&0xff)<<24;
tmp2|=(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp>>24) );
tmp=tmp2^(((unsigned int)*ip)<<24);
ip++;
}
if ((words == 8) && ((i % words) == 4))
{
tmp2 =(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp )&0xff) ;
tmp2|=(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp>> 8)&0xff)<< 8;
tmp2|=(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp>>16)&0xff)<<16;
tmp2|=(uint32_t)system_get_data_of_array_8(aes_sbox, (tmp>>24) )<<24;
tmp=tmp2;
}
W[i]=W[i-words]^tmp;
}
SSL_FREE(Rcon_ram);
/* copy the iv across */
memcpy(ctx->iv, iv, 16);
}
/**
* Change a key for decryption.
*/
void AES_convert_key(AES_CTX *ctx)
{
int i;
uint32_t *k,w,t1,t2,t3,t4;
k = ctx->ks;
k += 4;
for (i= ctx->rounds*4; i > 4; i--)
{
w= *k;
w = inv_mix_col(w,t1,t2,t3,t4);
*k++ =w;
}
}
/**
* Encrypt a byte sequence (with a block size 16) using the AES cipher.
*/
void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
{
int i;
uint32_t tin[4], tout[4], iv[4];
memcpy(iv, ctx->iv, AES_IV_SIZE);
for (i = 0; i < 4; i++)
tout[i] = tls_ntohl(iv[i]);
for (length -= AES_BLOCKSIZE; length >= 0; length -= AES_BLOCKSIZE)
{
uint32_t msg_32[4];
uint32_t out_32[4];
memcpy(msg_32, msg, AES_BLOCKSIZE);
msg += AES_BLOCKSIZE;
for (i = 0; i < 4; i++)
tin[i] = tls_ntohl(msg_32[i])^tout[i];
AES_encrypt(ctx, tin);
for (i = 0; i < 4; i++)
{
tout[i] = tin[i];
out_32[i] = tls_htonl(tout[i]);
}
memcpy(out, out_32, AES_BLOCKSIZE);
out += AES_BLOCKSIZE;
}
for (i = 0; i < 4; i++)
iv[i] = tls_htonl(tout[i]);
memcpy(ctx->iv, iv, AES_IV_SIZE);
}
/**
* Decrypt a byte sequence (with a block size 16) using the AES cipher.
*/
void AES_cbc_decrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
{
int i;
uint32_t tin[4], xor[4], tout[4], data[4], iv[4];
memcpy(iv, ctx->iv, AES_IV_SIZE);
for (i = 0; i < 4; i++)
xor[i] = tls_ntohl(iv[i]);
for (length -= 16; length >= 0; length -= 16)
{
uint32_t msg_32[4];
uint32_t out_32[4];
memcpy(msg_32, msg, AES_BLOCKSIZE);
msg += AES_BLOCKSIZE;
for (i = 0; i < 4; i++)
{
tin[i] = tls_ntohl(msg_32[i]);
data[i] = tin[i];
}
AES_decrypt(ctx, data);
for (i = 0; i < 4; i++)
{
tout[i] = data[i]^xor[i];
xor[i] = tin[i];
out_32[i] = tls_htonl(tout[i]);
}
memcpy(out, out_32, AES_BLOCKSIZE);
out += AES_BLOCKSIZE;
}
for (i = 0; i < 4; i++)
iv[i] = tls_htonl(xor[i]);
memcpy(ctx->iv, iv, AES_IV_SIZE);
}
/**
* Encrypt a single block (16 bytes) of data
*/
static void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
{
/* To make this code smaller, generate the sbox entries on the fly.
* This will have a really heavy effect upon performance.
*/
uint32_t tmp[4];
uint32_t tmp1, old_a0, a0, a1, a2, a3, row;
int curr_rnd;
int rounds = ctx->rounds;
const uint32_t *k = ctx->ks;
/* Pre-round key addition */
for (row = 0; row < 4; row++)
data[row] ^= *(k++);
/* Encrypt one block. */
for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++)
{
/* Perform ByteSub and ShiftRow operations together */
for (row = 0; row < 4; row++)
{
a0 = (uint32_t)system_get_data_of_array_8(aes_sbox, (data[row%4]>>24)&0xFF);
a1 = (uint32_t)system_get_data_of_array_8(aes_sbox, (data[(row+1)%4]>>16)&0xFF);
a2 = (uint32_t)system_get_data_of_array_8(aes_sbox, (data[(row+2)%4]>>8)&0xFF);
a3 = (uint32_t)system_get_data_of_array_8(aes_sbox, (data[(row+3)%4])&0xFF);
/* Perform MixColumn iff not last round */
if (curr_rnd < (rounds - 1))
{
tmp1 = a0 ^ a1 ^ a2 ^ a3;
old_a0 = a0;
a0 ^= tmp1 ^ AES_xtime(a0 ^ a1);
a1 ^= tmp1 ^ AES_xtime(a1 ^ a2);
a2 ^= tmp1 ^ AES_xtime(a2 ^ a3);
a3 ^= tmp1 ^ AES_xtime(a3 ^ old_a0);
}
tmp[row] = ((a0 << 24) | (a1 << 16) | (a2 << 8) | a3);
}
/* KeyAddition - note that it is vital that this loop is separate from
the MixColumn operation, which must be atomic...*/
for (row = 0; row < 4; row++)
data[row] = tmp[row] ^ *(k++);
}
}
/**
* Decrypt a single block (16 bytes) of data
*/
static void AES_decrypt(const AES_CTX *ctx, uint32_t *data)
{
uint32_t tmp[4];
uint32_t xt0,xt1,xt2,xt3,xt4,xt5,xt6;
uint32_t a0, a1, a2, a3, row;
int curr_rnd;
int rounds = ctx->rounds;
const uint32_t *k = ctx->ks + ((rounds+1)*4);
/* pre-round key addition */
for (row=4; row > 0;row--)
data[row-1] ^= *(--k);
/* Decrypt one block */
for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++)
{
/* Perform ByteSub and ShiftRow operations together */
for (row = 4; row > 0; row--)
{
a0 = system_get_data_of_array_8(aes_isbox, (data[(row+3)%4]>>24)&0xFF);
a1 = system_get_data_of_array_8(aes_isbox, (data[(row+2)%4]>>16)&0xFF);
a2 = system_get_data_of_array_8(aes_isbox, (data[(row+1)%4]>>8)&0xFF);
a3 = system_get_data_of_array_8(aes_isbox, (data[row%4])&0xFF);
/* Perform MixColumn iff not last round */
if (curr_rnd<(rounds-1))
{
/* The MDS cofefficients (0x09, 0x0B, 0x0D, 0x0E)
are quite large compared to encryption; this
operation slows decryption down noticeably. */
xt0 = AES_xtime(a0^a1);
xt1 = AES_xtime(a1^a2);
xt2 = AES_xtime(a2^a3);
xt3 = AES_xtime(a3^a0);
xt4 = AES_xtime(xt0^xt1);
xt5 = AES_xtime(xt1^xt2);
xt6 = AES_xtime(xt4^xt5);
xt0 ^= a1^a2^a3^xt4^xt6;
xt1 ^= a0^a2^a3^xt5^xt6;
xt2 ^= a0^a1^a3^xt4^xt6;
xt3 ^= a0^a1^a2^xt5^xt6;
tmp[row-1] = ((xt0<<24)|(xt1<<16)|(xt2<<8)|xt3);
}
else
tmp[row-1] = ((a0<<24)|(a1<<16)|(a2<<8)|a3);
}
for (row = 4; row > 0; row--)
data[row-1] = tmp[row-1] ^ *(--k);
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,417 +0,0 @@
/*
* Copyright (c) 2007-2015, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Some misc. routines to help things out
*/
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_ssl.h"
#include "ssl/ssl_crypto_misc.h"
//#include "lwip/sockets.h"
#include <fcntl.h>
#ifdef CONFIG_WIN32_USE_CRYPTO_LIB
#include "wincrypt.h"
#endif
#ifndef WIN32
//static int rng_fd = -1;
#elif defined(CONFIG_WIN32_USE_CRYPTO_LIB)
static HCRYPTPROV gCryptProv;
#endif
#if (!defined(CONFIG_USE_DEV_URANDOM) && !defined(CONFIG_WIN32_USE_CRYPTO_LIB))
/* change to processor registers as appropriate */
#define ENTROPY_POOL_SIZE 32
#define ENTROPY_COUNTER1 ((((uint64_t)tv.tv_sec)<<32) | tv.tv_usec)
#define ENTROPY_COUNTER2 rand()
static uint8_t entropy_pool[ENTROPY_POOL_SIZE];
#endif
const char unsupported_str[] = "Error: Feature not supported\n";
#ifndef CONFIG_SSL_SKELETON_MODE
/**
* Retrieve a file and put it into memory
* @return The size of the file, or -1 on failure.
*/
int get_file(const char *filename, uint8_t **buf)
{
#ifdef FILE
int total_bytes = 0;
int bytes_read = 0;
int filesize;
FILE *stream = fopen(filename, "rb");
if (stream == NULL)
{
#ifdef CONFIG_SSL_FULL_MODE
printf("file '%s' does not exist\n", filename); //TTY_FLUSH();
#endif
return -1;
}
/* Win CE doesn't support stat() */
fseek(stream, 0, SEEK_END);
filesize = ftell(stream);
*buf = (uint8_t *)SSL_MALLOC(filesize);
fseek(stream, 0, SEEK_SET);
do
{
bytes_read = fread(*buf+total_bytes, 1, filesize-total_bytes, stream);
total_bytes += bytes_read;
} while (total_bytes < filesize && bytes_read > 0);
fclose(stream);
return filesize;
#else
int total_bytes = 0;
int bytes_read = 0;
int filesize;
int stream = -1;
struct stat stream_stat;
stream = open(filename, 0x18);
if (stream < 0) {
#ifdef CONFIG_SSL_FULL_MODE
printf("file '%s' does not exist\n", filename);
#endif
return -1;
}
filesize = fstat(stream, &stream_stat);
if (filesize < 0) {
close(stream);
return filesize;
}
if (stream_stat.st_size == 0) {
close(stream);
return 0;
}
filesize = stream_stat.st_size;
*buf = (uint8_t *) SSL_ZALLOC(filesize);
do {
bytes_read = read(stream, *buf + total_bytes, filesize - total_bytes);
total_bytes += bytes_read;
} while (total_bytes < filesize && bytes_read > 0);
close(stream);
return filesize;
#endif
}
#endif
/**
* Initialise the Random Number Generator engine.
* - On Win32 use the platform SDK's crypto engine.
* - On Linux use /dev/urandom
* - If none of these work then use a custom RNG.
*/
EXP_FUNC void STDCALL RNG_initialize()
{
#if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM)
// rng_fd = ax_open("/dev/urandom", O_RDONLY);
#elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB)
if (!CryptAcquireContext(&gCryptProv,
NULL, NULL, PROV_RSA_FULL, 0))
{
if (GetLastError() == NTE_BAD_KEYSET &&
!CryptAcquireContext(&gCryptProv,
NULL,
NULL,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
printf("CryptoLib: %x\n", unsupported_str, GetLastError());
exit(1);
}
}
#else
/* start of with a stack to copy across */
int i;
memcpy(entropy_pool, &i, ENTROPY_POOL_SIZE);
srand((unsigned int)&i);
#endif
}
/**
* If no /dev/urandom, then initialise the RNG with something interesting.
*/
EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size)
{
#if defined(WIN32) || defined(CONFIG_WIN32_USE_CRYPTO_LIB)
int i;
for (i = 0; i < ENTROPY_POOL_SIZE && i < size; i++)
entropy_pool[i] ^= seed_buf[i];
#endif
}
/**
* Terminate the RNG engine.
*/
EXP_FUNC void STDCALL RNG_terminate(void)
{
#ifndef WIN32
// close(rng_fd);
#elif defined(CONFIG_WIN32_USE_CRYPTO_LIB)
CryptReleaseContext(gCryptProv, 0);
#endif
}
/**
* Set a series of bytes with a random number. Individual bytes can be 0
*/
EXP_FUNC int STDCALL get_random(int num_rand_bytes, uint8_t *rand_data)
{
#if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM)
// /* use the Linux default */
// read(rng_fd, rand_data, num_rand_bytes); /* read from /dev/urandom */
os_get_random(rand_data, num_rand_bytes);
#elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB)
/* use Microsoft Crypto Libraries */
CryptGenRandom(gCryptProv, num_rand_bytes, rand_data);
#else /* nothing else to use, so use a custom RNG */
/* The method we use when we've got nothing better. Use RC4, time
and a couple of random seeds to generate a random sequence */
RC4_CTX rng_ctx;
struct timeval tv;
MD5_CTX rng_digest_ctx;
uint8_t digest[MD5_SIZE];
uint64_t *ep;
int i;
/* A proper implementation would use counters etc for entropy */
// gettimeofday(&tv, NULL);
ep = (uint64_t *)entropy_pool;
ep[0] ^= ENTROPY_COUNTER1;
ep[1] ^= ENTROPY_COUNTER2;
/* use a digested version of the entropy pool as a key */
MD5_Init(&rng_digest_ctx);
MD5_Update(&rng_digest_ctx, entropy_pool, ENTROPY_POOL_SIZE);
MD5_Final(digest, &rng_digest_ctx);
/* come up with the random sequence */
RC4_setup(&rng_ctx, digest, MD5_SIZE); /* use as a key */
memcpy(rand_data, entropy_pool, num_rand_bytes < ENTROPY_POOL_SIZE ?
num_rand_bytes : ENTROPY_POOL_SIZE);
RC4_crypt(&rng_ctx, rand_data, rand_data, num_rand_bytes);
/* move things along */
for (i = ENTROPY_POOL_SIZE-1; i >= MD5_SIZE ; i--)
entropy_pool[i] = entropy_pool[i-MD5_SIZE];
/* insert the digest at the start of the entropy pool */
memcpy(entropy_pool, digest, MD5_SIZE);
#endif
return 0;
}
/**
* Set a series of bytes with a random number. Individual bytes are not zero.
*/
int get_random_NZ(int num_rand_bytes, uint8_t *rand_data)
{
int i;
if (get_random(num_rand_bytes, rand_data))
return -1;
for (i = 0; i < num_rand_bytes; i++)
{
while (rand_data[i] == 0) /* can't be 0 */
rand_data[i] = (uint8_t)(esp_random());
}
return 0;
}
/**
* Some useful diagnostic routines
*/
#if defined(CONFIG_SSL_FULL_MODE) || defined(CONFIG_DEBUG)
int hex_finish;
int hex_index;
#if 0
static void print_hex_init(int finish)
{
hex_finish = finish;
hex_index = 0;
}
static void print_hex(uint8_t hex)
{
static int column;
if (hex_index == 0)
{
column = 0;
}
ssl_printf("%02x ", hex);
if (++column == 8)
{
ssl_printf(": ");
}
else if (column >= 16)
{
ssl_printf("\n");
column = 0;
}
if (++hex_index >= hex_finish && column > 0)
{
ssl_printf("\n");
}
}
#endif
/**
* Spit out a blob of data for diagnostics. The data is is a nice column format
* for easy reading.
*
* @param format [in] The string (with possible embedded format characters)
* @param size [in] The number of numbers to print
* @param data [in] The start of data to use
* @param ... [in] Any additional arguments
*/
EXP_FUNC void STDCALL print_blob(const char *format,
const uint8_t *data, int size, ...)
{
// int i;
// char tmp[80];
// va_list(ap);
// va_start(ap, size);
// sprintf(tmp, "%s\n", format);
// vprintf(tmp, ap);
// print_hex_init(size);
// for (i = 0; i < size; i++)
// {
// print_hex(data[i]);
// }
// va_end(ap);
// TTY_FLUSH();
}
#elif defined(WIN32)
/* VC6.0 doesn't handle variadic macros */
EXP_FUNC void STDCALL print_blob(const char *format, const unsigned char *data,
int size, ...) {}
#endif
#if defined(CONFIG_SSL_HAS_PEM) || defined(CONFIG_HTTP_HAS_AUTHORIZATION)
/* base64 to binary lookup table */
static const uint8_t map[128] =
{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 255, 255, 255, 255, 255
};
EXP_FUNC int STDCALL base64_decode(const char *in, int len,
uint8_t *out, int *outlen)
{
int g, t, x, y, z;
uint8_t c;
int ret = -1;
uint8_t* base64_map = (uint8_t*)SSL_ZALLOC(128);
memcpy(base64_map, map, 128);
g = 3;
for (x = y = z = t = 0; x < len; x++)
{
if ((c = base64_map[in[x]&0x7F]) == 0xff)
continue;
if (c == 254) /* this is the end... */
{
c = 0;
if (--g < 0)
goto error;
}
else if (g != 3) /* only allow = at end */
goto error;
t = (t<<6) | c;
if (++y == 4)
{
out[z++] = (uint8_t)((t>>16)&255);
if (g > 1)
out[z++] = (uint8_t)((t>>8)&255);
if (g > 2)
out[z++] = (uint8_t)(t&255);
y = t = 0;
}
/* check that we don't go past the output buffer */
if (z > *outlen)
goto error;
}
if (y != 0)
goto error;
*outlen = z;
ret = 0;
error:
#ifdef CONFIG_SSL_FULL_MODE
if (ret < 0) {
ssl_printf("Error: Invalid base64\n"); //TTY_FLUSH();
}
#endif
//TTY_FLUSH();
SSL_FREE(base64_map);
return ret;
}
#endif

View File

@ -1,109 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* HMAC implementation - This code was originally taken from RFC2104
* See http://www.ietf.org/rfc/rfc2104.txt and
* http://www.faqs.org/rfcs/rfc2202.html
*/
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_crypto.h"
/**
* Perform HMAC-MD5
* NOTE: does not handle keys larger than the block size.
*/
void ssl_hmac_md5(const uint8_t *msg, int length, const uint8_t *key,
int key_len, uint8_t *digest)
{
MD5_CTX context;
uint8_t *k_ipad = (uint8_t *)SSL_ZALLOC(64);
uint8_t *k_opad = (uint8_t *)SSL_ZALLOC(64);
int i;
// memset(k_ipad, 0, sizeof k_ipad);
// memset(k_opad, 0, sizeof k_opad);
memcpy(k_ipad, key, key_len);
memcpy(k_opad, key, key_len);
for (i = 0; i < 64; i++)
{
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
MD5_Init(&context);
MD5_Update(&context, k_ipad, 64);
MD5_Update(&context, msg, length);
MD5_Final(digest, &context);
MD5_Init(&context);
MD5_Update(&context, k_opad, 64);
MD5_Update(&context, digest, MD5_SIZE);
MD5_Final(digest, &context);
SSL_FREE(k_ipad);
SSL_FREE(k_opad);
}
/**
* Perform HMAC-SHA1
* NOTE: does not handle keys larger than the block size.
*/
void ssl_hmac_sha1(const uint8_t *msg, int length, const uint8_t *key,
int key_len, uint8_t *digest)
{
SHA1_CTX context;
uint8_t *k_ipad = (uint8_t *)SSL_ZALLOC(64);
uint8_t *k_opad = (uint8_t *)SSL_ZALLOC(64);
int i;
// memset(k_ipad, 0, sizeof k_ipad);
// memset(k_opad, 0, sizeof k_opad);
memcpy(k_ipad, key, key_len);
memcpy(k_opad, key, key_len);
for (i = 0; i < 64; i++)
{
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
SHA1_Init(&context);
SHA1_Update(&context, k_ipad, 64);
SHA1_Update(&context, msg, length);
SHA1_Final(digest, &context);
SHA1_Init(&context);
SHA1_Update(&context, k_opad, 64);
SHA1_Update(&context, digest, SHA1_SIZE);
SHA1_Final(digest, &context);
SSL_FREE(k_ipad);
SSL_FREE(k_opad);
}

View File

@ -1,293 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* This file implements the MD5 algorithm as defined in RFC1321
*/
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_crypto.h"
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
/* ----- static functions ----- */
static void MD5Transform(uint32_t state[4], const uint8_t block[64]);
static void Encode(uint8_t *output, uint32_t *input, uint32_t len);
static void Decode(uint32_t *output, const uint8_t *input, uint32_t len);
static const uint8_t PADDING[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits. */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation. */
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/**
* MD5 initialization - begins an MD5 operation, writing a new ctx.
*/
EXP_FUNC void STDCALL MD5_Init(MD5_CTX *ctx)
{
ctx->count[0] = ctx->count[1] = 0;
/* Load magic initialization constants.
*/
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xefcdab89;
ctx->state[2] = 0x98badcfe;
ctx->state[3] = 0x10325476;
}
/**
* Accepts an array of octets as the next portion of the message.
*/
EXP_FUNC void STDCALL MD5_Update(MD5_CTX *ctx, const uint8_t * msg, int len)
{
uint32_t x;
int i, partLen;
/* Compute number of bytes mod 64 */
x = (uint32_t)((ctx->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((ctx->count[0] += ((uint32_t)len << 3)) < ((uint32_t)len << 3))
ctx->count[1]++;
ctx->count[1] += ((uint32_t)len >> 29);
partLen = 64 - x;
/* Transform as many times as possible. */
if (len >= partLen)
{
memcpy(&ctx->buffer[x], msg, partLen);
MD5Transform(ctx->state, ctx->buffer);
for (i = partLen; i + 63 < len; i += 64)
MD5Transform(ctx->state, &msg[i]);
x = 0;
}
else
i = 0;
/* Buffer remaining input */
memcpy(&ctx->buffer[x], &msg[i], len-i);
}
/**
* Return the 128-bit message digest into the user's array
*/
EXP_FUNC void STDCALL MD5_Final(uint8_t *digest, MD5_CTX *ctx)
{
uint8_t bits[8];
uint32_t x, padLen;
/* Save number of bits */
Encode(bits, ctx->count, 8);
/* Pad out to 56 mod 64.
*/
x = (uint32_t)((ctx->count[0] >> 3) & 0x3f);
padLen = (x < 56) ? (56 - x) : (120 - x);
MD5_Update(ctx, PADDING, padLen);
/* Append length (before padding) */
MD5_Update(ctx, bits, 8);
/* Store state in digest */
Encode(digest, ctx->state, MD5_SIZE);
}
/**
* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform(uint32_t state[4], const uint8_t block[64])
{
uint32_t a = state[0], b = state[1], c = state[2],
d = state[3], x[MD5_SIZE];
Decode(x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}
/**
* Encodes input (uint32_t) into output (uint8_t). Assumes len is
* a multiple of 4.
*/
static void Encode(uint8_t *output, uint32_t *input, uint32_t len)
{
uint32_t i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
{
output[j] = (uint8_t)(input[i] & 0xff);
output[j+1] = (uint8_t)((input[i] >> 8) & 0xff);
output[j+2] = (uint8_t)((input[i] >> 16) & 0xff);
output[j+3] = (uint8_t)((input[i] >> 24) & 0xff);
}
}
/**
* Decodes input (uint8_t) into output (uint32_t). Assumes len is
* a multiple of 4.
*/
static void Decode(uint32_t *output, const uint8_t *input, uint32_t len)
{
uint32_t i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
(((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
}

View File

@ -1,91 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* An implementation of the RC4/ARC4 algorithm.
* Originally written by Christophe Devine.
*/
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_crypto.h"
/**
* Get ready for an encrypt/decrypt operation
*/
void RC4_setup(RC4_CTX *ctx, const uint8_t *key, int length)
{
int i, j = 0, k = 0, a;
uint8_t *m;
ctx->x = 0;
ctx->y = 0;
m = ctx->m;
for (i = 0; i < 256; i++)
m[i] = i;
for (i = 0; i < 256; i++)
{
a = m[i];
j = (uint8_t)(j + a + key[k]);
m[i] = m[j];
m[j] = a;
if (++k >= length)
k = 0;
}
}
/**
* Perform the encrypt/decrypt operation (can use it for either since
* this is a stream cipher).
* NOTE: *msg and *out must be the same pointer (performance tweak)
*/
void RC4_crypt(RC4_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
{
int i;
uint8_t *m, x, y, a, b;
x = ctx->x;
y = ctx->y;
m = ctx->m;
for (i = 0; i < length; i++)
{
a = m[++x];
y += a;
m[x] = b = m[y];
m[y] = a;
out[i] ^= m[(uint8_t)(a + b)];
}
ctx->x = x;
ctx->y = y;
}

View File

@ -1,284 +0,0 @@
/*
* Copyright (c) 2007-2014, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Implements the RSA public encryption algorithm. Uses the bigint library to
* perform its calculations.
*/
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_crypto.h"
void RSA_priv_key_new(RSA_CTX **ctx,
const uint8_t *modulus, int mod_len,
const uint8_t *pub_exp, int pub_len,
const uint8_t *priv_exp, int priv_len
#if CONFIG_BIGINT_CRT
, const uint8_t *p, int p_len,
const uint8_t *q, int q_len,
const uint8_t *dP, int dP_len,
const uint8_t *dQ, int dQ_len,
const uint8_t *qInv, int qInv_len
#endif
)
{
RSA_CTX *rsa_ctx;
BI_CTX *bi_ctx;
RSA_pub_key_new(ctx, modulus, mod_len, pub_exp, pub_len);
rsa_ctx = *ctx;
bi_ctx = rsa_ctx->bi_ctx;
rsa_ctx->d = bi_import(bi_ctx, priv_exp, priv_len);
bi_permanent(rsa_ctx->d);
#ifdef CONFIG_BIGINT_CRT
rsa_ctx->p = bi_import(bi_ctx, p, p_len);
rsa_ctx->q = bi_import(bi_ctx, q, q_len);
rsa_ctx->dP = bi_import(bi_ctx, dP, dP_len);
rsa_ctx->dQ = bi_import(bi_ctx, dQ, dQ_len);
rsa_ctx->qInv = bi_import(bi_ctx, qInv, qInv_len);
bi_permanent(rsa_ctx->dP);
bi_permanent(rsa_ctx->dQ);
bi_permanent(rsa_ctx->qInv);
bi_set_mod(bi_ctx, rsa_ctx->p, BIGINT_P_OFFSET);
bi_set_mod(bi_ctx, rsa_ctx->q, BIGINT_Q_OFFSET);
#endif
}
void RSA_pub_key_new(RSA_CTX **ctx,
const uint8_t *modulus, int mod_len,
const uint8_t *pub_exp, int pub_len)
{
RSA_CTX *rsa_ctx;
BI_CTX *bi_ctx;
if (*ctx) /* if we load multiple certs, dump the old one */
RSA_free(*ctx);
bi_ctx = bi_initialize();
*ctx = (RSA_CTX *)SSL_ZALLOC(sizeof(RSA_CTX));
rsa_ctx = *ctx;
rsa_ctx->bi_ctx = bi_ctx;
rsa_ctx->num_octets = mod_len;
rsa_ctx->m = bi_import(bi_ctx, modulus, mod_len);
bi_set_mod(bi_ctx, rsa_ctx->m, BIGINT_M_OFFSET);
rsa_ctx->e = bi_import(bi_ctx, pub_exp, pub_len);
bi_permanent(rsa_ctx->e);
}
/**
* Free up any RSA context resources.
*/
void RSA_free(RSA_CTX *rsa_ctx)
{
BI_CTX *bi_ctx;
if (rsa_ctx == NULL) /* deal with ptrs that are null */
return;
bi_ctx = rsa_ctx->bi_ctx;
bi_depermanent(rsa_ctx->e);
bi_free(bi_ctx, rsa_ctx->e);
bi_free_mod(rsa_ctx->bi_ctx, BIGINT_M_OFFSET);
if (rsa_ctx->d)
{
bi_depermanent(rsa_ctx->d);
bi_free(bi_ctx, rsa_ctx->d);
#ifdef CONFIG_BIGINT_CRT
bi_depermanent(rsa_ctx->dP);
bi_depermanent(rsa_ctx->dQ);
bi_depermanent(rsa_ctx->qInv);
bi_free(bi_ctx, rsa_ctx->dP);
bi_free(bi_ctx, rsa_ctx->dQ);
bi_free(bi_ctx, rsa_ctx->qInv);
bi_free_mod(rsa_ctx->bi_ctx, BIGINT_P_OFFSET);
bi_free_mod(rsa_ctx->bi_ctx, BIGINT_Q_OFFSET);
#endif
}
bi_terminate(bi_ctx);
SSL_FREE(rsa_ctx);
}
/**
* @brief Use PKCS1.5 for decryption/verification.
* @param ctx [in] The context
* @param in_data [in] The data to decrypt (must be < modulus size-11)
* @param out_data [out] The decrypted data.
* @param out_len [int] The size of the decrypted buffer in bytes
* @param is_decryption [in] Decryption or verify operation.
* @return The number of bytes that were originally encrypted. -1 on error.
* @see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
*/
int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data,
uint8_t *out_data, int out_len, int is_decryption)
{
const int byte_size = ctx->num_octets;
int i = 0, size;
bigint *decrypted_bi, *dat_bi;
uint8_t *block = (uint8_t *)SSL_MALLOC(byte_size);
int pad_count = 0;
if (out_len < byte_size) /* check output has enough size */
return -1;
memset(out_data, 0, out_len); /* initialise */
/* decrypt */
dat_bi = bi_import(ctx->bi_ctx, in_data, byte_size);
#ifdef CONFIG_SSL_CERT_VERIFICATION
decrypted_bi = is_decryption ? /* decrypt or verify? */
RSA_private(ctx, dat_bi) : RSA_public(ctx, dat_bi);
#else /* always a decryption */
decrypted_bi = RSA_private(ctx, dat_bi);
#endif
/* convert to a normal block */
bi_export(ctx->bi_ctx, decrypted_bi, block, byte_size);
if (block[i++] != 0) /* leading 0? */
return -1;
#ifdef CONFIG_SSL_CERT_VERIFICATION
if (is_decryption == 0) /* PKCS1.5 signing pads with "0xff"s */
{
if (block[i++] != 0x01) /* BT correct? */
return -1;
while (block[i++] == 0xff && i < byte_size)
pad_count++;
}
else /* PKCS1.5 encryption padding is random */
#endif
{
if (block[i++] != 0x02) /* BT correct? */
return -1;
while (block[i++] && i < byte_size)
pad_count++;
}
/* check separator byte 0x00 - and padding must be 8 or more bytes */
if (i == byte_size || pad_count < 8)
return -1;
size = byte_size - i;
/* get only the bit we want */
if (size > 0)
memcpy(out_data, &block[i], size);
SSL_FREE(block);
return size ? size : -1;
}
/**
* Performs m = c^d mod n
*/
bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg)
{
#ifdef CONFIG_BIGINT_CRT
return bi_crt(c->bi_ctx, bi_msg, c->dP, c->dQ, c->p, c->q, c->qInv);
#else
BI_CTX *ctx = c->bi_ctx;
ctx->mod_offset = BIGINT_M_OFFSET;
return bi_mod_power(ctx, bi_msg, c->d);
#endif
}
#ifdef CONFIG_SSL_FULL_MODE
#if 0
/**
* Used for diagnostics.
*/
void RSA_print(const RSA_CTX *rsa_ctx)
{
if (rsa_ctx == NULL)
return;
ssl_printf("----------------- RSA DEBUG ----------------\n");
ssl_printf("Size:\t%d\n", rsa_ctx->num_octets);
bi_print("Modulus", rsa_ctx->m);
bi_print("Public Key", rsa_ctx->e);
bi_print("Private Key", rsa_ctx->d);
}
#endif
#endif
#if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT)
/**
* Performs c = m^e mod n
*/
bigint *RSA_public(const RSA_CTX * c, bigint *bi_msg)
{
c->bi_ctx->mod_offset = BIGINT_M_OFFSET;
return bi_mod_power(c->bi_ctx, bi_msg, c->e);
}
/**
* Use PKCS1.5 for encryption/signing.
* see http://www.rsasecurity.com/rsalabs/node.asp?id=2125
*/
int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
uint8_t *out_data, int is_signing)
{
int byte_size = ctx->num_octets;
int num_pads_needed = byte_size-in_len-3;
bigint *dat_bi, *encrypt_bi;
/* note: in_len+11 must be > byte_size */
out_data[0] = 0; /* ensure encryption block is < modulus */
if (is_signing)
{
out_data[1] = 1; /* PKCS1.5 signing pads with "0xff"'s */
memset(&out_data[2], 0xff, num_pads_needed);
}
else /* randomize the encryption padding with non-zero bytes */
{
out_data[1] = 2;
if (get_random_NZ(num_pads_needed, &out_data[2]) < 0)
return -1;
}
out_data[2+num_pads_needed] = 0;
memcpy(&out_data[3+num_pads_needed], in_data, in_len);
/* now encrypt it */
dat_bi = bi_import(ctx->bi_ctx, out_data, byte_size);
encrypt_bi = is_signing ? RSA_private(ctx, dat_bi) :
RSA_public(ctx, dat_bi);
bi_export(ctx->bi_ctx, encrypt_bi, out_data, byte_size);
/* save a few bytes of memory */
bi_clear_cache(ctx->bi_ctx);
return byte_size;
}
#endif /* CONFIG_SSL_CERT_VERIFICATION */

View File

@ -1,248 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* SHA1 implementation - as defined in FIPS PUB 180-1 published April 17, 1995.
* This code was originally taken from RFC3174
*/
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_crypto.h"
/*
* Define the SHA1 circular left shift macro
*/
#define SHA1CircularShift(bits,word) \
(((word) << (bits)) | ((word) >> (32-(bits))))
/* ----- static functions ----- */
static void SHA1PadMessage(SHA1_CTX *ctx);
static void SHA1ProcessMessageBlock(SHA1_CTX *ctx);
/**
* Initialize the SHA1 context
*/
void SHA1_Init(SHA1_CTX *ctx)
{
ctx->Length_Low = 0;
ctx->Length_High = 0;
ctx->Message_Block_Index = 0;
ctx->Intermediate_Hash[0] = 0x67452301;
ctx->Intermediate_Hash[1] = 0xEFCDAB89;
ctx->Intermediate_Hash[2] = 0x98BADCFE;
ctx->Intermediate_Hash[3] = 0x10325476;
ctx->Intermediate_Hash[4] = 0xC3D2E1F0;
}
/**
* Accepts an array of octets as the next portion of the message.
*/
void SHA1_Update(SHA1_CTX *ctx, const uint8_t *msg, int len)
{
while (len--)
{
ctx->Message_Block[ctx->Message_Block_Index++] = (*msg & 0xFF);
ctx->Length_Low += 8;
if (ctx->Length_Low == 0)
ctx->Length_High++;
if (ctx->Message_Block_Index == 64)
SHA1ProcessMessageBlock(ctx);
msg++;
}
}
/**
* Return the 160-bit message digest into the user's array
*/
void SHA1_Final(uint8_t *digest, SHA1_CTX *ctx)
{
int i;
SHA1PadMessage(ctx);
memset(ctx->Message_Block, 0, 64);
ctx->Length_Low = 0; /* and clear length */
ctx->Length_High = 0;
for (i = 0; i < SHA1_SIZE; i++)
{
digest[i] = ctx->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) );
}
}
/**
* Process the next 512 bits of the message stored in the array.
*/
static void SHA1ProcessMessageBlock(SHA1_CTX *ctx)
{
const uint32_t K[] = { /* Constants defined in SHA-1 */
0x5A827999,
0x6ED9EBA1,
0x8F1BBCDC,
0xCA62C1D6
};
int t; /* Loop counter */
uint32_t temp; /* Temporary word value */
uint32_t W[80]; /* Word sequence */
uint32_t A, B, C, D, E; /* Word buffers */
/*
* Initialize the first 16 words in the array W
*/
for (t = 0; t < 16; t++)
{
W[t] = ctx->Message_Block[t * 4] << 24;
W[t] |= ctx->Message_Block[t * 4 + 1] << 16;
W[t] |= ctx->Message_Block[t * 4 + 2] << 8;
W[t] |= ctx->Message_Block[t * 4 + 3];
}
for (t = 16; t < 80; t++)
{
W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
}
A = ctx->Intermediate_Hash[0];
B = ctx->Intermediate_Hash[1];
C = ctx->Intermediate_Hash[2];
D = ctx->Intermediate_Hash[3];
E = ctx->Intermediate_Hash[4];
for (t = 0; t < 20; t++)
{
temp = SHA1CircularShift(5,A) +
((B & C) | ((~B) & D)) + E + W[t] + K[0];
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}
for (t = 20; t < 40; t++)
{
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}
for (t = 40; t < 60; t++)
{
temp = SHA1CircularShift(5,A) +
((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}
for (t = 60; t < 80; t++)
{
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}
ctx->Intermediate_Hash[0] += A;
ctx->Intermediate_Hash[1] += B;
ctx->Intermediate_Hash[2] += C;
ctx->Intermediate_Hash[3] += D;
ctx->Intermediate_Hash[4] += E;
ctx->Message_Block_Index = 0;
}
/*
* According to the standard, the message must be padded to an even
* 512 bits. The first padding bit must be a '1'. The last 64
* bits represent the length of the original message. All bits in
* between should be 0. This function will pad the message
* according to those rules by filling the Message_Block array
* accordingly. It will also call the ProcessMessageBlock function
* provided appropriately. When it returns, it can be assumed that
* the message digest has been computed.
*
* @param ctx [in, out] The SHA1 context
*/
static void SHA1PadMessage(SHA1_CTX *ctx)
{
/*
* Check to see if the current message block is too small to hold
* the initial padding bits and length. If so, we will pad the
* block, process it, and then continue padding into a second
* block.
*/
if (ctx->Message_Block_Index > 55)
{
ctx->Message_Block[ctx->Message_Block_Index++] = 0x80;
while(ctx->Message_Block_Index < 64)
{
ctx->Message_Block[ctx->Message_Block_Index++] = 0;
}
SHA1ProcessMessageBlock(ctx);
while (ctx->Message_Block_Index < 56)
{
ctx->Message_Block[ctx->Message_Block_Index++] = 0;
}
}
else
{
ctx->Message_Block[ctx->Message_Block_Index++] = 0x80;
while(ctx->Message_Block_Index < 56)
{
ctx->Message_Block[ctx->Message_Block_Index++] = 0;
}
}
/*
* Store the message length as the last 8 octets
*/
ctx->Message_Block[56] = ctx->Length_High >> 24;
ctx->Message_Block[57] = ctx->Length_High >> 16;
ctx->Message_Block[58] = ctx->Length_High >> 8;
ctx->Message_Block[59] = ctx->Length_High;
ctx->Message_Block[60] = ctx->Length_Low >> 24;
ctx->Message_Block[61] = ctx->Length_Low >> 16;
ctx->Message_Block[62] = ctx->Length_Low >> 8;
ctx->Message_Block[63] = ctx->Length_Low;
SHA1ProcessMessageBlock(ctx);
}

View File

@ -1,696 +0,0 @@
/*
* Copyright (c) 2007-2015, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Some primitive asn methods for extraction ASN.1 data.
*/
#include <stdint.h>
#include <string.h>
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_ssl.h"
#include "ssl/ssl_crypto.h"
#include "ssl/ssl_crypto_misc.h"
struct tm
{
int tm_sec; /* Seconds. [0-60] (1 leap second) */
int tm_min; /* Minutes. [0-59] */
int tm_hour; /* Hours. [0-23] */
int tm_mday; /* Day. [1-31] */
int tm_mon; /* Month. [0-11] */
int tm_year; /* Year - 1900. */
int tm_wday; /* Day of week. [0-6] */
int tm_yday; /* Days in year.[0-365] */
int tm_isdst; /* DST. [-1/0/1]*/
#ifdef __USE_BSD
long int tm_gmtoff; /* Seconds east of UTC. */
__const char *tm_zone; /* Timezone abbreviation. */
#else
long int __tm_gmtoff; /* Seconds east of UTC. */
__const char *__tm_zone; /* Timezone abbreviation. */
#endif
};
/*1.2.840.113549.1.1 OID prefix - handle the following */
/* md5WithRSAEncryption(4) */
/* sha1WithRSAEncryption(5) */
/* sha256WithRSAEncryption (11) */
/* sha384WithRSAEncryption (12) */
/* sha512WithRSAEncryption (13) */
static const uint8_t sig_oid_prefix[] =
{
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01
};
/* 1.3.14.3.2.29 SHA1 with RSA signature */
static const uint8_t sig_sha1WithRSAEncrypt[] =
{
0x2b, 0x0e, 0x03, 0x02, 0x1d
};
/* 2.16.840.1.101.3.4.2.1 SHA-256 */
static const uint8_t sig_sha256[] =
{
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01
};
/* 2.16.840.1.101.3.4.2.2 SHA-384 */
static const uint8_t sig_sha384[] =
{
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02
};
/* 2.16.840.1.101.3.4.2.3 SHA-512 */
static const uint8_t sig_sha512[] =
{
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03
};
static const uint8_t sig_subject_alt_name[] =
{
0x55, 0x1d, 0x11
};
/* CN, O, OU */
static const uint8_t g_dn_types[] = { 3, 10, 11 };
uint32_t get_asn1_length(const uint8_t *buf, int *offset)
{
int i;
uint32_t len;
if (!(buf[*offset] & 0x80)) /* short form */
{
len = buf[(*offset)++];
}
else /* long form */
{
int length_bytes = buf[(*offset)++]&0x7f;
if (length_bytes > 4) /* limit number of bytes */
return 0;
len = 0;
for (i = 0; i < length_bytes; i++)
{
len <<= 8;
len += buf[(*offset)++];
}
}
return len;
}
/**
* Skip the ASN1.1 object type and its length. Get ready to read the object's
* data.
*/
int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type)
{
if (buf[*offset] != obj_type)
return X509_NOT_OK;
(*offset)++;
return get_asn1_length(buf, offset);
}
/**
* Skip over an ASN.1 object type completely. Get ready to read the next
* object.
*/
int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type)
{
int len;
if (buf[*offset] != obj_type)
return X509_NOT_OK;
(*offset)++;
len = get_asn1_length(buf, offset);
*offset += len;
return 0;
}
/**
* Read an integer value for ASN.1 data
* Note: This function allocates memory which must be freed by the user.
*/
int asn1_get_int(const uint8_t *buf, int *offset, uint8_t **object)
{
int len;
if ((len = asn1_next_obj(buf, offset, ASN1_INTEGER)) < 0)
goto end_int_array;
if (len > 1 && buf[*offset] == 0x00) /* ignore the negative byte */
{
len--;
(*offset)++;
}
*object = (uint8_t *)SSL_MALLOC(len);
memcpy(*object, &buf[*offset], len);
*offset += len;
end_int_array:
return len;
}
/**
* Get all the RSA private key specifics from an ASN.1 encoded file
*/
int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx)
{
int offset = 7;
uint8_t *modulus = NULL, *priv_exp = NULL, *pub_exp = NULL;
int mod_len, priv_len, pub_len;
#ifdef CONFIG_BIGINT_CRT
uint8_t *p = NULL, *q = NULL, *dP = NULL, *dQ = NULL, *qInv = NULL;
int p_len, q_len, dP_len, dQ_len, qInv_len;
#endif
/* not in der format */
if (buf[0] != ASN1_SEQUENCE) /* basic sanity check */
{
#ifdef CONFIG_SSL_FULL_MODE
ssl_printf("Error: This is not a valid ASN.1 file\n");
#endif
return X509_INVALID_PRIV_KEY;
}
/* Use the private key to mix up the RNG if possible. */
RNG_custom_init(buf, len);
mod_len = asn1_get_int(buf, &offset, &modulus);
pub_len = asn1_get_int(buf, &offset, &pub_exp);
priv_len = asn1_get_int(buf, &offset, &priv_exp);
if (mod_len <= 0 || pub_len <= 0 || priv_len <= 0)
return X509_INVALID_PRIV_KEY;
#ifdef CONFIG_BIGINT_CRT
p_len = asn1_get_int(buf, &offset, &p);
q_len = asn1_get_int(buf, &offset, &q);
dP_len = asn1_get_int(buf, &offset, &dP);
dQ_len = asn1_get_int(buf, &offset, &dQ);
qInv_len = asn1_get_int(buf, &offset, &qInv);
if (p_len <= 0 || q_len <= 0 || dP_len <= 0 || dQ_len <= 0 || qInv_len <= 0)
return X509_INVALID_PRIV_KEY;
RSA_priv_key_new(rsa_ctx,
modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len,
p, p_len, q, p_len, dP, dP_len, dQ, dQ_len, qInv, qInv_len);
SSL_FREE(p);
SSL_FREE(q);
SSL_FREE(dP);
SSL_FREE(dQ);
SSL_FREE(qInv);
#else
RSA_priv_key_new(rsa_ctx,
modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len);
#endif
SSL_FREE(modulus);
SSL_FREE(priv_exp);
SSL_FREE(pub_exp);
return X509_OK;
}
static time_t mktime(struct tm *ptm)
{
uint16_t year = 0,mon = 0,day = 0,hour = 0,min = 0,sec = 0;
if (ptm == NULL)
return 0;
year = ptm->tm_year;
mon = ptm->tm_mon;
day = ptm->tm_mday;
hour = ptm->tm_hour;
min = ptm->tm_min;
sec = ptm->tm_sec;
if (0 >= (int)(mon -= 2)){/*1..12 ->11,12,1..10*/
mon += 12; /*Puts Feb last since it has leap day*/
year -= 1;
}
return (((
(unsigned long)(year/4 - year/100 + year/400 +367*mon/12 +day) +
year*365 -719499
)*24 + hour/*now have hours*/
)*60 + min/*now have minutes*/
)*60 + sec;/*finally seconds*/
}
/**
* Get the time of a certificate. Ignore hours/minutes/seconds.
*/
static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t)
{
int ret = X509_NOT_OK, len, t_offset, abs_year;
struct tm tm;
/* see http://tools.ietf.org/html/rfc5280#section-4.1.2.5 */
if (buf[*offset] == ASN1_UTC_TIME)
{
(*offset)++;
len = get_asn1_length(buf, offset);
t_offset = *offset;
memset(&tm, 0, sizeof(struct tm));
tm.tm_year = (buf[t_offset] - '0')*10 + (buf[t_offset+1] - '0');
if (tm.tm_year <= 50) /* 1951-2050 thing */
{
tm.tm_year += 100;
}
tm.tm_mon = (buf[t_offset+2] - '0')*10 + (buf[t_offset+3] - '0') - 1;
tm.tm_mday = (buf[t_offset+4] - '0')*10 + (buf[t_offset+5] - '0');
// LiuH : add mktime interface in function at 2015.06.11
*t = mktime(&tm);
*offset += len;
ret = X509_OK;
}
else if (buf[*offset] == ASN1_GENERALIZED_TIME)
{
(*offset)++;
len = get_asn1_length(buf, offset);
t_offset = *offset;
memset(&tm, 0, sizeof(struct tm));
abs_year = ((buf[t_offset] - '0')*1000 +
(buf[t_offset+1] - '0')*100 + (buf[t_offset+2] - '0')*10 +
(buf[t_offset+3] - '0'));
if (abs_year <= 1901)
{
tm.tm_year = 1;
tm.tm_mon = 0;
tm.tm_mday = 1;
}
else
{
tm.tm_year = abs_year - 1900;
tm.tm_mon = (buf[t_offset+4] - '0')*10 + (buf[t_offset+5] - '0') - 1;
tm.tm_mday = (buf[t_offset+6] - '0')*10 + (buf[t_offset+7] - '0');
tm.tm_hour = (buf[t_offset+8] - '0')*10 + (buf[t_offset+9] - '0');
tm.tm_min = (buf[t_offset+10] - '0')*10 + (buf[t_offset+11] - '0');
tm.tm_sec = (buf[t_offset+12] - '0')*10 + (buf[t_offset+13] - '0');
*t = mktime(&tm);
}
*offset += len;
ret = X509_OK;
}
return ret;
}
/**
* Get the version type of a certificate (which we don't actually care about)
*/
int asn1_version(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
{
int ret = X509_NOT_OK;
(*offset) += 2; /* get past explicit tag */
if (asn1_skip_obj(cert, offset, ASN1_INTEGER))
goto end_version;
ret = X509_OK;
end_version:
return ret;
}
/**
* Retrieve the notbefore and notafter certificate times.
*/
int asn1_validity(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
{
return (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
asn1_get_utc_time(cert, offset, &x509_ctx->not_before) ||
asn1_get_utc_time(cert, offset, &x509_ctx->not_after));
}
/**
* Get the components of a distinguished name
*/
static int asn1_get_oid_x520(const uint8_t *buf, int *offset)
{
int dn_type = 0;
int len;
if ((len = asn1_next_obj(buf, offset, ASN1_OID)) < 0)
goto end_oid;
/* expect a sequence of 2.5.4.[x] where x is a one of distinguished name
components we are interested in. */
if (len == 3 && buf[(*offset)++] == 0x55 && buf[(*offset)++] == 0x04)
dn_type = buf[(*offset)++];
else
{
*offset += len; /* skip over it */
}
end_oid:
return dn_type;
}
/**
* Obtain an ASN.1 printable string type.
*/
static int asn1_get_printable_str(const uint8_t *buf, int *offset, char **str)
{
int len = X509_NOT_OK;
int asn1_type = buf[*offset];
/* some certs have this awful crud in them for some reason */
if (asn1_type != ASN1_PRINTABLE_STR &&
asn1_type != ASN1_PRINTABLE_STR2 &&
asn1_type != ASN1_TELETEX_STR &&
asn1_type != ASN1_IA5_STR &&
asn1_type != ASN1_UNICODE_STR)
goto end_pnt_str;
(*offset)++;
len = get_asn1_length(buf, offset);
if (asn1_type == ASN1_UNICODE_STR)
{
int i;
*str = (char *)SSL_MALLOC(len/2+1); /* allow for null */
for (i = 0; i < len; i += 2)
(*str)[i/2] = buf[*offset + i + 1];
(*str)[len/2] = 0; /* null terminate */
}
else
{
*str = (char *)SSL_MALLOC(len+1); /* allow for null */
memcpy(*str, &buf[*offset], len);
(*str)[len] = 0; /* null terminate */
}
*offset += len;
end_pnt_str:
return len;
}
/**
* Get the subject name (or the issuer) of a certificate.
*/
int asn1_name(const uint8_t *cert, int *offset, char *dn[])
{
int ret = X509_NOT_OK;
int dn_type;
char *tmp;
if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0)
goto end_name;
while (asn1_next_obj(cert, offset, ASN1_SET) >= 0)
{
int i, found = 0;
if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
(dn_type = asn1_get_oid_x520(cert, offset)) < 0)
goto end_name;
tmp = NULL;
if (asn1_get_printable_str(cert, offset, &tmp) < 0)
{
SSL_FREE(tmp);
goto end_name;
}
/* find the distinguished named type */
for (i = 0; i < X509_NUM_DN_TYPES; i++)
{
if (dn_type == g_dn_types[i])
{
if (dn[i] == NULL)
{
dn[i] = tmp;
found = 1;
break;
}
}
}
if (found == 0) /* not found so get rid of it */
{
SSL_FREE(tmp);
}
}
ret = X509_OK;
end_name:
return ret;
}
/**
* Read the modulus and public exponent of a certificate.
*/
int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
{
int ret = X509_NOT_OK, mod_len, pub_len;
uint8_t *modulus = NULL, *pub_exp = NULL;
if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 ||
asn1_skip_obj(cert, offset, ASN1_SEQUENCE) ||
asn1_next_obj(cert, offset, ASN1_BIT_STRING) < 0)
goto end_pub_key;
(*offset)++; /* ignore the padding bit field */
if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0)
goto end_pub_key;
mod_len = asn1_get_int(cert, offset, &modulus);
pub_len = asn1_get_int(cert, offset, &pub_exp);
RSA_pub_key_new(&x509_ctx->rsa_ctx, modulus, mod_len, pub_exp, pub_len);
SSL_FREE(modulus);
SSL_FREE(pub_exp);
ret = X509_OK;
end_pub_key:
return ret;
}
#ifdef CONFIG_SSL_CERT_VERIFICATION
/**
* Read the signature of the certificate.
*/
int asn1_signature(const uint8_t *cert, int *offset, X509_CTX *x509_ctx)
{
int ret = X509_NOT_OK;
if (cert[(*offset)++] != ASN1_BIT_STRING)
goto end_sig;
x509_ctx->sig_len = get_asn1_length(cert, offset)-1;
(*offset)++; /* ignore bit string padding bits */
x509_ctx->signature = (uint8_t *)SSL_MALLOC(x509_ctx->sig_len);
memcpy(x509_ctx->signature, &cert[*offset], x509_ctx->sig_len);
*offset += x509_ctx->sig_len;
ret = X509_OK;
end_sig:
return ret;
}
/*
* Compare 2 distinguished name components for equality
* @return 0 if a match
*/
static int asn1_compare_dn_comp(const char *dn1, const char *dn2)
{
int ret;
if (dn1 == NULL && dn2 == NULL)
ret = 0;
else
ret = (dn1 && dn2) ? strcmp(dn1, dn2) : 1;
return ret;
}
/**
* Clean up all of the CA certificates.
*/
void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx)
{
int i = 0;
if (ca_cert_ctx == NULL)
return;
while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
{
x509_free(ca_cert_ctx->cert[i]);
ca_cert_ctx->cert[i++] = NULL;
}
SSL_FREE(ca_cert_ctx);
}
/*
* Compare 2 distinguished names for equality
* @return 0 if a match
*/
int asn1_compare_dn(char * const dn1[], char * const dn2[])
{
int i;
for (i = 0; i < X509_NUM_DN_TYPES; i++)
{
#if CONFIG_SSL_DISPLAY_MODE
printf("distinguished names: [%s], [%s]\n", dn1[i], dn2[i]);
#endif
if (asn1_compare_dn_comp(dn1[i], dn2[i]))
return 1;
}
return 0; /* all good */
}
int asn1_find_oid(const uint8_t* cert, int* offset,
const uint8_t* oid, int oid_length)
{
int seqlen;
if ((seqlen = asn1_next_obj(cert, offset, ASN1_SEQUENCE))> 0)
{
int end = *offset + seqlen;
while (*offset < end)
{
int type = cert[(*offset)++];
int length = get_asn1_length(cert, offset);
int noffset = *offset + length;
if (type == ASN1_SEQUENCE)
{
type = cert[(*offset)++];
length = get_asn1_length(cert, offset);
if (type == ASN1_OID && length == oid_length &&
memcmp(cert + *offset, oid, oid_length) == 0)
{
*offset += oid_length;
return 1;
}
}
*offset = noffset;
}
}
return 0;
}
int asn1_find_subjectaltname(const uint8_t* cert, int offset)
{
if (asn1_find_oid(cert, &offset, sig_subject_alt_name,
sizeof(sig_subject_alt_name)))
{
return offset;
}
return 0;
}
#endif /* CONFIG_SSL_CERT_VERIFICATION */
/**
* Read the signature type of the certificate. We only support RSA-MD5 and
* RSA-SHA1 signature types.
*/
int asn1_signature_type(const uint8_t *cert,
int *offset, X509_CTX *x509_ctx)
{
int ret = X509_NOT_OK, len;
if (cert[(*offset)++] != ASN1_OID)
goto end_check_sig;
len = get_asn1_length(cert, offset);
if (len == sizeof(sig_sha1WithRSAEncrypt) &&
memcmp(sig_sha1WithRSAEncrypt, &cert[*offset],
sizeof(sig_sha1WithRSAEncrypt)) == 0)
{
x509_ctx->sig_type = SIG_TYPE_SHA1;
}
else if (len == sizeof(sig_sha256) &&
memcmp(sig_sha256, &cert[*offset],
sizeof(sig_sha256)) == 0)
{
x509_ctx->sig_type = SIG_TYPE_SHA256;
}
else if (len == sizeof(sig_sha384) &&
memcmp(sig_sha384, &cert[*offset],
sizeof(sig_sha384)) == 0)
{
x509_ctx->sig_type = SIG_TYPE_SHA384;
}
else if (len == sizeof(sig_sha512) &&
memcmp(sig_sha512, &cert[*offset],
sizeof(sig_sha512)) == 0)
{
x509_ctx->sig_type = SIG_TYPE_SHA512;
}
else
{
if (memcmp(sig_oid_prefix, &cert[*offset], sizeof(sig_oid_prefix)))
goto end_check_sig; /* unrecognised cert type */
x509_ctx->sig_type = cert[*offset + sizeof(sig_oid_prefix)];
}
*offset += len;
asn1_skip_obj(cert, offset, ASN1_NULL); /* if it's there */
ret = X509_OK;
end_check_sig:
return ret;
}

View File

@ -1,370 +0,0 @@
/*
* Copyright (c) 2007-2014, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ssl/ssl_config.h"
#ifdef CONFIG_SSL_GENERATE_X509_CERT
#include <string.h>
#include <stdlib.h>
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_ssl.h"
/**
* Generate a basic X.509 certificate
*/
static uint8_t set_gen_length(int len, uint8_t *buf, int *offset)
{
if (len < 0x80) /* short form */
{
buf[(*offset)++] = len;
return 1;
}
else /* long form */
{
int i, length_bytes = 0;
if (len & 0x00FF0000)
length_bytes = 3;
else if (len & 0x0000FF00)
length_bytes = 2;
else if (len & 0x000000FF)
length_bytes = 1;
buf[(*offset)++] = 0x80 + length_bytes;
for (i = length_bytes-1; i >= 0; i--)
{
buf[*offset+i] = len & 0xFF;
len >>= 8;
}
*offset += length_bytes;
return length_bytes+1;
}
}
static int pre_adjust_with_size(uint8_t type,
int *seq_offset, uint8_t *buf, int *offset)
{
buf[(*offset)++] = type;
*seq_offset = *offset;
*offset += 4; /* fill in later */
return *offset;
}
static void adjust_with_size(int seq_size, int seq_start,
uint8_t *buf, int *offset)
{
uint8_t seq_byte_size;
int orig_seq_size = seq_size;
int orig_seq_start = seq_start;
seq_size = *offset-seq_size;
seq_byte_size = set_gen_length(seq_size, buf, &seq_start);
if (seq_byte_size != 4)
{
memmove(&buf[orig_seq_start+seq_byte_size],
&buf[orig_seq_size], seq_size);
*offset -= 4-seq_byte_size;
}
}
static void gen_serial_number(uint8_t *buf, int *offset)
{
static const uint8_t ser_oid[] = { ASN1_INTEGER, 1, 0x7F };
memcpy(&buf[*offset], ser_oid , sizeof(ser_oid));
*offset += sizeof(ser_oid);
}
static void gen_signature_alg(uint8_t *buf, int *offset)
{
/* OBJECT IDENTIFIER sha1withRSAEncryption (1 2 840 113549 1 1 5) */
static const uint8_t sig_oid[] =
{
ASN1_SEQUENCE, 0x0d, ASN1_OID, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
ASN1_NULL, 0x00
};
memcpy(&buf[*offset], sig_oid, sizeof(sig_oid));
*offset += sizeof(sig_oid);
}
static int gen_dn(const char *name, uint8_t dn_type,
uint8_t *buf, int *offset)
{
int ret = X509_OK;
int name_size = strlen(name);
if (name_size > 0x70) /* just too big */
{
ret = X509_NOT_OK;
goto error;
}
buf[(*offset)++] = ASN1_SET;
set_gen_length(9+name_size, buf, offset);
buf[(*offset)++] = ASN1_SEQUENCE;
set_gen_length(7+name_size, buf, offset);
buf[(*offset)++] = ASN1_OID;
buf[(*offset)++] = 3;
buf[(*offset)++] = 0x55;
buf[(*offset)++] = 0x04;
buf[(*offset)++] = dn_type;
buf[(*offset)++] = ASN1_PRINTABLE_STR;
buf[(*offset)++] = name_size;
strcpy(&buf[*offset], name);
*offset += name_size;
error:
return ret;
}
static int gen_issuer(const char * dn[], uint8_t *buf, int *offset)
{
int ret = X509_OK;
int seq_offset;
int seq_size = pre_adjust_with_size(
ASN1_SEQUENCE, &seq_offset, buf, offset);
char fqdn[128];
/* we need the common name, so if not configured, work out the fully
* qualified domain name */
if (dn[X509_COMMON_NAME] == NULL || strlen(dn[X509_COMMON_NAME]) == 0)
{
int fqdn_len;
gethostname(fqdn, sizeof(fqdn));
fqdn_len = strlen(fqdn);
fqdn[fqdn_len++] = '.';
if (getdomainname(&fqdn[fqdn_len], sizeof(fqdn)-fqdn_len) < 0)
{
ret = X509_NOT_OK;
goto error;
}
fqdn_len = strlen(fqdn);
if (fqdn[fqdn_len-1] == '.') /* ensure '.' is not last char */
fqdn[fqdn_len-1] = 0;
dn[X509_COMMON_NAME] = fqdn;
}
if ((ret = gen_dn(dn[X509_COMMON_NAME], 3, buf, offset)))
goto error;
if (dn[X509_ORGANIZATION] != NULL && strlen(dn[X509_ORGANIZATION]) > 0)
{
if ((ret = gen_dn(dn[X509_ORGANIZATION], 10, buf, offset)))
goto error;
}
if (dn[X509_ORGANIZATIONAL_UNIT] != NULL &&
strlen(dn[X509_ORGANIZATIONAL_UNIT]) > 0)
{
if ((ret = gen_dn(dn[X509_ORGANIZATIONAL_UNIT], 11, buf, offset)))
goto error;
}
adjust_with_size(seq_size, seq_offset, buf, offset);
error:
return ret;
}
static void gen_utc_time(uint8_t *buf, int *offset)
{
static const uint8_t time_seq[] =
{
ASN1_SEQUENCE, 30,
ASN1_UTC_TIME, 13,
'0', '7', '0', '1', '0', '1', '0', '0', '0', '0', '0', '0', 'Z',
ASN1_UTC_TIME, 13, /* make it good for 30 or so years */
'3', '8', '0', '1', '0', '1', '0', '0', '0', '0', '0', '0', 'Z'
};
/* fixed time */
memcpy(&buf[*offset], time_seq, sizeof(time_seq));
*offset += sizeof(time_seq);
}
static void gen_pub_key2(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
{
static const uint8_t pub_key_seq[] =
{
ASN1_INTEGER, 0x03, 0x01, 0x00, 0x01 /* INTEGER 65537 */
};
int seq_offset;
int pub_key_size = rsa_ctx->num_octets;
uint8_t *block = (uint8_t *)alloca(pub_key_size);
int seq_size = pre_adjust_with_size(
ASN1_SEQUENCE, &seq_offset, buf, offset);
buf[(*offset)++] = ASN1_INTEGER;
bi_export(rsa_ctx->bi_ctx, rsa_ctx->m, block, pub_key_size);
if (*block & 0x80) /* make integer positive */
{
set_gen_length(pub_key_size+1, buf, offset);
buf[(*offset)++] = 0;
}
else
set_gen_length(pub_key_size, buf, offset);
memcpy(&buf[*offset], block, pub_key_size);
*offset += pub_key_size;
memcpy(&buf[*offset], pub_key_seq, sizeof(pub_key_seq));
*offset += sizeof(pub_key_seq);
adjust_with_size(seq_size, seq_offset, buf, offset);
}
static void gen_pub_key1(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
{
int seq_offset;
int seq_size = pre_adjust_with_size(
ASN1_BIT_STRING, &seq_offset, buf, offset);
buf[(*offset)++] = 0; /* bit string is multiple of 8 */
gen_pub_key2(rsa_ctx, buf, offset);
adjust_with_size(seq_size, seq_offset, buf, offset);
}
static void gen_pub_key(const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset)
{
/* OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1) */
static const uint8_t rsa_enc_oid[] =
{
ASN1_SEQUENCE, 0x0d, ASN1_OID, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
ASN1_NULL, 0x00
};
int seq_offset;
int seq_size = pre_adjust_with_size(
ASN1_SEQUENCE, &seq_offset, buf, offset);
memcpy(&buf[*offset], rsa_enc_oid, sizeof(rsa_enc_oid));
*offset += sizeof(rsa_enc_oid);
gen_pub_key1(rsa_ctx, buf, offset);
adjust_with_size(seq_size, seq_offset, buf, offset);
}
static void gen_signature(const RSA_CTX *rsa_ctx, const uint8_t *sha_dgst,
uint8_t *buf, int *offset)
{
static const uint8_t asn1_sig[] =
{
ASN1_SEQUENCE, 0x21, ASN1_SEQUENCE, 0x09, ASN1_OID, 0x05,
0x2b, 0x0e, 0x03, 0x02, 0x1a, /* sha1 (1 3 14 3 2 26) */
ASN1_NULL, 0x00, ASN1_OCTET_STRING, 0x14
};
uint8_t *enc_block = (uint8_t *)alloca(rsa_ctx->num_octets);
uint8_t *block = (uint8_t *)alloca(sizeof(asn1_sig) + SHA1_SIZE);
int sig_size;
/* add the digest as an embedded asn.1 sequence */
memcpy(block, asn1_sig, sizeof(asn1_sig));
memcpy(&block[sizeof(asn1_sig)], sha_dgst, SHA1_SIZE);
sig_size = RSA_encrypt(rsa_ctx, block,
sizeof(asn1_sig) + SHA1_SIZE, enc_block, 1);
buf[(*offset)++] = ASN1_BIT_STRING;
set_gen_length(sig_size+1, buf, offset);
buf[(*offset)++] = 0; /* bit string is multiple of 8 */
memcpy(&buf[*offset], enc_block, sig_size);
*offset += sig_size;
}
static int gen_tbs_cert(const char * dn[],
const RSA_CTX *rsa_ctx, uint8_t *buf, int *offset,
uint8_t *sha_dgst)
{
int ret = X509_OK;
SHA1_CTX sha_ctx;
int seq_offset;
int begin_tbs = *offset;
int seq_size = pre_adjust_with_size(
ASN1_SEQUENCE, &seq_offset, buf, offset);
gen_serial_number(buf, offset);
gen_signature_alg(buf, offset);
/* CA certicate issuer */
if ((ret = gen_issuer(dn, buf, offset)))
goto error;
gen_utc_time(buf, offset);
/* certificate issuer */
if ((ret = gen_issuer(dn, buf, offset)))
goto error;
gen_pub_key(rsa_ctx, buf, offset);
adjust_with_size(seq_size, seq_offset, buf, offset);
SHA1_Init(&sha_ctx);
SHA1_Update(&sha_ctx, &buf[begin_tbs], *offset-begin_tbs);
SHA1_Final(sha_dgst, &sha_ctx);
error:
return ret;
}
/**
* Create a new certificate.
*/
EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, uint32_t options, const char * dn[], uint8_t **cert_data)
{
int ret = X509_OK, offset = 0, seq_offset;
/* allocate enough space to load a new certificate */
uint8_t *buf = (uint8_t *)alloca(ssl_ctx->rsa_ctx->num_octets*2 + 512);
uint8_t sha_dgst[SHA1_SIZE];
int seq_size = pre_adjust_with_size(ASN1_SEQUENCE,
&seq_offset, buf, &offset);
if ((ret = gen_tbs_cert(dn, ssl_ctx->rsa_ctx, buf, &offset, sha_dgst)) < 0)
goto error;
gen_signature_alg(buf, &offset);
gen_signature(ssl_ctx->rsa_ctx, sha_dgst, buf, &offset);
adjust_with_size(seq_size, seq_offset, buf, &offset);
*cert_data = (uint8_t *)SSL_MALLOC(offset); /* create the exact memory for it */
memcpy(*cert_data, buf, offset);
error:
return ret < 0 ? ret : offset;
}
#endif

View File

@ -1,517 +0,0 @@
/*
* Copyright (c) 2007-2014, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Load certificates/keys into memory. These can be in many different formats.
* PEM support and other formats can be processed here.
*
* The PEM private keys may be optionally encrypted with AES128 or AES256.
* The encrypted PEM keys were generated with something like:
*
* openssl genrsa -aes128 -passout pass:abcd -out axTLS.key_aes128.pem 512
*/
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_ssl.h"
static int do_obj(SSL_CTX *ssl_ctx, int obj_type,
SSLObjLoader *ssl_obj, const char *password);
#ifdef CONFIG_SSL_HAS_PEM
static int ssl_obj_PEM_load(SSL_CTX *ssl_ctx, int obj_type,
SSLObjLoader *ssl_obj, const char *password);
#endif
/*
* Load a file into memory that is in binary DER (or ascii PEM) format.
*/
EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type,
const char *filename, const char *password)
{
#ifndef CONFIG_SSL_SKELETON_MODE
static const char * const begin = "-----BEGIN";
int ret = SSL_OK;
SSLObjLoader *ssl_obj = NULL;
if (filename == NULL)
{
ret = SSL_ERROR_INVALID_KEY;
goto error;
}
ssl_obj = (SSLObjLoader *)SSL_ZALLOC(sizeof(SSLObjLoader));
ssl_obj->len = get_file(filename, &ssl_obj->buf);
if (ssl_obj->len <= 0)
{
ret = SSL_ERROR_INVALID_KEY;
goto error;
}
/* is the file a PEM file? */
if ((char *)strstr((const char *)ssl_obj->buf, begin) != NULL)
{
#ifdef CONFIG_SSL_HAS_PEM
#if CONFIG_SSL_DISPLAY_MODE
printf("the file is a PEM file.\n");
#endif
ret = ssl_obj_PEM_load(ssl_ctx, obj_type, ssl_obj, password);
#else
ssl_printf(unsupported_str);
ret = SSL_ERROR_NOT_SUPPORTED;
#endif
}
else {
#if CONFIG_SSL_DISPLAY_MODE
printf("the file is not a PEM file.\n");
#endif
ret = do_obj(ssl_ctx, obj_type, ssl_obj, password);
}
error:
ssl_obj_free(ssl_obj);
return ret;
#else
ssl_printf(unsupported_str);
return SSL_ERROR_NOT_SUPPORTED;
#endif /* CONFIG_SSL_SKELETON_MODE */
}
/*
* Transfer binary data into the object loader.
*/
EXP_FUNC int STDCALL ssl_obj_memory_load(SSL_CTX *ssl_ctx, int mem_type,
const uint8_t *data, int len, const char *password)
{
int ret;
SSLObjLoader *ssl_obj;
uint32_t sign_len = (len + 3)&(~3);
ssl_obj = (SSLObjLoader *)SSL_ZALLOC(sizeof(SSLObjLoader));
ssl_obj->buf = (uint8_t *)SSL_MALLOC(sign_len);
memcpy(ssl_obj->buf, data, sign_len);
ssl_obj->len = len;
ret = do_obj(ssl_ctx, mem_type, ssl_obj, password);
ssl_obj_free(ssl_obj);
return ret;
}
/*
* Actually work out what we are doing
*/
static int do_obj(SSL_CTX *ssl_ctx, int obj_type,
SSLObjLoader *ssl_obj, const char *password)
{
int ret = SSL_OK;
switch (obj_type)
{
case SSL_OBJ_RSA_KEY:
ret = add_private_key(ssl_ctx, ssl_obj);
break;
case SSL_OBJ_X509_CERT:
ret = add_cert(ssl_ctx, ssl_obj->buf, ssl_obj->len);
break;
#ifdef CONFIG_SSL_CERT_VERIFICATION
case SSL_OBJ_X509_CACERT:
add_cert_auth(ssl_ctx, ssl_obj->buf, ssl_obj->len);
break;
#endif
#ifdef CONFIG_SSL_USE_PKCS12
case SSL_OBJ_PKCS8:
ret = pkcs8_decode(ssl_ctx, ssl_obj, password);
break;
case SSL_OBJ_PKCS12:
ret = pkcs12_decode(ssl_ctx, ssl_obj, password);
break;
#endif
default:
ssl_printf(unsupported_str);
ret = SSL_ERROR_NOT_SUPPORTED;
break;
}
return ret;
}
/*
* Clean up our mess.
*/
void ssl_obj_free(SSLObjLoader *ssl_obj)
{
if (ssl_obj)
{
SSL_FREE(ssl_obj->buf);
SSL_FREE(ssl_obj);
}
}
/*
* Support for PEM encoded keys/certificates.
*/
#ifdef CONFIG_SSL_HAS_PEM
#define NUM_PEM_TYPES 4
#define IV_SIZE 16
#define IS_RSA_PRIVATE_KEY 0
#define IS_ENCRYPTED_PRIVATE_KEY 1
#define IS_PRIVATE_KEY 2
#define IS_CERTIFICATE 3
static const char begins[NUM_PEM_TYPES][40] =
{
"-----BEGIN RSA PRIVATE KEY-----",
"-----BEGIN ENCRYPTED PRIVATE KEY-----",
"-----BEGIN PRIVATE KEY-----",
"-----BEGIN CERTIFICATE-----",
};
static const char ends[NUM_PEM_TYPES][40] =
{
"-----END RSA PRIVATE KEY-----",
"-----END ENCRYPTED PRIVATE KEY-----",
"-----END PRIVATE KEY-----",
"-----END CERTIFICATE-----",
};
static const char aes_str[2][24] =
{
"DEK-Info: AES-128-CBC,",
"DEK-Info: AES-256-CBC,"
};
/**
* Take a base64 blob of data and decrypt it (using AES) into its
* proper ASN.1 form.
*/
static int pem_decrypt(const char *where, const char *end,
const char *password, SSLObjLoader *ssl_obj)
{
int ret = -1;
int is_aes_256 = 0;
char *start = NULL;
uint8_t iv[IV_SIZE];
int i, pem_size;
MD5_CTX md5_ctx;
AES_CTX aes_ctx;
uint8_t key[32]; /* AES256 size */
char *aes_str_0_ram = NULL;
char *aes_str_1_ram = NULL;
if (password == NULL || strlen(password) == 0)
{
#ifdef CONFIG_SSL_FULL_MODE
ssl_printf("Error: Need a password for this PEM file\n"); //TTY_FLUSH();
#endif
goto error;
}
aes_str_0_ram = (char *)SSL_MALLOC(24);
aes_str_1_ram = (char *)SSL_MALLOC(24);
system_get_string_from_flash(aes_str[0], aes_str_0_ram, 24);
system_get_string_from_flash(aes_str[1], aes_str_1_ram, 24);
if ((start = (char *)strstr((const char *)where, aes_str_0_ram))) /* AES128? */
{
start += strlen(aes_str_0_ram);
}
else if ((start = (char *)strstr((const char *)where, aes_str_1_ram))) /* AES256? */
{
is_aes_256 = 1;
start += strlen(aes_str_1_ram);
}
else
{
#ifdef CONFIG_SSL_FULL_MODE
ssl_printf("Error: Unsupported password cipher\n"); //TTY_FLUSH();
#endif
goto error;
}
/* convert from hex to binary - assumes uppercase hex */
for (i = 0; i < IV_SIZE; i++)
{
char c = *start++ - '0';
iv[i] = (c > 9 ? c + '0' - 'A' + 10 : c) << 4;
c = *start++ - '0';
iv[i] += (c > 9 ? c + '0' - 'A' + 10 : c);
}
while (*start == '\r' || *start == '\n')
start++;
/* turn base64 into binary */
pem_size = (int)(end-start);
if (base64_decode(start, pem_size, ssl_obj->buf, &ssl_obj->len) != 0)
goto error;
/* work out the key */
MD5_Init(&md5_ctx);
MD5_Update(&md5_ctx, (const uint8_t *)password, strlen(password));
MD5_Update(&md5_ctx, iv, SALT_SIZE);
MD5_Final(key, &md5_ctx);
if (is_aes_256)
{
MD5_Init(&md5_ctx);
MD5_Update(&md5_ctx, key, MD5_SIZE);
MD5_Update(&md5_ctx, (const uint8_t *)password, strlen(password));
MD5_Update(&md5_ctx, iv, SALT_SIZE);
MD5_Final(&key[MD5_SIZE], &md5_ctx);
}
/* decrypt using the key/iv */
AES_set_key(&aes_ctx, key, iv, is_aes_256 ? AES_MODE_256 : AES_MODE_128);
AES_convert_key(&aes_ctx);
AES_cbc_decrypt(&aes_ctx, ssl_obj->buf, ssl_obj->buf, ssl_obj->len);
ret = 0;
error:
SSL_FREE(aes_str_0_ram);
SSL_FREE(aes_str_1_ram);
return ret;
}
/**
* Take a base64 blob of data and turn it into its proper ASN.1 form.
*/
static int new_pem_obj(SSL_CTX *ssl_ctx, int is_cacert, char *where,
int remain, const char *password)
{
int ret = SSL_ERROR_BAD_CERTIFICATE;
SSLObjLoader *ssl_obj = NULL;
char *begins_ram = (char *)SSL_MALLOC(40);
char *ends_ram = (char *)SSL_MALLOC(40);
while (remain > 0)
{
int i, pem_size, obj_type;
char *start = NULL, *end = NULL;
for (i = 0; i < NUM_PEM_TYPES; i++)
{
system_get_string_from_flash(begins[i], begins_ram, 40);
system_get_string_from_flash(ends[i], ends_ram, 40);
if ((start = (char *)strstr(where, begins_ram)) &&
(end = (char *)strstr(where, ends_ram)))
{
remain -= (int)(end-where);
start += strlen(begins_ram);
pem_size = (int)(end-start);
ssl_obj = (SSLObjLoader *)SSL_ZALLOC(sizeof(SSLObjLoader));
/* 4/3 bigger than what we need but so what */
ssl_obj->buf = (uint8_t *)SSL_ZALLOC(pem_size);
ssl_obj->len = pem_size;
if (i == IS_RSA_PRIVATE_KEY &&
strstr(start, "Proc-Type:") &&
strstr(start, "4,ENCRYPTED"))
{
/* check for encrypted PEM file */
if (pem_decrypt(start, end, password, ssl_obj) < 0)
{
ret = SSL_ERROR_BAD_CERTIFICATE;
goto error;
}
}
else
{
ssl_obj->len = pem_size;
if (base64_decode(start, pem_size,
ssl_obj->buf, &ssl_obj->len) != 0)
{
ret = SSL_ERROR_BAD_CERTIFICATE;
goto error;
}
}
switch (i)
{
case IS_RSA_PRIVATE_KEY:
obj_type = SSL_OBJ_RSA_KEY;
break;
case IS_ENCRYPTED_PRIVATE_KEY:
case IS_PRIVATE_KEY:
obj_type = SSL_OBJ_PKCS8;
break;
case IS_CERTIFICATE:
obj_type = is_cacert ?
SSL_OBJ_X509_CACERT : SSL_OBJ_X509_CERT;
break;
default:
ret = SSL_ERROR_BAD_CERTIFICATE;
goto error;
}
/* In a format we can now understand - so process it */
if ((ret = do_obj(ssl_ctx, obj_type, ssl_obj, password)))
goto error;
end += strlen(ends_ram);
remain -= strlen(ends_ram);
while (remain > 0 && (*end == '\r' || *end == '\n'))
{
end++;
remain--;
}
where = end;
break;
}
}
ssl_obj_free(ssl_obj);
ssl_obj = NULL;
if (start == NULL)
break;
}
error:
SSL_FREE(begins_ram);
SSL_FREE(ends_ram);
ssl_obj_free(ssl_obj);
return ret;
}
/*
* Load a file into memory that is in ASCII PEM format.
*/
static int ssl_obj_PEM_load(SSL_CTX *ssl_ctx, int obj_type,
SSLObjLoader *ssl_obj, const char *password)
{
char *start;
/* add a null terminator */
ssl_obj->len++;
ssl_obj->buf = (uint8_t *)SSL_REALLOC(ssl_obj->buf, ssl_obj->len);
ssl_obj->buf[ssl_obj->len-1] = 0;
start = (char *)ssl_obj->buf;
return new_pem_obj(ssl_ctx, obj_type == SSL_OBJ_X509_CACERT,
start, ssl_obj->len, password);
}
#endif /* CONFIG_SSL_HAS_PEM */
/**
* Load the key/certificates in memory depending on compile-time and user
* options.
*/
int load_key_certs(SSL_CTX *ssl_ctx)
{
int ret = SSL_OK;
uint32_t options = ssl_ctx->options;
#ifdef CONFIG_SSL_GENERATE_X509_CERT
uint8_t *cert_data = NULL;
int cert_size;
static const char *dn[] =
{
CONFIG_SSL_X509_COMMON_NAME,
CONFIG_SSL_X509_ORGANIZATION_NAME,
CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME
};
#endif
/* do the private key first */
if (strlen(CONFIG_SSL_PRIVATE_KEY_LOCATION) > 0)
{
if ((ret = ssl_obj_load(ssl_ctx, SSL_OBJ_RSA_KEY,
CONFIG_SSL_PRIVATE_KEY_LOCATION,
CONFIG_SSL_PRIVATE_KEY_PASSWORD)) < 0)
goto error;
}
else if (!(options & SSL_NO_DEFAULT_KEY))
{
#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE)
// static const /* saves a few more bytes */
//#include "private_key.h"
extern unsigned int def_private_key_len;
extern unsigned char *def_private_key;
if (def_private_key == NULL){
ret = SSL_NOT_OK;
goto error;
}
ssl_obj_memory_load(ssl_ctx, SSL_OBJ_RSA_KEY, def_private_key,
def_private_key_len, NULL);
#endif
}
/* now load the certificate */
#ifdef CONFIG_SSL_GENERATE_X509_CERT
if ((cert_size = ssl_x509_create(ssl_ctx, 0, dn, &cert_data)) < 0)
{
ret = cert_size;
goto error;
}
ssl_obj_memory_load(ssl_ctx, SSL_OBJ_X509_CERT, cert_data, cert_size, NULL);
SSL_FREE(cert_data);
#else
if (strlen(CONFIG_SSL_X509_CERT_LOCATION))
{
if ((ret = ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT,
CONFIG_SSL_X509_CERT_LOCATION, NULL)) < 0)
goto error;
}
else if (!(options & SSL_NO_DEFAULT_KEY))
{
#if defined(CONFIG_SSL_USE_DEFAULT_KEY) || defined(CONFIG_SSL_SKELETON_MODE)
// static const /* saves a few bytes and RAM */
//#include "cert.h"
extern unsigned char *def_certificate;
extern unsigned int def_certificate_len;
if (def_certificate == NULL){
ret = SSL_NOT_OK;
goto error;
}
ssl_obj_memory_load(ssl_ctx, SSL_OBJ_X509_CERT,
def_certificate, def_certificate_len, NULL);
#endif
}
#endif
error:
#ifdef CONFIG_SSL_FULL_MODE
if (ret)
{
ssl_printf("Error: Certificate or key not loaded\n"); //TTY_FLUSH();
}
#endif
return ret;
}

View File

@ -1,322 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Enable a subset of openssl compatible functions. We don't aim to be 100%
* compatible - just to be able to do basic ports etc.
*
* Only really tested on mini_httpd, so I'm not too sure how extensive this
* port is.
*/
#include "ssl/ssl_config.h"
#ifdef CONFIG_OPENSSL_COMPATIBLE
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_ssl.h"
#define OPENSSL_CTX_ATTR ((OPENSSL_CTX *)ssl_ctx->bonus_attr)
static char *key_password = NULL;
void *SSLv23_server_method(void) { return NULL; }
void *SSLv3_server_method(void) { return NULL; }
void *TLSv1_server_method(void) { return NULL; }
void *SSLv23_client_method(void) { return NULL; }
void *SSLv3_client_method(void) { return NULL; }
void *TLSv1_client_method(void) { return NULL; }
typedef void * (*ssl_func_type_t)(void);
typedef void * (*bio_func_type_t)(void);
typedef struct
{
ssl_func_type_t ssl_func_type;
} OPENSSL_CTX;
SSL_CTX *SSL_CTX_new(ssl_func_type_t meth)
{
SSL_CTX *ssl_ctx = ssl_ctx_new(0, 5);
ssl_ctx->bonus_attr = SSL_MALLOC(sizeof(OPENSSL_CTX));
OPENSSL_CTX_ATTR->ssl_func_type = meth;
return ssl_ctx;
}
void SSL_CTX_free(SSL_CTX *ssl_ctx)
{
SSL_FREE(ssl_ctx->bonus_attr);
ssl_ctx_free(ssl_ctx);
}
SSL *SSL_new(SSL_CTX *ssl_ctx)
{
SSL *ssl;
ssl_func_type_t ssl_func_type;
ssl = ssl_new(ssl_ctx, -1); /* fd is set later */
ssl_func_type = OPENSSL_CTX_ATTR->ssl_func_type;
#ifdef CONFIG_SSL_ENABLE_CLIENT
if (ssl_func_type == SSLv23_client_method ||
ssl_func_type == SSLv3_client_method ||
ssl_func_type == TLSv1_client_method)
{
SET_SSL_FLAG(SSL_IS_CLIENT);
}
else
#endif
{
ssl->next_state = HS_CLIENT_HELLO;
}
return ssl;
}
int SSL_set_fd(SSL *s, int fd)
{
s->client_fd = fd;
return 1; /* always succeeds */
}
int SSL_accept(SSL *ssl)
{
while (ssl_read(ssl, NULL) == SSL_OK)
{
if (ssl->next_state == HS_CLIENT_HELLO)
return 1; /* we're done */
}
return -1;
}
#ifdef CONFIG_SSL_ENABLE_CLIENT
int SSL_connect(SSL *ssl)
{
return do_client_connect(ssl) == SSL_OK ? 1 : -1;
}
#endif
void SSL_free(SSL *ssl)
{
ssl_free(ssl);
}
int SSL_read(SSL *ssl, void *buf, int num)
{
uint8_t *read_buf;
int ret;
while ((ret = ssl_read(ssl, &read_buf)) == SSL_OK);
if (ret > SSL_OK)
{
memcpy(buf, read_buf, ret > num ? num : ret);
}
return ret;
}
int SSL_write(SSL *ssl, const void *buf, int num)
{
return ssl_write(ssl, buf, num);
}
int SSL_CTX_use_certificate_file(SSL_CTX *ssl_ctx, const char *file, int type)
{
return (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, file, NULL) == SSL_OK);
}
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ssl_ctx, const char *file, int type)
{
return (ssl_obj_load(ssl_ctx, SSL_OBJ_RSA_KEY, file, key_password) == SSL_OK);
}
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ssl_ctx, int len, const uint8_t *d)
{
return (ssl_obj_memory_load(ssl_ctx,
SSL_OBJ_X509_CERT, d, len, NULL) == SSL_OK);
}
int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
unsigned int sid_ctx_len)
{
return 1;
}
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
{
return 1;
}
int SSL_CTX_use_certificate_chain_file(SSL_CTX *ssl_ctx, const char *file)
{
return (ssl_obj_load(ssl_ctx,
SSL_OBJ_X509_CERT, file, NULL) == SSL_OK);
}
int SSL_shutdown(SSL *ssl)
{
return 1;
}
/*** get/set session ***/
SSL_SESSION *SSL_get1_session(SSL *ssl)
{
return (SSL_SESSION *)ssl_get_session_id(ssl); /* note: wrong cast */
}
int SSL_set_session(SSL *ssl, SSL_SESSION *session)
{
memcpy(ssl->session_id, (uint8_t *)session, SSL_SESSION_ID_SIZE);
return 1;
}
void SSL_SESSION_free(SSL_SESSION *session) { }
/*** end get/set session ***/
long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
{
return 0;
}
void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
int (*verify_callback)(int, void *)) { }
void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) { }
int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
const char *CApath)
{
return 1;
}
void *SSL_load_client_CA_file(const char *file)
{
return (void *)file;
}
void SSL_CTX_set_client_CA_list(SSL_CTX *ssl_ctx, void *file)
{
ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, (const char *)file, NULL);
}
void SSLv23_method(void) { }
void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, void *cb) { }
void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u)
{
key_password = (char *)u;
}
int SSL_peek(SSL *ssl, void *buf, int num)
{
memcpy(buf, ssl->bm_data, num);
return num;
}
void SSL_set_bio(SSL *ssl, void *rbio, void *wbio) { }
long SSL_get_verify_result(const SSL *ssl)
{
return ssl_handshake_status(ssl);
}
int SSL_state(SSL *ssl)
{
return 0x03; // ok state
}
/** end of could do better list */
void *SSL_get_peer_certificate(const SSL *ssl)
{
return &ssl->ssl_ctx->certs[0];
}
int SSL_clear(SSL *ssl)
{
return 1;
}
int SSL_CTX_check_private_key(const SSL_CTX *ctx)
{
return 1;
}
int SSL_CTX_set_cipher_list(SSL *s, const char *str)
{
return 1;
}
int SSL_get_error(const SSL *ssl, int ret)
{
ssl_display_error(ret);
return 0; /* TODO: return proper return code */
}
void SSL_CTX_set_options(SSL_CTX *ssl_ctx, int option) {}
int SSL_library_init(void ) { return 1; }
void SSL_load_error_strings(void ) {}
void ERR_print_errors_fp(FILE *fp) {}
#ifndef CONFIG_SSL_SKELETON_MODE
long SSL_CTX_get_timeout(const SSL_CTX *ssl_ctx) {
return CONFIG_SSL_EXPIRY_TIME*3600; }
long SSL_CTX_set_timeout(SSL_CTX *ssl_ctx, long t) {
return SSL_CTX_get_timeout(ssl_ctx); }
#endif
void BIO_printf(FILE *f, const char *format, ...)
{
va_list(ap);
va_start(ap, format);
vfprintf(f, format, ap);
va_end(ap);
}
void* BIO_s_null(void) { return NULL; }
FILE *BIO_new(bio_func_type_t func)
{
if (func == BIO_s_null)
return fopen("/dev/null", "r");
else
return NULL;
}
FILE *BIO_new_fp(FILE *stream, int close_flag) { return stream; }
int BIO_free(FILE *a) { if (a != stdout && a != stderr) fclose(a); return 1; }
#endif

View File

@ -1,339 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file os_port.c
*
* OS specific functions.
*/
#include "ssl/ssl_os_port.h"
#include <sys/socket.h>
#ifdef WIN32
/**
* gettimeofday() not in Win32
*/
EXP_FUNC void STDCALL gettimeofday(struct timeval* t, void* timezone)
{
#if defined(_WIN32_WCE)
t->tv_sec = time(NULL);
t->tv_usec = 0; /* 1sec precision only */
#else
struct _timeb timebuffer;
_ftime(&timebuffer);
t->tv_sec = (long)timebuffer.time;
t->tv_usec = 1000 * timebuffer.millitm; /* 1ms precision */
#endif
}
/**
* strcasecmp() not in Win32
*/
EXP_FUNC int STDCALL strcasecmp(const char *s1, const char *s2)
{
while (tolower(*s1) == tolower(*s2++))
{
if (*s1++ == '\0')
{
return 0;
}
}
return *(unsigned char *)s1 - *(unsigned char *)(s2 - 1);
}
EXP_FUNC int STDCALL getdomainname(char *buf, int buf_size)
{
HKEY hKey;
unsigned long datatype;
unsigned long bufferlength = buf_size;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"),
0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
return -1;
RegQueryValueEx(hKey, "Domain", NULL, &datatype, buf, &bufferlength);
RegCloseKey(hKey);
return 0;
}
#endif
//static const char * out_of_mem_str = "out of memory %s %d\n";
#define exit_now printf
//#define SSL_LOG
#ifdef SSL_LOG
#define debug_now printf
#else
#define debug_now(fmt, ...)
#endif
#if 0
static MEM_LEAK * ptr_start = NULL;
static MEM_LEAK * ptr_next = NULL;
xTaskHandle mem_mutex;
#define name_length 128
extern int mem_flag;
void add(MEM_INFO alloc_info)
{
MEM_LEAK * mem_leak_info = NULL;
mem_leak_info = (MEM_LEAK *)malloc(sizeof(MEM_LEAK));
mem_leak_info->mem_info.address = alloc_info.address;
mem_leak_info->mem_info.size = alloc_info.size;
strcpy(mem_leak_info->mem_info.file_name, alloc_info.file_name);
mem_leak_info->mem_info.line = alloc_info.line;
mem_leak_info->next = NULL;
if (ptr_start == NULL)
{
ptr_start = mem_leak_info;
ptr_next = ptr_start;
}
else {
ptr_next->next = mem_leak_info;
ptr_next = ptr_next->next;
}
if(mem_flag) {
printf("mem_leak_info =%p\n",mem_leak_info);
mem_flag = 0;
report_mem_leak();
}
}
void erase(unsigned pos)
{
unsigned index = 0;
MEM_LEAK * alloc_info, * temp;
if(pos == 0)
{
MEM_LEAK * temp = ptr_start;
ptr_start = ptr_start->next;
free(temp);
}
else
{
for(index = 0, alloc_info = ptr_start; index < pos;
alloc_info = alloc_info->next, ++index)
{
if(pos == index + 1)
{
temp = alloc_info->next;
alloc_info->next = temp->next;
free(temp);
break;
}
}
}
}
void clear()
{
MEM_LEAK * temp = ptr_start;
MEM_LEAK * alloc_info = ptr_start;
while(alloc_info != NULL)
{
alloc_info = alloc_info->next;
free(temp);
temp = alloc_info;
}
}
void add_mem_info (void * mem_ref, unsigned int size, const char * file, unsigned int line)
{
sys_mutex_lock(&mem_mutex);
MEM_INFO mem_alloc_info;
memset( &mem_alloc_info, 0, sizeof ( mem_alloc_info ) );
mem_alloc_info.address = mem_ref;
mem_alloc_info.size = size;
strncpy(mem_alloc_info.file_name, file, FILE_NAME_LENGTH);
mem_alloc_info.line = line;
add(mem_alloc_info);
sys_mutex_unlock(&mem_mutex);
}
void remove_mem_info (void * mem_ref)
{
unsigned short index;
MEM_LEAK * leak_info = ptr_start;
sys_mutex_lock(&mem_mutex);
for(index = 0; leak_info != NULL; ++index, leak_info = leak_info->next)
{
if ( leak_info->mem_info.address == mem_ref )
{
erase ( index );
break;
}
}
sys_mutex_unlock(&mem_mutex);
}
#endif
EXP_FUNC void * ax_malloc(size_t s, const char* file, int line)
{
void *x;
if ((x = malloc(s)) == NULL)
exit_now("out of memory %s %d\n", file, line);
else {
debug_now("%s %d point[%p] size[%d] heap[%d]\n", file, line, x, s, esp_get_free_heap_size());
//add_mem_info(x, s, file, line);
}
return x;
}
EXP_FUNC void * ax_realloc(void *y, size_t s, const char* file, int line)
{
void *x;
if ((x = realloc(y, s)) == NULL)
exit_now("out of memory %s %d\n", file, line);
else {
debug_now("%s %d point[%p] size[%d] heap[%d]\n", file, line, x, s, esp_get_free_heap_size());
//add_mem_info(x, s, file, line);
}
return x;
}
EXP_FUNC void * ax_calloc(size_t n, size_t s, const char* file, int line)
{
void *x;
//unsigned total_size =0;
if ((x = calloc(n, s)) == NULL)
exit_now("out of memory %s %d\n", file, line);
else {
debug_now("%s %d point[%p] size[%d] heap[%d]\n", file, line, x, s, esp_get_free_heap_size());
//total_size = n * s;
//add_mem_info (x, total_size, file, line);
}
return x;
}
EXP_FUNC void * ax_zalloc(size_t s, const char* file, int line)
{
void *x;
if ((x = (void*)zalloc(s)) == NULL)
exit_now("out of memory %s %d\n", file, line);
else {
debug_now("%s %d point[%p] size[%d] heap[%d]\n", file, line, x, s, esp_get_free_heap_size());
//add_mem_info(x, s, file, line);
}
return x;
}
EXP_FUNC void ax_free(void *p, const char* file, int line)
{
if(p) {
debug_now("%s %d point[%p] size[%d] heap[%d]\n", file, line, p,0, esp_get_free_heap_size());
free(p);
p = NULL;
}
return ;
}
#if 0
void report_mem_leak(void)
{
unsigned short index;
MEM_LEAK * leak_info;
char *info;
sys_mutex_lock(&mem_mutex);
printf("ptr_start =%p\n",ptr_start);
info = (char *)zalloc(name_length);
if(info) {
for(leak_info = ptr_start; leak_info != NULL; leak_info = leak_info->next)
{
printf("%p\n",leak_info);
sprintf(info, "address : %p\n", leak_info->mem_info.address);
printf("%s\n",info);
sprintf(info, "size : %d bytes\n", leak_info->mem_info.size);
printf("%s\n",info);
snprintf(info,name_length,"file : %s\n", leak_info->mem_info.file_name);
printf("%s\n",info);
sprintf(info, "line : %d\n", leak_info->mem_info.line);
printf("%s\n",info);
}
clear();
free(info);
}
sys_mutex_unlock(&mem_mutex);
sys_mutex_free(&mem_mutex);
}
/*
void exit_now(const char *format, ...)
{
va_list argp;
va_start(argp, format);
vfprintf(stderr, format, argp);
va_end(argp);
abort();
}*/
/**
* gettimeofday() not in Win32
*/
#if 0
EXP_FUNC void STDCALL gettimeofday(struct timeval* t, void* timezone)
{
#if defined(_WIN32_WCE)
t->tv_sec = time(NULL);
t->tv_usec = 0; /* 1sec precision only */
#else
/* wujg : pass compile first */
if (timezone != NULL)
t->tv_sec = *(time_t*)timezone + system_get_time()/1000000;
else
t->tv_sec = system_get_time() + system_get_time()/1000000;
t->tv_usec = 0; /* 1ms precision */
#endif
}
#endif
#endif
unsigned int def_private_key_len = 0;
unsigned char *def_private_key = NULL;
unsigned char *def_certificate = NULL;
unsigned int def_certificate_len = 0;

View File

@ -1,480 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Process PKCS#8/PKCS#12 keys.
*
* The decoding of a PKCS#12 key is fairly specific - this code was tested on a
* key generated with:
*
* openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem
* -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128
* -name "p12_withoutCA" -out axTLS.withoutCA.p12 -password pass:abcd
*
* or with a certificate chain:
*
* openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem
* -certfile axTLS.ca_x509.pem -keypbe PBE-SHA1-RC4-128 -certpbe
* PBE-SHA1-RC4-128 -name "p12_withCA" -out axTLS.withCA.p12 -password pass:abcd
*
* Note that the PBE has to be specified with PBE-SHA1-RC4-128. The
* private/public keys/certs have to use RSA encryption. Both the integrity
* and privacy passwords are the same.
*
* The PKCS#8 files were generated with something like:
*
* PEM format:
* openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -v1
* PBE-SHA1-RC4-128 -out axTLS.encrypted_pem.p8
*
* DER format:
* openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -outform DER
* -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted.p8
*/
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_ssl.h"
/* all commented out if not used */
#ifdef CONFIG_SSL_USE_PKCS12
#define BLOCK_SIZE 64
#define PKCS12_KEY_ID 1
#define PKCS12_IV_ID 2
#define PKCS12_MAC_ID 3
static char *make_uni_pass(const char *password, int *uni_pass_len);
static int p8_decrypt(const char *uni_pass, int uni_pass_len,
const uint8_t *salt, int iter,
uint8_t *priv_key, int priv_key_len, int id);
static int p8_add_key(SSL_CTX *ssl_ctx, uint8_t *priv_key);
static int get_pbe_params(uint8_t *buf, int *offset,
const uint8_t **salt, int *iterations);
/*
* Take a raw pkcs8 block and then decrypt it and turn it into a normal key.
*/
int pkcs8_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password)
{
uint8_t *buf = ssl_obj->buf;
int len, offset = 0;
int iterations;
int ret = SSL_NOT_OK;
uint8_t *version = NULL;
const uint8_t *salt;
uint8_t *priv_key;
int uni_pass_len;
char *uni_pass = make_uni_pass(password, &uni_pass_len);
if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0)
{
#ifdef CONFIG_SSL_FULL_MODE
ssl_printf("Error: Invalid p8 ASN.1 file\n");
#endif
goto error;
}
/* unencrypted key? */
if (asn1_get_int(buf, &offset, &version) > 0 && *version == 0)
{
ret = p8_add_key(ssl_ctx, buf);
goto error;
}
if (get_pbe_params(buf, &offset, &salt, &iterations) < 0)
goto error;
if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0)
goto error;
priv_key = &buf[offset];
p8_decrypt(uni_pass, uni_pass_len, salt,
iterations, priv_key, len, PKCS12_KEY_ID);
ret = p8_add_key(ssl_ctx, priv_key);
error:
SSL_FREE(version);
SSL_FREE(uni_pass);
return ret;
}
/*
* Take the unencrypted pkcs8 and turn it into a private key
*/
static int p8_add_key(SSL_CTX *ssl_ctx, uint8_t *priv_key)
{
uint8_t *buf = priv_key;
int len, offset = 0;
int ret = SSL_NOT_OK;
/* Skip the preamble and go straight to the private key.
We only support rsaEncryption (1.2.840.113549.1.1.1) */
if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
asn1_skip_obj(buf, &offset, ASN1_INTEGER) < 0 ||
asn1_skip_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
(len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0)
goto error;
ret = asn1_get_private_key(&buf[offset], len, &ssl_ctx->rsa_ctx);
error:
return ret;
}
/*
* Create the unicode password
*/
static char * make_uni_pass(const char *password, int *uni_pass_len)
{
int pass_len = 0, i;
char *uni_pass;
if (password == NULL)
{
password = "";
}
uni_pass = (char *)SSL_MALLOC((strlen(password)+1)*2);
/* modify the password into a unicode version */
for (i = 0; i < (int)strlen(password); i++)
{
uni_pass[pass_len++] = 0;
uni_pass[pass_len++] = password[i];
}
uni_pass[pass_len++] = 0; /* null terminate */
uni_pass[pass_len++] = 0;
*uni_pass_len = pass_len;
return uni_pass;
}
/*
* Decrypt a pkcs8 block.
*/
static int p8_decrypt(const char *uni_pass, int uni_pass_len,
const uint8_t *salt, int iter,
uint8_t *priv_key, int priv_key_len, int id)
{
uint8_t p[BLOCK_SIZE*2];
uint8_t d[BLOCK_SIZE];
uint8_t Ai[SHA1_SIZE];
SHA1_CTX sha_ctx;
RC4_CTX rc4_ctx;
int i;
for (i = 0; i < BLOCK_SIZE; i++)
{
p[i] = salt[i % SALT_SIZE];
p[BLOCK_SIZE+i] = uni_pass[i % uni_pass_len];
d[i] = id;
}
/* get the key - no IV since we are using RC4 */
SHA1_Init(&sha_ctx);
SHA1_Update(&sha_ctx, d, sizeof(d));
SHA1_Update(&sha_ctx, p, sizeof(p));
SHA1_Final(Ai, &sha_ctx);
for (i = 1; i < iter; i++)
{
SHA1_Init(&sha_ctx);
SHA1_Update(&sha_ctx, Ai, SHA1_SIZE);
SHA1_Final(Ai, &sha_ctx);
}
/* do the decryption */
if (id == PKCS12_KEY_ID)
{
RC4_setup(&rc4_ctx, Ai, 16);
RC4_crypt(&rc4_ctx, priv_key, priv_key, priv_key_len);
}
else /* MAC */
memcpy(priv_key, Ai, SHA1_SIZE);
return 0;
}
/*
* Take a raw pkcs12 block and the decrypt it and turn it into a certificate(s)
* and keys.
*/
int pkcs12_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password)
{
uint8_t *buf = ssl_obj->buf;
int len, iterations, auth_safes_start,
auth_safes_end, auth_safes_len, key_offset, offset = 0;
int all_certs = 0;
uint8_t *version = NULL, *auth_safes = NULL, *cert, *orig_mac;
uint8_t key[SHA1_SIZE];
uint8_t mac[SHA1_SIZE];
const uint8_t *salt;
int uni_pass_len, ret = SSL_OK;
char *uni_pass = make_uni_pass(password, &uni_pass_len);
static const uint8_t pkcs_data[] = /* pkc7 data */
{ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01 };
static const uint8_t pkcs_encrypted[] = /* pkc7 encrypted */
{ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06 };
static const uint8_t pkcs8_key_bag[] = /* 1.2.840.113549.1.12.10.1.2 */
{ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02 };
if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0)
{
#ifdef CONFIG_SSL_FULL_MODE
ssl_printf("Error: Invalid p12 ASN.1 file\n");
#endif
goto error;
}
if (asn1_get_int(buf, &offset, &version) < 0 || *version != 3)
{
ret = SSL_ERROR_INVALID_VERSION;
goto error;
}
/* remove all the boring pcks7 bits */
if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
(len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
len != sizeof(pkcs_data) ||
memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data)))
goto error;
offset += len;
if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0)
goto error;
/* work out the MAC start/end points (done on AuthSafes) */
auth_safes_start = offset;
auth_safes_end = offset;
if (asn1_skip_obj(buf, &auth_safes_end, ASN1_SEQUENCE) < 0)
goto error;
auth_safes_len = auth_safes_end - auth_safes_start;
auth_safes = SSL_MALLOC(auth_safes_len);
memcpy(auth_safes, &buf[auth_safes_start], auth_safes_len);
if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
(len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
(len != sizeof(pkcs_encrypted) ||
memcmp(&buf[offset], pkcs_encrypted, sizeof(pkcs_encrypted))))
goto error;
offset += len;
if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
asn1_skip_obj(buf, &offset, ASN1_INTEGER) < 0 ||
asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
(len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
len != sizeof(pkcs_data) ||
memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data)))
goto error;
offset += len;
/* work out the salt for the certificate */
if (get_pbe_params(buf, &offset, &salt, &iterations) < 0 ||
(len = asn1_next_obj(buf, &offset, ASN1_IMPLICIT_TAG)) < 0)
goto error;
/* decrypt the certificate */
cert = &buf[offset];
if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert,
len, PKCS12_KEY_ID)) < 0)
goto error;
offset += len;
/* load the certificate */
key_offset = 0;
all_certs = asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE);
/* keep going until all certs are loaded */
while (key_offset < all_certs)
{
int cert_offset = key_offset;
if (asn1_skip_obj(cert, &cert_offset, ASN1_SEQUENCE) < 0 ||
asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE) < 0 ||
asn1_skip_obj(cert, &key_offset, ASN1_OID) < 0 ||
asn1_next_obj(cert, &key_offset, ASN1_EXPLICIT_TAG) < 0 ||
asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE) < 0 ||
asn1_skip_obj(cert, &key_offset, ASN1_OID) < 0 ||
asn1_next_obj(cert, &key_offset, ASN1_EXPLICIT_TAG) < 0 ||
(len = asn1_next_obj(cert, &key_offset, ASN1_OCTET_STRING)) < 0)
goto error;
if ((ret = add_cert(ssl_ctx, &cert[key_offset], len)) < 0)
goto error;
key_offset = cert_offset;
}
if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
(len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
len != sizeof(pkcs_data) ||
memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data)))
goto error;
offset += len;
if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0 ||
asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
(len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
(len != sizeof(pkcs8_key_bag)) ||
memcmp(&buf[offset], pkcs8_key_bag, sizeof(pkcs8_key_bag)))
goto error;
offset += len;
/* work out the salt for the private key */
if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
get_pbe_params(buf, &offset, &salt, &iterations) < 0 ||
(len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0)
goto error;
/* decrypt the private key */
cert = &buf[offset];
if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert,
len, PKCS12_KEY_ID)) < 0)
goto error;
offset += len;
/* load the private key */
if ((ret = p8_add_key(ssl_ctx, cert)) < 0)
goto error;
/* miss out on friendly name, local key id etc */
if (asn1_skip_obj(buf, &offset, ASN1_SET) < 0)
goto error;
/* work out the MAC */
if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
asn1_skip_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
(len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 ||
len != SHA1_SIZE)
goto error;
orig_mac = &buf[offset];
offset += len;
/* get the salt */
if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 || len != 8)
goto error;
salt = &buf[offset];
/* work out what the mac should be */
if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations,
key, SHA1_SIZE, PKCS12_MAC_ID)) < 0)
goto error;
ssl_hmac_sha1(auth_safes, auth_safes_len, key, SHA1_SIZE, mac);
if (memcmp(mac, orig_mac, SHA1_SIZE))
{
ret = SSL_ERROR_INVALID_HMAC;
goto error;
}
error:
SSL_FREE(version);
SSL_FREE(uni_pass);
SSL_FREE(auth_safes);
return ret;
}
/*
* Retrieve the salt/iteration details from a PBE block.
*/
static int get_pbe_params(uint8_t *buf, int *offset,
const uint8_t **salt, int *iterations)
{
static const uint8_t pbeSH1RC4[] = /* pbeWithSHAAnd128BitRC4 */
{ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01 };
int i, len;
uint8_t *iter = NULL;
int error_code = SSL_ERROR_NOT_SUPPORTED;
/* Get the PBE type */
if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 ||
(len = asn1_next_obj(buf, offset, ASN1_OID)) < 0)
goto error;
/* we expect pbeWithSHAAnd128BitRC4 (1.2.840.113549.1.12.1.1)
which is the only algorithm we support */
if (len != sizeof(pbeSH1RC4) ||
memcmp(&buf[*offset], pbeSH1RC4, sizeof(pbeSH1RC4)))
{
#ifdef CONFIG_SSL_FULL_MODE
ssl_printf("Error: pkcs8/pkcs12 must use \"PBE-SHA1-RC4-128\"\n");
#endif
goto error;
}
*offset += len;
if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 ||
(len = asn1_next_obj(buf, offset, ASN1_OCTET_STRING)) < 0 ||
len != 8)
goto error;
*salt = &buf[*offset];
*offset += len;
if ((len = asn1_get_int(buf, offset, &iter)) < 0)
goto error;
*iterations = 0;
for (i = 0; i < len; i++)
{
(*iterations) <<= 8;
(*iterations) += iter[i];
}
SSL_FREE(iter);
error_code = SSL_OK; /* got here - we are ok */
error:
return error_code;
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,397 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_ssl.h"
//#include "lwip/tcp.h"
#ifdef CONFIG_SSL_ENABLE_CLIENT /* all commented out if no client */
static int send_client_hello(SSL *ssl);
static int process_server_hello(SSL *ssl);
static int process_server_hello_done(SSL *ssl);
static int send_client_key_xchg(SSL *ssl);
static int process_cert_req(SSL *ssl);
static int send_cert_verify(SSL *ssl);
/*
* Establish a new SSL connection to an SSL server.
*/
EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const
uint8_t *session_id, uint8_t sess_id_size)
{
SSL *ssl = ssl_new(ssl_ctx, client_fd);
ssl->version = SSL_PROTOCOL_VERSION_MAX; /* try top version first */
if (session_id && ssl_ctx->num_sessions)
{
if (sess_id_size > SSL_SESSION_ID_SIZE) /* validity check */
{
ssl_free(ssl);
return NULL;
}
memcpy(ssl->session_id, session_id, sess_id_size);
ssl->sess_id_size = sess_id_size;
SET_SSL_FLAG(SSL_SESSION_RESUME); /* just flag for later */
}
SET_SSL_FLAG(SSL_IS_CLIENT);
do_client_connect(ssl);
return ssl;
}
/*
* Process the handshake record.
*/
int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len)
{
int ret;
/* To get here the state must be valid */
// ssl_printf("do_clnt_handshake: %d %d\n",__LINE__, handshake_type);
switch (handshake_type)
{
case HS_SERVER_HELLO:
ret = process_server_hello(ssl);
break;
case HS_CERTIFICATE:
ret = process_certificate(ssl, &ssl->x509_ctx);
break;
case HS_SERVER_HELLO_DONE:
if ((ret = process_server_hello_done(ssl)) == SSL_OK)
{
if (IS_SET_SSL_FLAG(SSL_HAS_CERT_REQ))
{
if ((ret = send_certificate(ssl)) == SSL_OK &&
(ret = send_client_key_xchg(ssl)) == SSL_OK)
{
send_cert_verify(ssl);
}
}
else
{
ret = send_client_key_xchg(ssl);
}
if (ret == SSL_OK &&
(ret = send_change_cipher_spec(ssl)) == SSL_OK)
{
ret = send_finished(ssl);
}
}
break;
case HS_CERT_REQ:
ret = process_cert_req(ssl);
break;
case HS_FINISHED:
ret = process_finished(ssl, buf, hs_len);
disposable_free(ssl); /* free up some memory */
/* note: client renegotiation is not allowed after this */
break;
case HS_HELLO_REQUEST:
disposable_new(ssl);
ret = do_client_connect(ssl);
break;
default:
ret = SSL_ERROR_INVALID_HANDSHAKE;
break;
}
return ret;
}
/*
* Do the handshaking from the beginning.
*/
int do_client_connect(SSL *ssl)
{
int ret = SSL_OK;
send_client_hello(ssl); /* send the client hello */
ssl->bm_read_index = 0;
ssl->next_state = HS_SERVER_HELLO;
ssl->hs_status = SSL_NOT_OK; /* not connected */
/* sit in a loop until it all looks good */
if (!IS_SET_SSL_FLAG(SSL_CONNECT_IN_PARTS))
{
while (ssl->hs_status != SSL_OK)
{
// esp_ssl_sleep(100);
ret = ssl_read(ssl, NULL);
ssl_printf("%s %d %d\n", __func__, __LINE__,ret);
if (ret < SSL_OK)
break;
}
ssl->hs_status = ret; /* connected? */
}
return ret;
}
/*
* Send the initial client hello.
*/
static int send_client_hello(SSL *ssl)
{
uint8_t *buf = ssl->bm_data;
time_t tm = 0; //time(NULL); wujg : pass compile first
uint8_t *tm_ptr = &buf[6]; /* time will go here */
int i, offset;
buf[0] = HS_CLIENT_HELLO;
buf[1] = 0;
buf[2] = 0;
/* byte 3 is calculated later */
buf[4] = 0x03;
buf[5] = ssl->version & 0x0f;
/* client random value - spec says that 1st 4 bytes are big endian time */
*tm_ptr++ = (uint8_t)(((long)tm & 0xff000000) >> 24);
*tm_ptr++ = (uint8_t)(((long)tm & 0x00ff0000) >> 16);
*tm_ptr++ = (uint8_t)(((long)tm & 0x0000ff00) >> 8);
*tm_ptr++ = (uint8_t)(((long)tm & 0x000000ff));
if (get_random(SSL_RANDOM_SIZE-4, &buf[10]) < 0)
return SSL_NOT_OK;
memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE);
offset = 6 + SSL_RANDOM_SIZE;
/* give session resumption a go */
if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME)) /* set initially by user */
{
buf[offset++] = ssl->sess_id_size;
memcpy(&buf[offset], ssl->session_id, ssl->sess_id_size);
offset += ssl->sess_id_size;
CLR_SSL_FLAG(SSL_SESSION_RESUME); /* clear so we can set later */
}
else
{
/* no session id - because no session resumption just yet */
buf[offset++] = 0;
}
buf[offset++] = 0; /* number of ciphers */
buf[offset++] = NUM_PROTOCOLS*2;/* number of ciphers */
/* put all our supported protocols in our request */
for (i = 0; i < NUM_PROTOCOLS; i++)
{
buf[offset++] = 0; /* cipher we are using */
buf[offset++] = system_get_data_of_array_8(ssl_prot_prefs, i);
}
buf[offset++] = 1; /* no compression */
buf[offset++] = 0;
buf[3] = offset - 4; /* handshake size */
return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
}
/*
* Process the server hello.
*/
static int process_server_hello(SSL *ssl)
{
uint8_t *buf = ssl->bm_data;
int pkt_size = ssl->bm_index;
int num_sessions = ssl->ssl_ctx->num_sessions;
uint8_t sess_id_size;
int offset, ret = SSL_OK;
/* check that we are talking to a TLSv1 server */
uint8_t version = (buf[4] << 4) + buf[5];
if (version > SSL_PROTOCOL_VERSION_MAX)
{
version = SSL_PROTOCOL_VERSION_MAX;
}
else if (ssl->version < SSL_PROTOCOL_MIN_VERSION)
{
ret = SSL_ERROR_INVALID_VERSION;
//ssl_display_error(ret);
goto error;
}
ssl->version = version;
/* get the server random value */
memcpy(ssl->dc->server_random, &buf[6], SSL_RANDOM_SIZE);
offset = 6 + SSL_RANDOM_SIZE; /* skip of session id size */
sess_id_size = buf[offset++];
if (sess_id_size > SSL_SESSION_ID_SIZE)
{
ret = SSL_ERROR_INVALID_SESSION;
goto error;
}
if (num_sessions)
{
ssl->session = ssl_session_update(num_sessions,
ssl->ssl_ctx->ssl_sessions, ssl, &buf[offset]);
memcpy(ssl->session->session_id, &buf[offset], sess_id_size);
/* pad the rest with 0's */
if (sess_id_size < SSL_SESSION_ID_SIZE)
{
memset(&ssl->session->session_id[sess_id_size], 0,
SSL_SESSION_ID_SIZE-sess_id_size);
}
}
memcpy(ssl->session_id, &buf[offset], sess_id_size);
ssl->sess_id_size = sess_id_size;
offset += sess_id_size;
/* get the real cipher we are using */
ssl->cipher = buf[++offset];
ssl->next_state = IS_SET_SSL_FLAG(SSL_SESSION_RESUME) ?
HS_FINISHED : HS_CERTIFICATE;
offset++; // skip the compr
PARANOIA_CHECK(pkt_size, offset);
ssl->dc->bm_proc_index = offset+1;
error:
return ret;
}
/**
* Process the server hello done message.
*/
static int process_server_hello_done(SSL *ssl)
{
ssl->next_state = HS_FINISHED;
return SSL_OK;
}
/*
* Send a client key exchange message.
*/
static int send_client_key_xchg(SSL *ssl)
{
uint8_t *buf = ssl->bm_data;
uint8_t premaster_secret[SSL_SECRET_SIZE];
int enc_secret_size = -1;
buf[0] = HS_CLIENT_KEY_XCHG;
buf[1] = 0;
premaster_secret[0] = 0x03; /* encode the version number */
premaster_secret[1] = SSL_PROTOCOL_MINOR_VERSION; /* must be TLS 1.1 */
if (get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]) < 0)
return SSL_NOT_OK;
//DISPLAY_RSA(ssl, ssl->x509_ctx->rsa_ctx);
/* rsa_ctx->bi_ctx is not thread-safe */
SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
enc_secret_size = RSA_encrypt(ssl->x509_ctx->rsa_ctx, premaster_secret,
SSL_SECRET_SIZE, &buf[6], 0);
SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
buf[2] = (enc_secret_size + 2) >> 8;
buf[3] = (enc_secret_size + 2) & 0xff;
buf[4] = enc_secret_size >> 8;
buf[5] = enc_secret_size & 0xff;
generate_master_secret(ssl, premaster_secret);
return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, enc_secret_size+6);
}
/*
* Process the certificate request.
*/
static int process_cert_req(SSL *ssl)
{
uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index];
int ret = SSL_OK;
int offset = (buf[2] << 4) + buf[3];
int pkt_size = ssl->bm_index;
/* don't do any processing - we will send back an RSA certificate anyway */
ssl->next_state = HS_SERVER_HELLO_DONE;
SET_SSL_FLAG(SSL_HAS_CERT_REQ);
ssl->dc->bm_proc_index += offset;
PARANOIA_CHECK(pkt_size, offset);
error:
return ret;
}
/*
* Send a certificate verify message.
*/
static int send_cert_verify(SSL *ssl)
{
uint8_t *buf = ssl->bm_data;
uint8_t dgst[MD5_SIZE+SHA1_SIZE];
RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx;
int n = 0, ret;
//DISPLAY_RSA(ssl, rsa_ctx);
buf[0] = HS_CERT_VERIFY;
buf[1] = 0;
finished_digest(ssl, NULL, dgst); /* calculate the digest */
/* rsa_ctx->bi_ctx is not thread-safe */
if (rsa_ctx)
{
SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
n = RSA_encrypt(rsa_ctx, dgst, sizeof(dgst), &buf[6], 1);
SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
if (n == 0)
{
ret = SSL_ERROR_INVALID_KEY;
goto error;
}
}
buf[4] = n >> 8; /* add the RSA size (not officially documented) */
buf[5] = n & 0xff;
n += 2;
buf[2] = n >> 8;
buf[3] = n & 0xff;
ret = send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, n+4);
error:
return ret;
}
#endif /* CONFIG_SSL_ENABLE_CLIENT */

View File

@ -1,492 +0,0 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_ssl.h"
static const uint8_t g_hello_done[] = { HS_SERVER_HELLO_DONE, 0, 0, 0 };
static int process_client_hello(SSL *ssl);
static int send_server_hello_sequence(SSL *ssl);
static int send_server_hello(SSL *ssl);
static int send_server_hello_done(SSL *ssl);
static int process_client_key_xchg(SSL *ssl);
#ifdef CONFIG_SSL_CERT_VERIFICATION
static int send_certificate_request(SSL *ssl);
static int process_cert_verify(SSL *ssl);
#endif
/*
* Establish a new SSL connection to an SSL client.
*/
EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd)
{
SSL *ssl;
ssl = ssl_new(ssl_ctx, client_fd);
ssl->next_state = HS_CLIENT_HELLO;
#ifdef CONFIG_SSL_FULL_MODE
if (ssl_ctx->chain_length == 0) {
ssl_printf("Warning - no server certificate defined\n"); //TTY_FLUSH();
}
#endif
return ssl;
}
/*
* Process the handshake record.
*/
int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len)
{
int ret = SSL_OK;
ssl->hs_status = SSL_NOT_OK; /* not connected */
/* To get here the state must be valid */
// ssl_printf("%d %s %d\n",handshake_type, __func__, __LINE__);
switch (handshake_type)
{
case HS_CLIENT_HELLO:
if ((ret = process_client_hello(ssl)) == SSL_OK)
ret = send_server_hello_sequence(ssl);
break;
#ifdef CONFIG_SSL_CERT_VERIFICATION
case HS_CERTIFICATE:/* the client sends its cert */
ret = process_certificate(ssl, &ssl->x509_ctx);
if (ret == SSL_OK) /* verify the cert */
{
int cert_res;
cert_res = x509_verify(
ssl->ssl_ctx->ca_cert_ctx, ssl->x509_ctx);
ret = (cert_res == 0) ? SSL_OK : SSL_X509_ERROR(cert_res);
}
break;
case HS_CERT_VERIFY:
ret = process_cert_verify(ssl);
add_packet(ssl, buf, hs_len); /* needs to be done after */
break;
#endif
case HS_CLIENT_KEY_XCHG:
ret = process_client_key_xchg(ssl);
break;
case HS_FINISHED:
ret = process_finished(ssl, buf, hs_len);
disposable_free(ssl); /* free up some memory */
break;
}
return ret;
}
/*
* Process a client hello message.
*/
static int process_client_hello(SSL *ssl)
{
uint8_t *buf = ssl->bm_data;
int pkt_size = ssl->bm_index;
int i, j, cs_len, id_len, offset = 6 + SSL_RANDOM_SIZE;
int ret = SSL_OK;
uint8_t version = (buf[4] << 4) + buf[5];
ssl->version = ssl->client_version = version;
if (version > SSL_PROTOCOL_VERSION_MAX)
{
/* use client's version instead */
ssl->version = SSL_PROTOCOL_VERSION_MAX;
}
else if (version < SSL_PROTOCOL_MIN_VERSION) /* old version supported? */
{
ret = SSL_ERROR_INVALID_VERSION;
//ssl_display_error(ret);
goto error;
}
memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE);
/* process the session id */
id_len = buf[offset++];
if (id_len > SSL_SESSION_ID_SIZE)
{
return SSL_ERROR_INVALID_SESSION;
}
#ifndef CONFIG_SSL_SKELETON_MODE
ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions,
ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL);
#endif
offset += id_len;
cs_len = (buf[offset]<<8) + buf[offset+1];
offset += 3; /* add 1 due to all cipher suites being 8 bit */
PARANOIA_CHECK(pkt_size, offset);
/* work out what cipher suite we are going to use - client defines
the preference */
for (i = 0; i < cs_len; i += 2)
{
for (j = 0; j < NUM_PROTOCOLS; j++)
{
if (system_get_data_of_array_8(ssl_prot_prefs, j) == ((buf[offset+i]<<8) + buf[offset+i+1])) /* got a match? */
{
ssl->cipher = system_get_data_of_array_8(ssl_prot_prefs, j);
goto do_state;
}
}
}
/* ouch! protocol is not supported */
ret = SSL_ERROR_NO_CIPHER;
do_state:
error:
return ret;
}
#ifdef CONFIG_SSL_ENABLE_V23_HANDSHAKE
/*
* Some browsers use a hybrid SSLv2 "client hello"
*/
int process_sslv23_client_hello(SSL *ssl)
{
uint8_t *buf = ssl->bm_data;
int bytes_needed = ((buf[0] & 0x7f) << 8) + buf[1];
int ret = SSL_OK;
/* we have already read 3 extra bytes so far */
int read_len = SOCKET_READ(ssl->client_fd, buf, bytes_needed-3);
int cs_len = buf[1];
int id_len = buf[3];
int ch_len = buf[5];
int i, j, offset = 8; /* start at first cipher */
int random_offset = 0;
DISPLAY_BYTES(ssl, "received %d bytes", buf, read_len, read_len);
/* connection has gone, so die */
if (read_len < 0)
{
return SSL_ERROR_CONN_LOST;
}
add_packet(ssl, buf, read_len);
/* now work out what cipher suite we are going to use */
for (j = 0; j < NUM_PROTOCOLS; j++)
{
for (i = 0; i < cs_len; i += 3)
{
if (ssl_prot_prefs[j] == buf[offset+i])
{
ssl->cipher = ssl_prot_prefs[j];
goto server_hello;
}
}
}
/* ouch! protocol is not supported */
ret = SSL_ERROR_NO_CIPHER;
goto error;
server_hello:
/* get the session id */
offset += cs_len - 2; /* we've gone 2 bytes past the end */
#ifndef CONFIG_SSL_SKELETON_MODE
ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions,
ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL);
#endif
/* get the client random data */
offset += id_len;
/* random can be anywhere between 16 and 32 bytes long - so it is padded
* with 0's to the left */
if (ch_len == 0x10)
{
random_offset += 0x10;
}
memcpy(&ssl->dc->client_random[random_offset], &buf[offset], ch_len);
ret = send_server_hello_sequence(ssl);
error:
return ret;
}
#endif
/*
* Send the entire server hello sequence
*/
static int send_server_hello_sequence(SSL *ssl)
{
int ret;
if ((ret = send_server_hello(ssl)) == SSL_OK)
{
#ifndef CONFIG_SSL_SKELETON_MODE
/* resume handshake? */
if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME))
{
if ((ret = send_change_cipher_spec(ssl)) == SSL_OK)
{
ret = send_finished(ssl);
ssl->next_state = HS_FINISHED;
}
}
else
#endif
if ((ret = send_certificate(ssl)) == SSL_OK)
{
#ifdef CONFIG_SSL_CERT_VERIFICATION
/* ask the client for its certificate */
if (IS_SET_SSL_FLAG(SSL_CLIENT_AUTHENTICATION))
{
if ((ret = send_certificate_request(ssl)) == SSL_OK)
{
ret = send_server_hello_done(ssl);
ssl->next_state = HS_CERTIFICATE;
}
}
else
#endif
{
ret = send_server_hello_done(ssl);
ssl->next_state = HS_CLIENT_KEY_XCHG;
}
}
}
return ret;
}
/*
* Send a server hello message.
*/
static int send_server_hello(SSL *ssl)
{
uint8_t *buf = ssl->bm_data;
int offset = 0;
buf[0] = HS_SERVER_HELLO;
buf[1] = 0;
buf[2] = 0;
/* byte 3 is calculated later */
buf[4] = 0x03;
buf[5] = ssl->version & 0x0f;
/* server random value */
if (get_random(SSL_RANDOM_SIZE, &buf[6]) < 0)
return SSL_NOT_OK;
memcpy(ssl->dc->server_random, &buf[6], SSL_RANDOM_SIZE);
offset = 6 + SSL_RANDOM_SIZE;
#ifndef CONFIG_SSL_SKELETON_MODE
if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME))
{
/* retrieve id from session cache */
buf[offset++] = SSL_SESSION_ID_SIZE;
memcpy(&buf[offset], ssl->session->session_id, SSL_SESSION_ID_SIZE);
memcpy(ssl->session_id, ssl->session->session_id, SSL_SESSION_ID_SIZE);
ssl->sess_id_size = SSL_SESSION_ID_SIZE;
offset += SSL_SESSION_ID_SIZE;
}
else /* generate our own session id */
#endif
{
#ifndef CONFIG_SSL_SKELETON_MODE
buf[offset++] = SSL_SESSION_ID_SIZE;
get_random(SSL_SESSION_ID_SIZE, &buf[offset]);
memcpy(ssl->session_id, &buf[offset], SSL_SESSION_ID_SIZE);
ssl->sess_id_size = SSL_SESSION_ID_SIZE;
/* store id in session cache */
if (ssl->ssl_ctx->num_sessions)
{
memcpy(ssl->session->session_id,
ssl->session_id, SSL_SESSION_ID_SIZE);
}
offset += SSL_SESSION_ID_SIZE;
#else
buf[offset++] = 0; /* don't bother with session id in skelton mode */
#endif
}
buf[offset++] = 0; /* cipher we are using */
buf[offset++] = ssl->cipher;
buf[offset++] = 0; /* no compression */
buf[3] = offset - 4; /* handshake size */
return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset);
}
/*
* Send the server hello done message.
*/
static int send_server_hello_done(SSL *ssl)
{
uint8_t g_hello_done_ram[4];
memcpy(g_hello_done_ram, g_hello_done, sizeof(g_hello_done));
return send_packet(ssl, PT_HANDSHAKE_PROTOCOL,
g_hello_done_ram, sizeof(g_hello_done));
}
/*
* Pull apart a client key exchange message. Decrypt the pre-master key (using
* our RSA private key) and then work out the master key. Initialise the
* ciphers.
*/
static int process_client_key_xchg(SSL *ssl)
{
uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index];
int pkt_size = ssl->bm_index;
int premaster_size, secret_length = (buf[2] << 8) + buf[3];
// uint8_t premaster_secret[MAX_KEY_BYTE_SIZE];
uint8_t* premaster_secret = (uint8_t*)SSL_ZALLOC(MAX_KEY_BYTE_SIZE);
RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx;
int offset = 4;
int ret = SSL_OK;
if (rsa_ctx == NULL)
{
ret = SSL_ERROR_NO_CERT_DEFINED;
goto error;
}
/* is there an extra size field? */
if ((secret_length - 2) == rsa_ctx->num_octets)
offset += 2;
PARANOIA_CHECK(pkt_size, rsa_ctx->num_octets+offset);
/* rsa_ctx->bi_ctx is not thread-safe */
SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
premaster_size = RSA_decrypt(rsa_ctx, &buf[offset], premaster_secret,
MAX_KEY_BYTE_SIZE, 1);
SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
if (premaster_size != SSL_SECRET_SIZE ||
premaster_secret[0] != 0x03 || /* must be the same as client
offered version */
premaster_secret[1] != (ssl->client_version & 0x0f))
{
/* guard against a Bleichenbacher attack */
if (get_random(SSL_SECRET_SIZE, premaster_secret) < 0)
return SSL_NOT_OK;
/* and continue - will die eventually when checking the mac */
}
#if 0
print_blob("pre-master", premaster_secret, SSL_SECRET_SIZE);
#endif
generate_master_secret(ssl, premaster_secret);
#ifdef CONFIG_SSL_CERT_VERIFICATION
ssl->next_state = IS_SET_SSL_FLAG(SSL_CLIENT_AUTHENTICATION) ?
HS_CERT_VERIFY : HS_FINISHED;
#else
ssl->next_state = HS_FINISHED;
#endif
ssl->dc->bm_proc_index += rsa_ctx->num_octets+offset;
error:
SSL_FREE(premaster_secret);
return ret;
}
#ifdef CONFIG_SSL_CERT_VERIFICATION
static const uint8_t g_cert_request[] = { HS_CERT_REQ, 0, 0, 4, 1, 0, 0, 0 };
/*
* Send the certificate request message.
*/
static int send_certificate_request(SSL *ssl)
{
uint8_t g_cert_request_ram[8];
memcpy(g_cert_request_ram, g_cert_request, sizeof(g_cert_request));
return send_packet(ssl, PT_HANDSHAKE_PROTOCOL,
g_cert_request_ram, sizeof(g_cert_request));
}
/*
* Ensure the client has the private key by first decrypting the packet and
* then checking the packet digests.
*/
static int process_cert_verify(SSL *ssl)
{
uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index];
int pkt_size = ssl->bm_index;
// uint8_t dgst_buf[MAX_KEY_BYTE_SIZE];
uint8_t* dgst_buf = (uint8_t*)SSL_ZALLOC(MAX_KEY_BYTE_SIZE);
uint8_t dgst[MD5_SIZE+SHA1_SIZE];
X509_CTX *x509_ctx = ssl->x509_ctx;
int ret = SSL_OK;
int n;
PARANOIA_CHECK(pkt_size, x509_ctx->rsa_ctx->num_octets+6);
//DISPLAY_RSA(ssl, x509_ctx->rsa_ctx);
/* rsa_ctx->bi_ctx is not thread-safe */
SSL_CTX_LOCK(ssl->ssl_ctx->mutex);
n = RSA_decrypt(x509_ctx->rsa_ctx, &buf[6], dgst_buf, MAX_KEY_BYTE_SIZE, 0);
SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex);
if (n != SHA1_SIZE + MD5_SIZE)
{
ret = SSL_ERROR_INVALID_KEY;
goto end_cert_vfy;
}
finished_digest(ssl, NULL, dgst); /* calculate the digest */
if (memcmp(dgst_buf, dgst, MD5_SIZE + SHA1_SIZE))
{
ret = SSL_ERROR_INVALID_KEY;
}
end_cert_vfy:
ssl->next_state = HS_FINISHED;
error:
SSL_FREE(dgst_buf);
return ret;
}
#endif

View File

@ -1,617 +0,0 @@
/*
* Copyright (c) 2007-2015, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file x509.c
*
* Certificate processing.
*/
#include "ssl/ssl_os_port.h"
#include "ssl/ssl_ssl.h"
#include "ssl/ssl_crypto_misc.h"
#include "lwip/sockets.h"
#ifdef CONFIG_SSL_CERT_VERIFICATION
/**
* Retrieve the signature from a certificate.
*/
static const uint8_t * get_signature(const uint8_t *asn1_sig, int *len)
{
int offset = 0;
const uint8_t *ptr = NULL;
if (asn1_next_obj(asn1_sig, &offset, ASN1_SEQUENCE) < 0 ||
asn1_skip_obj(asn1_sig, &offset, ASN1_SEQUENCE))
goto end_get_sig;
if (asn1_sig[offset++] != ASN1_OCTET_STRING)
goto end_get_sig;
*len = get_asn1_length(asn1_sig, &offset);
ptr = &asn1_sig[offset]; /* all ok */
end_get_sig:
return ptr;
}
#endif
/**
* Construct a new x509 object.
* @return 0 if ok. < 0 if there was a problem.
*/
int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
{
int begin_tbs, end_tbs;
int ret = X509_NOT_OK, offset = 0, cert_size = 0;
X509_CTX *x509_ctx;
BI_CTX *bi_ctx;
*ctx = (X509_CTX *)SSL_ZALLOC(sizeof(X509_CTX));
x509_ctx = *ctx;
/* get the certificate size */
asn1_skip_obj(cert, &cert_size, ASN1_SEQUENCE);
if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
goto end_cert;
begin_tbs = offset; /* start of the tbs */
end_tbs = begin_tbs; /* work out the end of the tbs */
asn1_skip_obj(cert, &end_tbs, ASN1_SEQUENCE);
if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
goto end_cert;
if (cert[offset] == ASN1_EXPLICIT_TAG) /* optional version */
{
if (asn1_version(cert, &offset, x509_ctx))
goto end_cert;
}
if (asn1_skip_obj(cert, &offset, ASN1_INTEGER) || /* serial number */
asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
goto end_cert;
/* make sure the signature is ok */
if (asn1_signature_type(cert, &offset, x509_ctx))
{
ret = X509_VFY_ERROR_UNSUPPORTED_DIGEST;
goto end_cert;
}
if (asn1_name(cert, &offset, x509_ctx->ca_cert_dn) ||
asn1_validity(cert, &offset, x509_ctx) ||
asn1_name(cert, &offset, x509_ctx->cert_dn) ||
asn1_public_key(cert, &offset, x509_ctx))
{
goto end_cert;
}
bi_ctx = x509_ctx->rsa_ctx->bi_ctx;
#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
/* use the appropriate signature algorithm */
switch (x509_ctx->sig_type)
{
case SIG_TYPE_MD5:
{
MD5_CTX md5_ctx;
uint8_t md5_dgst[MD5_SIZE];
MD5_Init(&md5_ctx);
MD5_Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
MD5_Final(md5_dgst, &md5_ctx);
x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE);
}
break;
case SIG_TYPE_SHA1:
{
SHA1_CTX sha_ctx;
uint8_t sha_dgst[SHA1_SIZE];
SHA1_Init(&sha_ctx);
SHA1_Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
SHA1_Final(sha_dgst, &sha_ctx);
x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE);
}
break;
case SIG_TYPE_SHA256:
{
SHA256_CTX sha256_ctx;
uint8_t sha256_dgst[SHA256_SIZE];
SHA256_Init(&sha256_ctx);
SHA256_Update(&sha256_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
SHA256_Final(sha256_dgst, &sha256_ctx);
x509_ctx->digest = bi_import(bi_ctx, sha256_dgst, SHA256_SIZE);
}
break;
case SIG_TYPE_SHA384:
{
SHA384_CTX sha384_ctx;
uint8_t sha384_dgst[SHA384_SIZE];
SHA384_Init(&sha384_ctx);
SHA384_Update(&sha384_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
SHA384_Final(sha384_dgst, &sha384_ctx);
x509_ctx->digest = bi_import(bi_ctx, sha384_dgst, SHA384_SIZE);
}
break;
case SIG_TYPE_SHA512:
{
SHA512_CTX sha512_ctx;
uint8_t sha512_dgst[SHA512_SIZE];
SHA512_Init(&sha512_ctx);
SHA512_Update(&sha512_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
SHA512_Final(sha512_dgst, &sha512_ctx);
x509_ctx->digest = bi_import(bi_ctx, sha512_dgst, SHA512_SIZE);
}
break;
}
if (cert[offset] == ASN1_V3_DATA)
{
int suboffset;
++offset;
get_asn1_length(cert, &offset);
if ((suboffset = asn1_find_subjectaltname(cert, offset)) > 0)
{
if (asn1_next_obj(cert, &suboffset, ASN1_OCTET_STRING) > 0)
{
int altlen;
if ((altlen = asn1_next_obj(cert,
&suboffset, ASN1_SEQUENCE)) > 0)
{
int endalt = suboffset + altlen;
int totalnames = 0;
while (suboffset < endalt)
{
int type = cert[suboffset++];
int dnslen = get_asn1_length(cert, &suboffset);
if (type == ASN1_CONTEXT_DNSNAME)
{
x509_ctx->subject_alt_dnsnames = (char**)
SSL_REALLOC(x509_ctx->subject_alt_dnsnames,
(totalnames + 2) * sizeof(char*));
x509_ctx->subject_alt_dnsnames[totalnames] =
(char*)SSL_MALLOC(dnslen + 1);
x509_ctx->subject_alt_dnsnames[totalnames+1] = NULL;
memcpy(x509_ctx->subject_alt_dnsnames[totalnames],
cert + suboffset, dnslen);
x509_ctx->subject_alt_dnsnames[
totalnames][dnslen] = 0;
++totalnames;
}
suboffset += dnslen;
}
}
}
}
}
offset = end_tbs; /* skip the rest of v3 data */
if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) ||
asn1_signature(cert, &offset, x509_ctx))
goto end_cert;
#endif
ret = X509_OK;
end_cert:
if (len)
{
*len = cert_size;
}
if (ret)
{
#ifdef CONFIG_SSL_FULL_MODE
ssl_printf("Error: Invalid X509 ASN.1 file (%s)\n",
x509_display_error(ret));
#endif
x509_free(x509_ctx);
*ctx = NULL;
}
return ret;
}
/**
* Free an X.509 object's resources.
*/
void x509_free(X509_CTX *x509_ctx)
{
X509_CTX *next;
int i;
if (x509_ctx == NULL) /* if already null, then don't bother */
return;
for (i = 0; i < X509_NUM_DN_TYPES; i++)
{
SSL_FREE(x509_ctx->ca_cert_dn[i]);
SSL_FREE(x509_ctx->cert_dn[i]);
}
SSL_FREE(x509_ctx->signature);
#ifdef CONFIG_SSL_CERT_VERIFICATION
if (x509_ctx->digest)
{
bi_free(x509_ctx->rsa_ctx->bi_ctx, x509_ctx->digest);
}
if (x509_ctx->subject_alt_dnsnames)
{
for (i = 0; x509_ctx->subject_alt_dnsnames[i]; ++i)
SSL_FREE(x509_ctx->subject_alt_dnsnames[i]);
SSL_FREE(x509_ctx->subject_alt_dnsnames);
}
#endif
RSA_free(x509_ctx->rsa_ctx);
next = x509_ctx->next;
SSL_FREE(x509_ctx);
x509_free(next); /* clear the chain */
}
#ifdef CONFIG_SSL_CERT_VERIFICATION
/**
* Take a signature and decrypt it.
*/
static bigint *sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
bigint *modulus, bigint *pub_exp)
{
int i, size;
bigint *decrypted_bi, *dat_bi;
bigint *bir = NULL;
uint8_t *block = (uint8_t *)SSL_MALLOC(sig_len);
/* decrypt */
dat_bi = bi_import(ctx, sig, sig_len);
ctx->mod_offset = BIGINT_M_OFFSET;
/* convert to a normal block */
decrypted_bi = bi_mod_power2(ctx, dat_bi, modulus, pub_exp);
bi_export(ctx, decrypted_bi, block, sig_len);
ctx->mod_offset = BIGINT_M_OFFSET;
i = 10; /* start at the first possible non-padded byte */
while (block[i++] && i < sig_len);
size = sig_len - i;
/* get only the bit we want */
if (size > 0)
{
int len;
const uint8_t *sig_ptr = get_signature(&block[i], &len);
if (sig_ptr)
{
bir = bi_import(ctx, sig_ptr, len);
}
}
/* save a few bytes of memory */
bi_clear_cache(ctx);
SSL_FREE(block);
return bir;
}
/**
* Do some basic checks on the certificate chain.
*
* Certificate verification consists of a number of checks:
* - The date of the certificate is after the start date.
* - The date of the certificate is before the finish date.
* - A root certificate exists in the certificate store.
* - That the certificate(s) are not self-signed.
* - The certificate chain is valid.
* - The signature of the certificate is valid.
*/
int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
{
int ret = X509_OK, i = 0;
bigint *cert_sig;
X509_CTX *next_cert = NULL;
BI_CTX *ctx = NULL;
bigint *mod = NULL, *expn = NULL;
int match_ca_cert = 0;
struct timeval tv;
uint8_t is_self_signed = 0;
if (cert == NULL)
{
ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
goto end_verify;
}
/* a self-signed certificate that is not in the CA store - use this
to check the signature */
if (asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0)
{
#if CONFIG_SSL_DISPLAY_MODE
printf("a self-signed certificate that is not in the CA store\n");
#endif
is_self_signed = 1;
ctx = cert->rsa_ctx->bi_ctx;
mod = cert->rsa_ctx->m;
expn = cert->rsa_ctx->e;
}
gettimeofday(&tv, (void*)&cert->not_before);
#if CONFIG_SSL_DISPLAY_MODE
printf("before %u, tv_sec %u, after %u\n",cert->not_before, tv.tv_sec, cert->not_after);
#endif
/* check the not before date */
if (tv.tv_sec < cert->not_before)
{
ret = X509_VFY_ERROR_NOT_YET_VALID;
goto end_verify;
}
/* check the not after date */
if (tv.tv_sec > cert->not_after)
{
ret = X509_VFY_ERROR_EXPIRED;
goto end_verify;
}
next_cert = cert->next;
/* last cert in the chain - look for a trusted cert */
if (next_cert == NULL)
{
if (ca_cert_ctx != NULL)
{
#if CONFIG_SSL_DISPLAY_MODE
printf("look for a trusted cert\n");
#endif
/* go thu the CA store */
while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
{
if (asn1_compare_dn(cert->ca_cert_dn,
ca_cert_ctx->cert[i]->cert_dn) == 0)
{
/* use this CA certificate for signature verification */
#if CONFIG_SSL_DISPLAY_MODE
printf("use the CA certificate for signature verification\n");
#endif
match_ca_cert = 1;
ctx = ca_cert_ctx->cert[i]->rsa_ctx->bi_ctx;
mod = ca_cert_ctx->cert[i]->rsa_ctx->m;
expn = ca_cert_ctx->cert[i]->rsa_ctx->e;
break;
}
i++;
}
}
/* couldn't find a trusted cert (& let self-signed errors
be returned) */
if (!match_ca_cert && !is_self_signed)
{
ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
goto end_verify;
}
}
else if (asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn) != 0)
{
/* check the chain */
ret = X509_VFY_ERROR_INVALID_CHAIN;
goto end_verify;
}
else /* use the next certificate in the chain for signature verify */
{
ctx = next_cert->rsa_ctx->bi_ctx;
mod = next_cert->rsa_ctx->m;
expn = next_cert->rsa_ctx->e;
}
/* cert is self signed */
if (!match_ca_cert && is_self_signed)
{
ret = X509_VFY_ERROR_SELF_SIGNED;
goto end_verify;
}
/* check the signature */
cert_sig = sig_verify(ctx, cert->signature, cert->sig_len,
bi_clone(ctx, mod), bi_clone(ctx, expn));
if (cert_sig && cert->digest)
{
if (bi_compare(cert_sig, cert->digest) != 0)
ret = X509_VFY_ERROR_BAD_SIGNATURE;
#if CONFIG_SSL_DISPLAY_MODE
printf("check the signature ok\n");
#endif
// bi_free(ctx, cert_sig);//comment the line for check signature by LiuH at 20150.06.11
}
else
{
ret = X509_VFY_ERROR_BAD_SIGNATURE;
}
if (cert_sig != NULL)
bi_free(ctx, cert_sig);//add the line for check signature by LiuH at 2015.06.11
if (ret)
goto end_verify;
/* go down the certificate chain using recursion. */
if (next_cert != NULL)
{
ret = x509_verify(ca_cert_ctx, next_cert);
}
end_verify:
return ret;
}
#endif
#if defined (CONFIG_SSL_FULL_MODE)
/**
* Used for diagnostics.
*/
//static const char *not_part_of_cert = "<Not Part Of Certificate>";
void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx)
{
if (cert == NULL)
return;
ssl_printf("=== CERTIFICATE ISSUED TO ===\n");
ssl_printf("Common Name (CN):\t\t");
ssl_printf("%s\n", cert->cert_dn[X509_COMMON_NAME] ?
cert->cert_dn[X509_COMMON_NAME] : not_part_of_cert);
ssl_printf("Organization (O):\t\t");
ssl_printf("%s\n", cert->cert_dn[X509_ORGANIZATION] ?
cert->cert_dn[X509_ORGANIZATION] : not_part_of_cert);
ssl_printf("Organizational Unit (OU):\t");
ssl_printf("%s\n", cert->cert_dn[X509_ORGANIZATIONAL_UNIT] ?
cert->cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert);
ssl_printf("=== CERTIFICATE ISSUED BY ===\n");
ssl_printf("Common Name (CN):\t\t");
ssl_printf("%s\n", cert->ca_cert_dn[X509_COMMON_NAME] ?
cert->ca_cert_dn[X509_COMMON_NAME] : not_part_of_cert);
ssl_printf("Organization (O):\t\t");
ssl_printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATION] ?
cert->ca_cert_dn[X509_ORGANIZATION] : not_part_of_cert);
ssl_printf("Organizational Unit (OU):\t");
ssl_printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] ?
cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert);
ssl_printf("Not Before:\t\t\t%d\n", cert->not_before);
ssl_printf("Not After:\t\t\t%d\n", cert->not_after);
ssl_printf("RSA bitsize:\t\t\t%d\n", cert->rsa_ctx->num_octets*8);
ssl_printf("Sig Type:\t\t\t");
switch (cert->sig_type)
{
case SIG_TYPE_MD2:
ssl_printf("MD2\n");
break;
case SIG_TYPE_MD5:
ssl_printf("MD5\n");
break;
case SIG_TYPE_SHA1:
ssl_printf("SHA1\n");
break;
case SIG_TYPE_SHA256:
ssl_printf("SHA256\n");
break;
case SIG_TYPE_SHA384:
ssl_printf("SHA384\n");
break;
case SIG_TYPE_SHA512:
ssl_printf("SHA512\n");
break;
default:
ssl_printf("Unrecognized: %d\n", cert->sig_type);
break;
}
if (ca_cert_ctx)
{
ssl_printf("Verify:\t\t\t\t%s\n",
x509_display_error(x509_verify(ca_cert_ctx, cert)));
}
#if 0
print_blob("Signature", cert->signature, cert->sig_len);
bi_print("Modulus", cert->rsa_ctx->m);
bi_print("Pub Exp", cert->rsa_ctx->e);
#endif
if (ca_cert_ctx)
{
x509_print(cert->next, ca_cert_ctx);
}
//TTY_FLUSH();
}
#if 0
const char * x509_display_error(int error)
{
switch (error)
{
case X509_OK:
return "Certificate verify successful";
case X509_NOT_OK:
return "X509 not ok";
case X509_VFY_ERROR_NO_TRUSTED_CERT:
return "No trusted cert is available";
case X509_VFY_ERROR_BAD_SIGNATURE:
return "Bad signature";
case X509_VFY_ERROR_NOT_YET_VALID:
return "Cert is not yet valid";
case X509_VFY_ERROR_EXPIRED:
return "Cert has expired";
case X509_VFY_ERROR_SELF_SIGNED:
return "Cert is self-signed";
case X509_VFY_ERROR_INVALID_CHAIN:
return "Chain is invalid (check order of certs)";
case X509_VFY_ERROR_UNSUPPORTED_DIGEST:
return "Unsupported digest";
case X509_INVALID_PRIV_KEY:
return "Invalid private key";
default:
return "Unknown";
}
}
#endif
#endif /* CONFIG_SSL_FULL_MODE */

View File

@ -20,8 +20,5 @@ ifdef CONFIG_SSL_USING_MBEDTLS
COMPONENT_PRIV_INCLUDEDIRS := mbedtls/port/openssl/include/internal mbedtls/port/openssl/include/openssl mbedtls/port/openssl/include/platform
COMPONENT_ADD_INCLUDEDIRS += mbedtls/mbedtls/include mbedtls/port/esp8266/include mbedtls/port/openssl/include
COMPONENT_SRCDIRS += mbedtls/mbedtls/library mbedtls/port/esp8266 mbedtls/port/openssl/source/library mbedtls/port/openssl/source/platform
else
COMPONENT_ADD_INCLUDEDIRS := axtls/include
COMPONENT_SRCDIRS := axtls/source/ssl axtls/source/crypto
endif
endif