From 5ac03256db0fe4ca7e3ad1117d096c3a76368b76 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Fri, 9 Jan 2015 09:46:07 +0100 Subject: backported CyaSSL/OpenSSL support for internal webserver instead of MatrixSSL --- release/src/router/cyassl/include/cyassl_int.h | 1225 ++++++++++++++++++++++++ 1 file changed, 1225 insertions(+) create mode 100644 release/src/router/cyassl/include/cyassl_int.h (limited to 'release/src/router/cyassl/include/cyassl_int.h') diff --git a/release/src/router/cyassl/include/cyassl_int.h b/release/src/router/cyassl/include/cyassl_int.h new file mode 100644 index 00000000..68423755 --- /dev/null +++ b/release/src/router/cyassl/include/cyassl_int.h @@ -0,0 +1,1225 @@ +/* cyassl_int.h + * + * Copyright (C) 2006-2011 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + + +#ifndef CYASSL_INT_H +#define CYASSL_INT_H + + +#include "types.h" +#include "random.h" +#include "des3.h" +#include "hc128.h" +#include "rabbit.h" +#include "asn.h" +#include "ctc_md5.h" +#include "ctc_aes.h" +#ifdef HAVE_ECC + #include "ctc_ecc.h" +#endif +#ifndef NO_SHA256 + #include "sha256.h" +#endif + +#ifdef CYASSL_CALLBACKS + #include "cyassl_callbacks.h" + #include +#endif + +#ifdef USE_WINDOWS_API + #include +#elif defined(THREADX) + #ifndef SINGLE_THREADED + #include "tx_api.h" + #endif +#elif defined(MICRIUM) + /* do nothing, just don't pick Unix */ +#else + #ifndef SINGLE_THREADED + #define CYASSL_PTHREADS + #include + #endif + #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS) + #include /* for close of BIO */ + #endif +#endif + +#ifdef HAVE_LIBZ + #include "zlib.h" +#endif + +#ifdef _MSC_VER + /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ + #pragma warning(disable: 4996) +#endif + +#ifdef NO_AES + #if !defined (ALIGN16) + #define ALIGN16 + #endif +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + +#ifdef USE_WINDOWS_API + typedef unsigned int SOCKET_T; +#else + typedef int SOCKET_T; +#endif + + +typedef byte word24[3]; + +/* Define or comment out the cipher suites you'd like to be compiled in + make sure to use at least one BUILD_SSL_xxx or BUILD_TLS_xxx is defined + + When adding cipher suites, add name to cipher_names, idx to cipher_name_idx +*/ +#ifndef NO_RC4 + #define BUILD_SSL_RSA_WITH_RC4_128_SHA + #define BUILD_SSL_RSA_WITH_RC4_128_MD5 + #if !defined(NO_TLS) && defined(HAVE_NTRU) + #define BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA + #endif +#endif + +#ifndef NO_DES3 + #define BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA + #if !defined(NO_TLS) && defined(HAVE_NTRU) + #define BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA + #endif +#endif + +#if !defined(NO_AES) && !defined(NO_TLS) + #define BUILD_TLS_RSA_WITH_AES_128_CBC_SHA + #define BUILD_TLS_RSA_WITH_AES_256_CBC_SHA + #if !defined (NO_PSK) + #define BUILD_TLS_PSK_WITH_AES_128_CBC_SHA + #define BUILD_TLS_PSK_WITH_AES_256_CBC_SHA + #endif + #if defined(HAVE_NTRU) + #define BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA + #define BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA + #endif +#endif + +#if !defined(NO_HC128) && !defined(NO_TLS) + #define BUILD_TLS_RSA_WITH_HC_128_CBC_MD5 + #define BUILD_TLS_RSA_WITH_HC_128_CBC_SHA +#endif + +#if !defined(NO_RABBIT) && !defined(NO_TLS) + #define BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA +#endif + +#if !defined(NO_DH) && !defined(NO_AES) && !defined(NO_TLS) && defined(OPENSSL_EXTRA) + #define BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + #define BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA +#endif + +#if defined(HAVE_ECC) && !defined(NO_TLS) + #if !defined(NO_AES) + #define BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + #define BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + #endif + #if !defined(NO_RC4) + #define BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA + #define BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + #endif + #if !defined(NO_DES3) + #define BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + #define BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + #endif +#endif + + +#if defined(BUILD_SSL_RSA_WITH_RC4_128_SHA) || \ + defined(BUILD_SSL_RSA_WITH_RC4_128_MD5) + #define BUILD_ARC4 +#endif + +#if defined(BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA) + #define BUILD_DES3 +#endif + +#if defined(BUILD_TLS_RSA_WITH_AES_128_CBC_SHA) || \ + defined(BUILD_TLS_RSA_WITH_AES_256_CBC_SHA) + #define BUILD_AES +#endif + +#if defined(BUILD_TLS_RSA_WITH_HC_128_CBC_SHA) || \ + defined(BUILD_TLS_RSA_WITH_HC_128_CBC_MD5) + #define BUILD_HC128 +#endif + +#if defined(BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA) + #define BUILD_RABBIT +#endif + +#ifdef NO_DES3 + #define DES_BLOCK_SIZE 8 +#endif + +#ifdef NO_AES + #define AES_BLOCK_SIZE 16 +#endif + + +/* actual cipher values, 2nd byte */ +enum { + TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x39, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x33, + TLS_RSA_WITH_AES_256_CBC_SHA = 0x35, + TLS_RSA_WITH_AES_128_CBC_SHA = 0x2F, + TLS_PSK_WITH_AES_256_CBC_SHA = 0x8d, + TLS_PSK_WITH_AES_128_CBC_SHA = 0x8c, + SSL_RSA_WITH_RC4_128_SHA = 0x05, + SSL_RSA_WITH_RC4_128_MD5 = 0x04, + SSL_RSA_WITH_3DES_EDE_CBC_SHA = 0x0A, + + /* ECC suites, first byte is 0xC0 (ECC_BYTE) */ + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0x14, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0x13, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0x0A, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0x09, + TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0x11, + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0x07, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x12, + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0x08, + + /* CyaSSL extension - eSTREAM */ + TLS_RSA_WITH_HC_128_CBC_MD5 = 0xFB, + TLS_RSA_WITH_HC_128_CBC_SHA = 0xFC, + TLS_RSA_WITH_RABBIT_CBC_SHA = 0xFD, + + /* CyaSSL extension - NTRU */ + TLS_NTRU_RSA_WITH_RC4_128_SHA = 0x65, + TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA = 0x66, + TLS_NTRU_RSA_WITH_AES_128_CBC_SHA = 0x67, + TLS_NTRU_RSA_WITH_AES_256_CBC_SHA = 0x68 +}; + + +enum Misc { + SERVER_END = 0, + CLIENT_END, + + ECC_BYTE = 0xC0, /* ECC first cipher suite byte */ + + SEND_CERT = 1, + SEND_BLANK_CERT = 2, + + DTLS_MAJOR = 0xfe, /* DTLS major version number */ + DTLS_MINOR = 0xff, /* DTLS minor version number */ + SSLv3_MAJOR = 3, /* SSLv3 and TLSv1+ major version number */ + SSLv3_MINOR = 0, /* TLSv1 minor version number */ + TLSv1_MINOR = 1, /* TLSv1 minor version number */ + TLSv1_1_MINOR = 2, /* TLSv1_1 minor version number */ + TLSv1_2_MINOR = 3, /* TLSv1_2 minor version number */ + NO_COMPRESSION = 0, + ZLIB_COMPRESSION = 221, /* CyaSSL zlib compression */ + SECRET_LEN = 48, /* pre RSA and all master */ + ENCRYPT_LEN = 256, /* allow 2048 bit static buffer */ + SIZEOF_SENDER = 4, /* clnt or srvr */ + FINISHED_SZ = MD5_DIGEST_SIZE + SHA_DIGEST_SIZE, + MAX_RECORD_SIZE = 16384, /* 2^14, max size by standard */ + MAX_UDP_SIZE = 1400, /* don't exceed MTU */ + MAX_MSG_EXTRA = 68, /* max added to msg, mac + pad */ + MAX_COMP_EXTRA = 1024, /* max compression extra */ + MAX_MTU = 1500, /* max expected MTU */ + MAX_DH_SZ = 612, /* 2240 p, pub, g + 2 byte size for each */ + MAX_STR_VERSION = 8, /* string rep of protocol version */ + + PAD_MD5 = 48, /* pad length for finished */ + PAD_SHA = 40, /* pad length for finished */ + PEM_LINE_LEN = 80, /* PEM line max + fudge */ + LENGTH_SZ = 2, /* length field for HMAC, data only */ + VERSION_SZ = 2, /* length of proctocol version */ + SEQ_SZ = 8, /* 64 bit sequence number */ + BYTE3_LEN = 3, /* up to 24 bit byte lengths */ + ALERT_SIZE = 2, /* level + description */ + REQUEST_HEADER = 2, /* always use 2 bytes */ + VERIFY_HEADER = 2, /* always use 2 bytes */ + + MAX_SUITE_SZ = 200, /* 100 suites for now! */ + RAN_LEN = 32, /* random length */ + SEED_LEN = RAN_LEN * 2, /* tls prf seed length */ + ID_LEN = 32, /* session id length */ + MAX_COOKIE_LEN = 32, /* max dtls cookie size */ + SUITE_LEN = 2, /* cipher suite sz length */ + ENUM_LEN = 1, /* always a byte */ + COMP_LEN = 1, /* compression length */ + CURVE_LEN = 2, /* ecc named curve length */ + + HANDSHAKE_HEADER_SZ = 4, /* type + length(3) */ + RECORD_HEADER_SZ = 5, /* type + version + len(2) */ + CERT_HEADER_SZ = 3, /* always 3 bytes */ + REQ_HEADER_SZ = 2, /* cert request header sz */ + HINT_LEN_SZ = 2, /* length of hint size field */ + + DTLS_HANDSHAKE_HEADER_SZ = 12, /* normal + seq(2) + offset(3) + length(3) */ + DTLS_RECORD_HEADER_SZ = 13, /* normal + epoch(2) + seq_num(6) */ + DTLS_HANDSHAKE_EXTRA = 8, /* diff from normal */ + DTLS_RECORD_EXTRA = 8, /* diff from normal */ + + FINISHED_LABEL_SZ = 15, /* TLS finished label size */ + TLS_FINISHED_SZ = 12, /* TLS has a shorter size */ + MASTER_LABEL_SZ = 13, /* TLS master secret label sz */ + KEY_LABEL_SZ = 13, /* TLS key block expansion sz */ + MAX_PRF_HALF = 128, /* Maximum half secret len */ + MAX_PRF_LABSEED = 80, /* Maximum label + seed len */ + MAX_PRF_DIG = 148, /* Maximum digest len */ + MAX_REQUEST_SZ = 256, /* Maximum cert req len (no auth yet */ + SESSION_FLUSH_COUNT = 256, /* Flush session cache unless user turns off */ + + RC4_KEY_SIZE = 16, /* always 128bit */ + DES_KEY_SIZE = 8, /* des */ + DES3_KEY_SIZE = 24, /* 3 des ede */ + DES_IV_SIZE = DES_BLOCK_SIZE, + AES_256_KEY_SIZE = 32, /* for 256 bit */ + AES_192_KEY_SIZE = 24, /* for 192 bit */ + AES_IV_SIZE = 16, /* always block size */ + AES_128_KEY_SIZE = 16, /* for 128 bit */ + + HC_128_KEY_SIZE = 16, /* 128 bits */ + HC_128_IV_SIZE = 16, /* also 128 bits */ + + RABBIT_KEY_SIZE = 16, /* 128 bits */ + RABBIT_IV_SIZE = 8, /* 64 bits for iv */ + + EVP_SALT_SIZE = 8, /* evp salt size 64 bits */ + + ECDHE_SIZE = 32, /* ECHDE server size defaults to 256 bit */ + MAX_EXPORT_ECC_SZ = 256, /* Export ANS X9.62 max future size */ + + MAX_HELLO_SZ = 128, /* max client or server hello */ + MAX_CERT_VERIFY_SZ = 1024, /* max */ + CLIENT_HELLO_FIRST = 35, /* Protocol + RAN_LEN + sizeof(id_len) */ + MAX_SUITE_NAME = 48, /* maximum length of cipher suite string */ + DEFAULT_TIMEOUT = 500, /* default resumption timeout in seconds */ + + MAX_PSK_ID_LEN = 128, /* max psk identity/hint supported */ + MAX_PSK_KEY_LEN = 64, /* max psk key supported */ + + MAX_CHAIN_DEPTH = 4, /* max cert chain peer depth */ + MAX_X509_SIZE = 2048, /* max static x509 buffer size */ + FILE_BUFFER_SIZE = 1024, /* default static file buffer size for input, + will use dynamic buffer if not big enough */ + + MAX_NTRU_PUB_KEY_SZ = 1027, /* NTRU max for now */ + MAX_NTRU_ENCRYPT_SZ = 1027, /* NTRU max for now */ + MAX_NTRU_BITS = 256, /* max symmetric bit strength */ + NO_SNIFF = 0, /* not sniffing */ + SNIFF = 1, /* currently sniffing */ + + HASH_SIG_SIZE = 2, /* default SHA1 RSA */ + + NO_COPY = 0, /* should we copy static buffer for write */ + COPY = 1 /* should we copy static buffer for write */ +}; + + +/* states */ +enum states { + NULL_STATE = 0, + + SERVER_HELLOVERIFYREQUEST_COMPLETE, + SERVER_HELLO_COMPLETE, + SERVER_CERT_COMPLETE, + SERVER_KEYEXCHANGE_COMPLETE, + SERVER_HELLODONE_COMPLETE, + SERVER_FINISHED_COMPLETE, + + CLIENT_HELLO_COMPLETE, + CLIENT_KEYEXCHANGE_COMPLETE, + CLIENT_FINISHED_COMPLETE, + + HANDSHAKE_DONE +}; + + +#ifndef SSL_TYPES_DEFINED + typedef struct SSL_METHOD SSL_METHOD; + typedef struct SSL_CTX SSL_CTX; + typedef struct SSL_SESSION SSL_SESSION; + typedef struct SSL_CIPHER SSL_CIPHER; + typedef struct SSL SSL; + typedef struct X509 X509; + typedef struct X509_CHAIN X509_CHAIN; + typedef struct BIO BIO; + typedef struct BIO_METHOD BIO_METHOD; + + #undef X509_NAME + typedef struct X509_NAME X509_NAME; + + typedef struct X509_STORE_CTX { + int error; + int error_depth; + X509* current_cert; /* stunnel dereference */ + char* domain; /* subject CN domain name */ + } X509_STORE_CTX; + + + typedef int (*pem_password_cb)(char*, int, int, void*); + typedef int (*CallbackIORecv)(char *buf, int sz, void *ctx); + typedef int (*CallbackIOSend)(char *buf, int sz, void *ctx); + typedef int (*VerifyCallback)(int, X509_STORE_CTX*); + + /* make sure external "C" linkage for C++ programs with callbacks */ + void CyaSSL_SetIORecv(SSL_CTX*, CallbackIORecv); + void CyaSSL_SetIOSend(SSL_CTX*, CallbackIOSend); + + void CyaSSL_SetIOReadCtx(SSL* ssl, void *ctx); + void CyaSSL_SetIOWriteCtx(SSL* ssl, void *ctx); +#endif /* SSL_TYPES_DEFINED */ + + +/* SSL Version */ +typedef struct ProtocolVersion { + byte major; + byte minor; +} ProtocolVersion; + + +ProtocolVersion MakeSSLv3(void); +ProtocolVersion MakeTLSv1(void); +ProtocolVersion MakeTLSv1_1(void); +ProtocolVersion MakeTLSv1_2(void); + +#ifdef CYASSL_DTLS + ProtocolVersion MakeDTLSv1(void); +#endif + + +enum BIO_TYPE { + BIO_BUFFER = 1, + BIO_SOCKET = 2, + BIO_SSL = 3 +}; + + +/* OpenSSL BIO_METHOD type */ +struct BIO_METHOD { + byte type; /* method type */ +}; + + +/* OpenSSL BIO type */ +struct BIO { + byte type; /* method type */ + byte close; /* close flag */ + byte eof; /* eof flag */ + SSL* ssl; /* possible associated ssl */ + int fd; /* possible file descriptor */ + BIO* prev; /* previous in chain */ + BIO* next; /* next in chain */ +}; + + +/* OpenSSL method type */ +struct SSL_METHOD { + ProtocolVersion version; + int side; /* connection side, server or client */ + int verifyPeer; /* request or send certificate */ + int verifyNone; /* whether to verify certificate */ + int failNoCert; /* fail if no certificate */ + int downgrade; /* whether to downgrade version, default no */ +}; + + +/* defautls to client */ +void InitSSL_Method(SSL_METHOD*, ProtocolVersion); + +/* for sniffer */ +int DoFinished(SSL* ssl, const byte* input, word32* inOutIdx, int sniff); +int DoApplicationData(SSL* ssl, byte* input, word32* inOutIdx); + + +/* CyaSSL buffer type */ +typedef struct buffer { + word32 length; + byte* buffer; +} buffer; + + +enum { + FORCED_FREE = 1, + NO_FORCED_FREE = 0 +}; + + +/* only use compression extra if using compression */ +#ifdef HAVE_LIBZ + #define COMP_EXTRA MAX_COMP_EXTRA +#else + #define COMP_EXTRA 0 +#endif + +/* only the sniffer needs space in the buffer for an extra MTU record */ +#ifdef CYASSL_SNIFFER + #define MTU_EXTRA MAX_MTU +#else + #define MTU_EXTRA 0 +#endif + +/* give user option to use 16K static buffers, sniffer needs them too */ +#if defined(LARGE_STATIC_BUFFERS) || defined(CYASSL_SNIFFER) + #define RECORD_SIZE MAX_RECORD_SIZE +#else + #ifdef CYASSL_DTLS + #define RECORD_SIZE 1500 + #else + #define RECORD_SIZE 128 + #endif +#endif + + +/* user option to turn off 16K output option */ +/* if using small static buffers (default) and SSL_write tries to write data + larger than the record we have, dynamically get it, unless user says only + write in static buffer chuncks */ +#ifndef STATIC_CHUNKS_ONLY + #define OUTPUT_RECORD_SIZE MAX_RECORD_SIZE +#else + #define OUTPUT_RECORD_SIZE RECORD_SIZE +#endif + +/* CyaSSL input buffer + + RFC 2246: + + length + The length (in bytes) of the following TLSPlaintext.fragment. + The length should not exceed 2^14. +*/ +#define STATIC_BUFFER_LEN RECORD_HEADER_SZ + RECORD_SIZE + COMP_EXTRA + \ + MTU_EXTRA + MAX_MSG_EXTRA + +typedef struct { + word32 length; /* total buffer length used */ + word32 idx; /* idx to part of length already consumed */ + byte* buffer; /* place holder for static or dynamic buffer */ + ALIGN16 byte staticBuffer[STATIC_BUFFER_LEN]; + word32 bufferSize; /* current buffer size */ + byte dynamicFlag; /* dynamic memory currently in use */ +} bufferStatic; + +/* Cipher Suites holder */ +typedef struct Suites { + int setSuites; /* user set suites from default */ + byte suites[MAX_SUITE_SZ]; + word16 suiteSz; /* suite length in bytes */ +} Suites; + + +void InitSuites(Suites*, ProtocolVersion, byte, byte, byte, byte, int); +int SetCipherList(SSL_CTX* ctx, const char* list); + +#ifndef PSK_TYPES_DEFINED + typedef unsigned int (*psk_client_callback)(SSL*, const char*, char*, + unsigned int, unsigned char*, unsigned int); + typedef unsigned int (*psk_server_callback)(SSL*, const char*, + unsigned char*, unsigned int); +#endif /* PSK_TYPES_DEFINED */ + + +#ifndef CYASSL_USER_IO + /* default IO callbacks */ + int EmbedReceive(char *buf, int sz, void *ctx); + int EmbedSend(char *buf, int sz, void *ctx); +#endif + +#ifdef CYASSL_DTLS + int IsUDP(void*); +#endif + + +/* OpenSSL Cipher type just points back to SSL */ +struct SSL_CIPHER { + SSL* ssl; +}; + + +/* OpenSSL context type */ +struct SSL_CTX { + SSL_METHOD* method; + buffer certificate; + buffer privateKey; + Signer* caList; /* SSL_CTX owns this, SSL will reference */ + Suites suites; + void* heap; /* for user memory overrides */ + byte verifyPeer; + byte verifyNone; + byte failNoCert; + byte sessionCacheOff; + byte sessionCacheFlushOff; + byte sendVerify; /* for client side */ + byte haveDH; /* server DH parms set by user */ + byte haveNTRU; /* server private NTRU key loaded */ + byte haveECDSA; /* server private ECDSA key loaded */ + byte partialWrite; /* only one msg per write call */ + byte quietShutdown; /* don't send close notify */ + CallbackIORecv CBIORecv; + CallbackIOSend CBIOSend; + VerifyCallback verifyCallback; /* cert verification callback */ +#ifndef NO_PSK + byte havePSK; /* psk key set by user */ + psk_client_callback client_psk_cb; /* client callback */ + psk_server_callback server_psk_cb; /* server callback */ + char server_hint[MAX_PSK_ID_LEN]; +#endif /* NO_PSK */ +#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) + pem_password_cb passwd_cb; + void* userdata; +#endif /* OPENSSL_EXTRA */ +}; + + +void InitSSL_Ctx(SSL_CTX*, SSL_METHOD*); +void FreeSSL_Ctx(SSL_CTX*); +void SSL_CtxResourceFree(SSL_CTX*); + +int DeriveTlsKeys(SSL* ssl); +int ProcessOldClientHello(SSL* ssl, const byte* input, word32* inOutIdx, + word32 inSz, word16 sz); + +/* All cipher suite related info */ +typedef struct CipherSpecs { + byte bulk_cipher_algorithm; + byte cipher_type; /* block or stream */ + byte mac_algorithm; + byte kea; /* key exchange algo */ + byte sig_algo; + byte hash_size; + byte pad_size; + word16 key_size; + word16 iv_size; + word16 block_size; +} CipherSpecs; + + + +/* Supported Ciphers from page 43 */ +enum BulkCipherAlgorithm { + cipher_null, + rc4, + rc2, + des, + triple_des, /* leading 3 (3des) not valid identifier */ + des40, + idea, + aes, + hc128, /* CyaSSL extensions */ + rabbit +}; + + +/* Supported Message Authentication Codes from page 43 */ +enum MACAlgorithm { + no_mac = 0, + md5_mac, + sha_mac, + sha224_mac, + sha256_mac, + sha384_mac, + sha512_mac, + rmd_mac +}; + + +/* Supported Key Exchange Protocols */ +enum KeyExchangeAlgorithm { + no_kea = 0, + rsa_kea, + diffie_hellman_kea, + fortezza_kea, + psk_kea, + ntru_kea, + ecc_diffie_hellman_kea +}; + + +/* Supported Authentication Schemes */ +enum SignatureAlgorithm { + anonymous_sa_algo = 0, + rsa_sa_algo, + dsa_sa_algo, + ecc_dsa_sa_algo +}; + + +/* Supprted ECC Curve Types */ +enum EccCurves { + named_curve = 3 +}; + + +/* Supprted ECC Named Curves */ +enum EccNamedCurves { + secp256r1 = 0x17, /* default, OpenSSL also calls it prime256v1 */ + secp384r1 = 0x18, + secp521r1 = 0x19, + + secp160r1 = 0x10, + secp192r1 = 0x13, /* Openssl also call it prime192v1 */ + secp224r1 = 0x15 +}; + + +/* Valid client certificate request types from page 27 */ +enum ClientCertificateType { + rsa_sign = 1, + dss_sign = 2, + rsa_fixed_dh = 3, + dss_fixed_dh = 4, + rsa_ephemeral_dh = 5, + dss_ephemeral_dh = 6, + fortezza_kea_cert = 20 +}; + + +enum CipherType { stream, block }; + + +/* keys and secrets */ +typedef struct Keys { + byte client_write_MAC_secret[SHA_DIGEST_SIZE]; /* max sizes */ + byte server_write_MAC_secret[SHA_DIGEST_SIZE]; + byte client_write_key[AES_256_KEY_SIZE]; /* max sizes */ + byte server_write_key[AES_256_KEY_SIZE]; + byte client_write_IV[AES_IV_SIZE]; /* max sizes */ + byte server_write_IV[AES_IV_SIZE]; + + word32 peer_sequence_number; + word32 sequence_number; + +#ifdef CYASSL_DTLS + word32 dtls_sequence_number; + word32 dtls_peer_sequence_number; + word16 dtls_handshake_number; + word16 dtls_epoch; + word16 dtls_peer_epoch; +#endif + + word32 encryptSz; /* last size of encrypted data */ + byte encryptionOn; /* true after change cipher spec */ +} Keys; + + +/* cipher for now */ +typedef union { +#ifdef BUILD_ARC4 + Arc4 arc4; +#endif +#ifdef BUILD_DES3 + Des3 des3; +#endif +#ifdef BUILD_AES + Aes aes; +#endif +#ifdef BUILD_HC128 + HC128 hc128; +#endif +#ifdef BUILD_RABBIT + Rabbit rabbit; +#endif +} Ciphers; + + +/* hashes type */ +typedef struct Hashes { + byte md5[MD5_DIGEST_SIZE]; + byte sha[SHA_DIGEST_SIZE]; +} Hashes; + + +/* Static x509 buffer */ +typedef struct x509_buffer { + int length; /* actual size */ + byte buffer[MAX_X509_SIZE]; /* max static cert size */ +} x509_buffer; + + +/* CyaSSL X509_CHAIN, for no dynamic memory SESSION_CACHE */ +struct X509_CHAIN { + int count; /* total number in chain */ + x509_buffer certs[MAX_CHAIN_DEPTH]; /* only allow max depth 4 for now */ +}; + + +/* openSSL session type */ +struct SSL_SESSION { + byte sessionID[ID_LEN]; + byte masterSecret[SECRET_LEN]; + word32 bornOn; /* create time in seconds */ + word32 timeout; /* timeout in seconds */ +#ifdef SESSION_CERTS + X509_CHAIN chain; /* peer cert chain, static */ + ProtocolVersion version; + byte cipherSuite0; /* first byte, normally 0 */ + byte cipherSuite; /* 2nd byte, actual suite */ +#endif +}; + + +SSL_SESSION* GetSession(SSL*, byte*); +int SetSession(SSL*, SSL_SESSION*); + +typedef void (*hmacfp) (SSL*, byte*, const byte*, word32, int, int); + + +/* client connect state for nonblocking restart */ +enum ConnectState { + CONNECT_BEGIN = 0, + CLIENT_HELLO_SENT, + HELLO_AGAIN, /* HELLO_AGAIN s for DTLS case */ + HELLO_AGAIN_REPLY, + FIRST_REPLY_DONE, + FIRST_REPLY_FIRST, + FIRST_REPLY_SECOND, + FIRST_REPLY_THIRD, + FIRST_REPLY_FOURTH, + FINISHED_DONE, + SECOND_REPLY_DONE +}; + + +/* server accpet state for nonblocking restart */ +enum AcceptState { + ACCEPT_BEGIN = 0, + ACCEPT_CLIENT_HELLO_DONE, + HELLO_VERIFY_SENT, + ACCEPT_FIRST_REPLY_DONE, + SERVER_HELLO_SENT, + CERT_SENT, + KEY_EXCHANGE_SENT, + CERT_REQ_SENT, + SERVER_HELLO_DONE, + ACCEPT_SECOND_REPLY_DONE, + CHANGE_CIPHER_SENT, + ACCEPT_FINISHED_DONE, + ACCEPT_THIRD_REPLY_DONE +}; + + +typedef struct Buffers { + buffer certificate; /* SSL_CTX owns */ + buffer key; /* SSL_CTX owns */ + buffer domainName; /* for client check */ + buffer serverDH_P; + buffer serverDH_G; + buffer serverDH_Pub; + buffer serverDH_Priv; + bufferStatic inputBuffer; + bufferStatic outputBuffer; + buffer clearOutputBuffer; + int prevSent; /* previous plain text bytes sent + when got WANT_WRITE */ + int plainSz; /* plain text bytes in buffer to send + when got WANT_WRITE */ +} Buffers; + + +typedef struct Options { + byte sessionCacheOff; + byte sessionCacheFlushOff; + byte cipherSuite0; /* first byte, normally 0 */ + byte cipherSuite; /* second byte, actual suite */ + byte serverState; + byte clientState; + byte handShakeState; + byte side; /* client or server end */ + byte verifyPeer; + byte verifyNone; + byte failNoCert; + byte downgrade; /* allow downgrade of versions */ + byte sendVerify; /* false = 0, true = 1, sendBlank = 2 */ + byte resuming; + byte tls; /* using TLS ? */ + byte tls1_1; /* using TLSv1.1+ ? */ + byte dtls; /* using datagrams ? */ + byte connReset; /* has the peer reset */ + byte isClosed; /* if we consider conn closed */ + byte closeNotify; /* we've recieved a close notify */ + byte sentNotify; /* we've sent a close notify */ + byte connectState; /* nonblocking resume */ + byte acceptState; /* nonblocking resume */ + byte usingCompression; /* are we using compression */ + byte haveDH; /* server DH parms set by user */ + byte haveNTRU; /* server NTRU private key loaded */ + byte haveECDSA; /* server ECDSA private key loaded */ + byte havePeerCert; /* do we have peer's cert */ + byte usingPSK_cipher; /* whether we're using psk as cipher */ + byte sendAlertState; /* nonblocking resume */ + byte processReply; /* nonblocking resume */ + byte partialWrite; /* only one msg per write call */ + byte quietShutdown; /* don't send close notify */ +#ifndef NO_PSK + byte havePSK; /* psk key set by user */ + psk_client_callback client_psk_cb; + psk_server_callback server_psk_cb; +#endif /* NO_PSK */ +} Options; + + +typedef struct Arrays { + byte clientRandom[RAN_LEN]; + byte serverRandom[RAN_LEN]; + byte sessionID[ID_LEN]; + byte preMasterSecret[ENCRYPT_LEN]; + byte masterSecret[SECRET_LEN]; +#ifdef CYASSL_DTLS + byte cookie[MAX_COOKIE_LEN]; +#endif +#ifndef NO_PSK + char client_identity[MAX_PSK_ID_LEN]; + char server_hint[MAX_PSK_ID_LEN]; + byte psk_key[MAX_PSK_KEY_LEN]; + word32 psk_keySz; /* acutal size */ +#endif + word32 preMasterSz; /* differs for DH, actual size */ +} Arrays; + + +#undef X509_NAME + +struct X509_NAME { + char name[ASN_NAME_MAX]; + int sz; +}; + + +struct X509 { + X509_NAME issuer; + X509_NAME subject; +}; + + +/* record layer header for PlainText, Compressed, and CipherText */ +typedef struct RecordLayerHeader { + byte type; + ProtocolVersion version; + byte length[2]; +} RecordLayerHeader; + + +/* record layer header for DTLS PlainText, Compressed, and CipherText */ +typedef struct DtlsRecordLayerHeader { + byte type; + ProtocolVersion version; + byte epoch[2]; /* increment on cipher state change */ + byte sequence_number[6]; /* per record */ + byte length[2]; +} DtlsRecordLayerHeader; + + +/* OpenSSL ssl type */ +struct SSL { + SSL_CTX* ctx; + int error; + ProtocolVersion version; /* negotiated version */ + ProtocolVersion chVersion; /* client hello version */ + Suites suites; + Ciphers encrypt; + Ciphers decrypt; + CipherSpecs specs; + Keys keys; + int rfd; /* read file descriptor */ + int wfd; /* write file descriptor */ + BIO* biord; /* socket bio read to free/close */ + BIO* biowr; /* socket bio write to free/close */ + void* IOCB_ReadCtx; + void* IOCB_WriteCtx; + RNG rng; + Md5 hashMd5; /* md5 hash of handshake msgs */ + Sha hashSha; /* sha hash of handshake msgs */ +#ifndef NO_SHA256 + Sha256 hashSha256; /* sha256 hash of handshake msgs */ +#endif + Hashes verifyHashes; + Hashes certHashes; /* for cert verify */ + Signer* caList; /* SSL_CTX owns */ + Buffers buffers; + Options options; + Arrays arrays; + SSL_SESSION session; + RsaKey peerRsaKey; + byte peerRsaKeyPresent; +#ifdef HAVE_NTRU + word16 peerNtruKeyLen; + byte peerNtruKey[MAX_NTRU_PUB_KEY_SZ]; + byte peerNtruKeyPresent; +#endif +#ifdef HAVE_ECC + ecc_key peerEccKey; /* peer's ECDHE key */ + byte peerEccKeyPresent; + ecc_key peerEccDsaKey; /* peer's ECDSA key */ + byte peerEccDsaKeyPresent; + ecc_key eccTempKey; /* private ECDHE key */ + byte eccTempKeyPresent; + ecc_key eccDsaKey; /* private ECDSA key */ + byte eccDsaKeyPresent; +#endif + hmacfp hmac; + void* heap; /* for user overrides */ + RecordLayerHeader curRL; + word16 curSize; + SSL_CIPHER cipher; +#ifdef HAVE_LIBZ + z_stream c_stream; /* compression stream */ + z_stream d_stream; /* decompression stream */ + byte didStreamInit; /* for stream init and end */ +#endif +#ifdef CYASSL_CALLBACKS + HandShakeInfo handShakeInfo; /* info saved during handshake */ + TimeoutInfo timeoutInfo; /* info saved during handshake */ + byte hsInfoOn; /* track handshake info */ + byte toInfoOn; /* track timeout info */ +#endif +#ifdef OPENSSL_EXTRA + X509 peerCert; /* X509 peer cert */ +#endif +}; + + +int InitSSL(SSL*, SSL_CTX*); +void FreeSSL(SSL*); +void SSL_ResourceFree(SSL*); + + +enum { + IV_SZ = 32, /* max iv sz */ + NAME_SZ = 80, /* max one line */ +}; + + +typedef struct EncryptedInfo { + char name[NAME_SZ]; + byte iv[IV_SZ]; + word32 ivSz; + byte set; +} EncryptedInfo; + + +#ifdef CYASSL_CALLBACKS + void InitHandShakeInfo(HandShakeInfo*); + void FinishHandShakeInfo(HandShakeInfo*, const SSL*); + void AddPacketName(const char*, HandShakeInfo*); + + void InitTimeoutInfo(TimeoutInfo*); + void FreeTimeoutInfo(TimeoutInfo*, void*); + void AddPacketInfo(const char*, TimeoutInfo*, const byte*, int, void*); + void AddLateName(const char*, TimeoutInfo*); + void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info); +#endif + + +/* Record Layer Header identifier from page 12 */ +enum ContentType { + no_type = 0, + change_cipher_spec = 20, + alert = 21, + handshake = 22, + application_data = 23 +}; + + +/* handshake header, same for each message type, pgs 20/21 */ +typedef struct HandShakeHeader { + byte type; + word24 length; +} HandShakeHeader; + + +/* DTLS handshake header, same for each message type */ +typedef struct DtlsHandShakeHeader { + byte type; + word24 length; + byte message_seq[2]; /* start at 0, restransmit gets same # */ + word24 fragment_offset; /* bytes in previous fragments */ + word24 fragment_length; /* length of this fragment */ +} DtlsHandShakeHeader; + + +enum HandShakeType { + no_shake = -1, + hello_request = 0, + client_hello = 1, + server_hello = 2, + hello_verify_request = 3, /* DTLS addition */ + certificate = 11, + server_key_exchange = 12, + certificate_request = 13, + server_hello_done = 14, + certificate_verify = 15, + client_key_exchange = 16, + finished = 20 +}; + + +/* Valid Alert types from page 16/17 */ +enum AlertDescription { + close_notify = 0, + unexpected_message = 10, + bad_record_mac = 20, + decompression_failure = 30, + handshake_failure = 40, + no_certificate = 41, + bad_certificate = 42, + unsupported_certificate = 43, + certificate_revoked = 44, + certificate_expired = 45, + certificate_unknown = 46, + illegal_parameter = 47, + decrypt_error = 51 +}; + + +/* I/O Callback default errors */ +enum IOerrors { + IO_ERR_GENERAL = -1, /* general unexpected err, not in below group */ + IO_ERR_WANT_READ = -2, /* need to call read again */ + IO_ERR_WANT_WRITE = -2, /* need to call write again */ + IO_ERR_CONN_RST = -3, /* connection reset */ + IO_ERR_ISR = -4, /* interrupt */ + IO_ERR_CONN_CLOSE = -5 /* connection closed or epipe */ +}; + + +enum AlertLevel { + alert_warning = 1, + alert_fatal = 2 +}; + + +static const byte client[SIZEOF_SENDER] = { 0x43, 0x4C, 0x4E, 0x54 }; +static const byte server[SIZEOF_SENDER] = { 0x53, 0x52, 0x56, 0x52 }; + +static const byte tls_client[FINISHED_LABEL_SZ + 1] = "client finished"; +static const byte tls_server[FINISHED_LABEL_SZ + 1] = "server finished"; + + +/* internal functions */ +int SendChangeCipher(SSL*); +int SendData(SSL*, const void*, int); +int SendCertificate(SSL*); +int SendCertificateRequest(SSL*); +int SendServerKeyExchange(SSL*); +int SendBuffered(SSL*); +int ReceiveData(SSL*, byte*, int); +int SendFinished(SSL*); +int SendAlert(SSL*, int, int); +int ProcessReply(SSL*); + +int SetCipherSpecs(SSL*); +int MakeMasterSecret(SSL*); + +int AddSession(SSL*); +int DeriveKeys(SSL* ssl); +int StoreKeys(SSL* ssl, const byte* keyData); + +int IsTLS(const SSL* ssl); +int IsAtLeastTLSv1_2(const SSL* ssl); + +void ShrinkInputBuffer(SSL* ssl, int forcedFree); +void ShrinkOutputBuffer(SSL* ssl); + +#ifndef NO_CYASSL_CLIENT + int SendClientHello(SSL*); + int SendClientKeyExchange(SSL*); + int SendCertificateVerify(SSL*); +#endif /* NO_CYASSL_CLIENT */ + +#ifndef NO_CYASSL_SERVER + int SendServerHello(SSL*); + int SendServerHelloDone(SSL*); + #ifdef CYASSL_DTLS + int SendHelloVerifyRequest(SSL*); + #endif +#endif /* NO_CYASSL_SERVER */ + + +#ifndef NO_TLS + + +#endif /* NO_TLS */ + + + +typedef double timer_d; + +timer_d Timer(void); +word32 LowResTimer(void); + + +#ifdef SINGLE_THREADED + typedef int CyaSSL_Mutex; +#else /* MULTI_THREADED */ + #ifdef USE_WINDOWS_API + typedef CRITICAL_SECTION CyaSSL_Mutex; + #elif defined(CYASSL_PTHREADS) + typedef pthread_mutex_t CyaSSL_Mutex; + #elif defined(THREADX) + typedef TX_MUTEX CyaSSL_Mutex; + #elif defined(MICRIUM) + typedef OS_MUTEX CyaSSL_Mutex; + #else + #error Need a mutex type in multithreaded mode + #endif /* USE_WINDOWS_API */ +#endif /* SINGLE_THREADED */ + +int InitMutex(CyaSSL_Mutex*); +int FreeMutex(CyaSSL_Mutex*); +int LockMutex(CyaSSL_Mutex*); +int UnLockMutex(CyaSSL_Mutex*); + + +#ifdef DEBUG_CYASSL + + void CYASSL_ENTER(const char* msg); + void CYASSL_LEAVE(const char* msg, int ret); + + void CYASSL_ERROR(int); + void CYASSL_MSG(const char* msg); + +#else /* DEBUG_CYASSL */ + + #define CYASSL_ENTER(m) + #define CYASSL_LEAVE(m, r) + + #define CYASSL_ERROR(e) + #define CYASSL_MSG(m) + +#endif /* DEBUG_CYASSL */ + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* CyaSSL_INT_H */ + -- cgit v1.2.3-54-g00ecf