diff --git a/IDE/MDK-ARM/MDK-ARM/CyaSSL/config-FS.h b/IDE/MDK-ARM/MDK-ARM/CyaSSL/config-FS.h
index ed2e6d642..1964338ba 100644
--- a/IDE/MDK-ARM/MDK-ARM/CyaSSL/config-FS.h
+++ b/IDE/MDK-ARM/MDK-ARM/CyaSSL/config-FS.h
@@ -76,7 +76,11 @@
// STM32 Hardware Crypt
// STM32F2 Hardware RNG
+<<<<<<< HEAD
#define MDK_CONF_STM32F2_RNG 0
+=======
+#define MDK_CONF_STM32F2_RNG 1
+>>>>>>> cyassl/master
#if MDK_CONF_STM32F2_RNG == 1
#define STM32F2_RNG
#else
diff --git a/IDE/MDK-ARM/MDK-ARM/CyaSSL/config-RTX-TCP-FS.h b/IDE/MDK-ARM/MDK-ARM/CyaSSL/config-RTX-TCP-FS.h
index 17b644d79..fb1d43424 100644
--- a/IDE/MDK-ARM/MDK-ARM/CyaSSL/config-RTX-TCP-FS.h
+++ b/IDE/MDK-ARM/MDK-ARM/CyaSSL/config-RTX-TCP-FS.h
@@ -99,7 +99,11 @@
//
// STM32 Hardware Crypt
// STM32F2 Hardware RNG
+<<<<<<< HEAD
#define MDK_CONF_STM32F2_RNG 0
+=======
+#define MDK_CONF_STM32F2_RNG 1
+>>>>>>> cyassl/master
#if MDK_CONF_STM32F2_RNG == 1
#define STM32F2_RNG
#else
@@ -127,19 +131,31 @@
//
// CertGen
+<<<<<<< HEAD
#define MDK_CONF_CERT_GEN 1
+=======
+#define MDK_CONF_CERT_GEN 0
+>>>>>>> cyassl/master
#if MDK_CONF_CERT_GEN == 1
#define CYASSL_CERT_GEN
#endif
//
// KeyGen
+<<<<<<< HEAD
#define MDK_CONF_KEY_GEN 1
+=======
+#define MDK_CONF_KEY_GEN 0
+>>>>>>> cyassl/master
#if MDK_CONF_KEY_GEN == 1
#define CYASSL_KEY_GEN
#endif
//
// CRL
+<<<<<<< HEAD
#define MDK_CONF_DER_LOAD 1
+=======
+#define MDK_CONF_DER_LOAD 0
+>>>>>>> cyassl/master
#if MDK_CONF_DER_LOAD == 1
#define CYASSL_DER_LOAD
#endif
@@ -160,7 +176,11 @@
// MD5, SHA, SHA-256, AES, RC4, ASN, RSA
//
// MD2
+<<<<<<< HEAD
#define MDK_CONF_MD2 1
+=======
+#define MDK_CONF_MD2 0
+>>>>>>> cyassl/master
#if MDK_CONF_MD2 == 1
#define CYASSL_MD2
#endif
@@ -173,13 +193,21 @@
//
// SHA-384
// This has to be with SHA512
+<<<<<<< HEAD
#define MDK_CONF_SHA384 1
+=======
+#define MDK_CONF_SHA384 0
+>>>>>>> cyassl/master
#if MDK_CONF_SHA384 == 1
#define CYASSL_SHA384
#endif
//
// SHA-512
+<<<<<<< HEAD
#define MDK_CONF_SHA512 1
+=======
+#define MDK_CONF_SHA512 0
+>>>>>>> cyassl/master
#if MDK_CONF_SHA512 == 1
#define CYASSL_SHA512
#endif
@@ -197,7 +225,11 @@
#endif
//
// HC128
+<<<<<<< HEAD
#define MDK_CONF_HC128 1
+=======
+#define MDK_CONF_HC128 0
+>>>>>>> cyassl/master
#if MDK_CONF_HC128 == 1
#define HAVE_HC128
#endif
@@ -210,7 +242,11 @@
//
// AEAD
+<<<<<<< HEAD
#define MDK_CONF_AEAD 1
+=======
+#define MDK_CONF_AEAD 0
+>>>>>>> cyassl/master
#if MDK_CONF_AEAD == 1
#define HAVE_AEAD
#endif
@@ -222,7 +258,11 @@
#endif
//
// CAMELLIA
+<<<<<<< HEAD
#define MDK_CONF_CAMELLIA 1
+=======
+#define MDK_CONF_CAMELLIA 0
+>>>>>>> cyassl/master
#if MDK_CONF_CAMELLIA == 1
#define HAVE_CAMELLIA
#endif
@@ -261,13 +301,21 @@
#endif
//
// AESCCM (Turn off Hardware Crypt)
+<<<<<<< HEAD
#define MDK_CONF_AESCCM 1
+=======
+#define MDK_CONF_AESCCM 0
+>>>>>>> cyassl/master
#if MDK_CONF_AESCCM == 1
#define HAVE_AESCCM
#endif
//
// AESGCM (Turn off Hardware Crypt)
+<<<<<<< HEAD
#define MDK_CONF_AESGCM 1
+=======
+#define MDK_CONF_AESGCM 0
+>>>>>>> cyassl/master
#if MDK_CONF_AESGCM == 1
#define HAVE_AESGCM
#define BUILD_AESGCM
diff --git a/IDE/MDK-ARM/MDK-ARM/CyaSSL/cyassl_MDK_ARM.c b/IDE/MDK-ARM/MDK-ARM/CyaSSL/cyassl_MDK_ARM.c
index f0959de12..cf63cddf2 100644
--- a/IDE/MDK-ARM/MDK-ARM/CyaSSL/cyassl_MDK_ARM.c
+++ b/IDE/MDK-ARM/MDK-ARM/CyaSSL/cyassl_MDK_ARM.c
@@ -59,7 +59,11 @@ unsigned long inet_addr(const char *cp)
/*** tcp_connect is actually associated with following syassl_tcp_connect. ***/
int Cyassl_connect(int sd, const struct sockaddr* sa, int sz)
{
+<<<<<<< HEAD
int ret = 0 ;
+=======
+ int ret ;
+>>>>>>> cyassl/master
#if defined(CYASSL_KEIL_TCP_NET)
SOCKADDR_IN addr ;
@@ -86,7 +90,11 @@ int Cyassl_connect(int sd, const struct sockaddr* sa, int sz)
int Cyassl_accept(int sd, struct sockaddr *addr, int *addrlen)
{
+<<<<<<< HEAD
int ret = 0 ;
+=======
+ int ret ;
+>>>>>>> cyassl/master
#if defined(CYASSL_KEIL_TCP_NET)
while(1) {
@@ -110,7 +118,11 @@ int Cyassl_accept(int sd, struct sockaddr *addr, int *addrlen)
int Cyassl_recv(int sd, void *buf, size_t len, int flags)
{
+<<<<<<< HEAD
int ret = 0;
+=======
+ int ret ;
+>>>>>>> cyassl/master
#if defined(CYASSL_KEIL_TCP_NET)
while(1) {
#undef recv /* Go to KEIL TCPnet recv */
@@ -132,7 +144,11 @@ int Cyassl_recv(int sd, void *buf, size_t len, int flags)
int Cyassl_send(int sd, const void *buf, size_t len, int flags)
{
+<<<<<<< HEAD
int ret = 0 ;
+=======
+ int ret ;
+>>>>>>> cyassl/master
#if defined(CYASSL_KEIL_TCP_NET)
while(1) {
@@ -170,6 +186,43 @@ int Cyassl_tcp_select(int sd, int timeout)
}
#endif
+<<<<<<< HEAD
+=======
+struct tm *Cyassl_MDK_gmtime(const time_t *c)
+{
+
+ RTC_TimeTypeDef RTC_Time ;
+ RTC_DateTypeDef RTC_Date ;
+ static struct tm date ;
+
+ RTC_GetTime(RTC_Format_BIN, &RTC_Time) ;
+ RTC_GetDate(RTC_Format_BIN, &RTC_Date) ;
+
+ date.tm_year = RTC_Date.RTC_Year + 100 ;
+ date.tm_mon = RTC_Date.RTC_Month - 1 ;
+ date.tm_mday = RTC_Date.RTC_Date ;
+ date.tm_hour = RTC_Time.RTC_Hours ;
+ date.tm_min = RTC_Time.RTC_Minutes ;
+ date.tm_sec = RTC_Time.RTC_Seconds ;
+
+ #if defined(DEBUG_CYASSL)
+ {
+ char msg[100] ;
+ sprintf(msg, "Debug::Cyassl_KEIL_gmtime(DATE=/%4d/%02d/%02d TIME=%02d:%02d:%02d)\n",
+ RTC_Date.RTC_Year+2000, RTC_Date.RTC_Month, RTC_Date.RTC_Date,
+ RTC_Time.RTC_Hours, RTC_Time.RTC_Minutes, RTC_Time.RTC_Seconds) ;
+ CYASSL_MSG(msg) ;
+ }
+ #endif
+
+ return(&date) ;
+}
+
+double current_time()
+{
+ return ((double)TIM2->CNT/1000000.0) ;
+}
+>>>>>>> cyassl/master
extern int getkey(void) ;
extern int sendchar(int c) ;
diff --git a/IDE/MDK-ARM/MDK-ARM/CyaSSL/cyassl_MDK_ARM.h b/IDE/MDK-ARM/MDK-ARM/CyaSSL/cyassl_MDK_ARM.h
index 052fe2991..5da8149cd 100644
--- a/IDE/MDK-ARM/MDK-ARM/CyaSSL/cyassl_MDK_ARM.h
+++ b/IDE/MDK-ARM/MDK-ARM/CyaSSL/cyassl_MDK_ARM.h
@@ -95,9 +95,19 @@ extern int setsockopt(int sockfd, int level, int optname,
extern int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, const struct timeval *timeout);
+<<<<<<< HEAD
/* CyaSSL MDK-ARM time functions */
#include
struct tm *Cyassl_MDK_gmtime(const time_t *c) ;
+=======
+
+/** KEIL-RL gmtime ****/
+
+#include
+#include "stm32f2xx_rtc.h"
+extern struct tm *gmtime(const time_t *timer);
+extern struct tm *Cyassl_MDK_gmtime(const time_t *timer);
+>>>>>>> cyassl/master
extern double current_time(void) ;
#endif /* CYASSL_KEIL_RL_H */
diff --git a/IDE/MDK-ARM/MDK-ARM/CyaSSL/main.c b/IDE/MDK-ARM/MDK-ARM/CyaSSL/main.c
index 7a39b51f4..5781bf2c4 100644
--- a/IDE/MDK-ARM/MDK-ARM/CyaSSL/main.c
+++ b/IDE/MDK-ARM/MDK-ARM/CyaSSL/main.c
@@ -30,6 +30,13 @@
#include
#include "cyassl_MDK_ARM.h"
+<<<<<<< HEAD
+=======
+#include "stm32f2xx_tim.h"
+#include "stm32f2xx_rcc.h"
+
+
+>>>>>>> cyassl/master
/*-----------------------------------------------------------------------------
* Initialize a Flash Memory Card
*----------------------------------------------------------------------------*/
@@ -83,6 +90,80 @@ __task void tcp_poll (void)
}
#endif
+<<<<<<< HEAD
+=======
+/*-----------------------------------------------------------------------------
+ * initialize RTC
+ *----------------------------------------------------------------------------*/
+#include "stm32f2xx_rtc.h"
+#include "stm32f2xx_rcc.h"
+#include "stm32f2xx_pwr.h"
+
+static init_RTC()
+{
+ RTC_InitTypeDef RTC_InitStruct ;
+
+ RTC_TimeTypeDef RTC_Time ;
+ RTC_DateTypeDef RTC_Date ;
+
+
+ /* Enable the PWR clock */
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
+
+ /* Allow access to RTC */
+ PWR_BackupAccessCmd(ENABLE);
+
+/***Configures the External Low Speed oscillator (LSE)****/
+
+ RCC_LSEConfig(RCC_LSE_ON);
+
+ /* Wait till LSE is ready */
+ while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
+ {
+ }
+
+ /* Select the RTC Clock Source */
+ RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
+
+ /* Enable the RTC Clock */
+ RCC_RTCCLKCmd(ENABLE);
+
+ /* Wait for RTC APB registers synchronisation */
+ RTC_WaitForSynchro();
+
+ /* Calendar Configuration with LSI supposed at 32KHz */
+ RTC_InitStruct.RTC_AsynchPrediv = 0x7F;
+ RTC_InitStruct.RTC_SynchPrediv = 0xFF;
+ RTC_InitStruct.RTC_HourFormat = RTC_HourFormat_24;
+ RTC_Init(&RTC_InitStruct);
+
+ RTC_GetTime(RTC_Format_BIN, &RTC_Time) ;
+ RTC_GetDate(RTC_Format_BIN, &RTC_Date) ;
+}
+
+/*-----------------------------------------------------------------------------
+ * initialize TIM
+ *----------------------------------------------------------------------------*/
+void init_timer()
+{
+ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure ;
+
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE) ;
+
+ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
+ TIM_TimeBaseStructure.TIM_Prescaler = 60;
+ TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+ TIM_TimeBaseStructure.TIM_Period = 0xffffffff;
+ TIM_TimeBaseStructure.TIM_ClockDivision = 0;
+ TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
+
+ TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
+
+ TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure) ;
+ TIM_Cmd(TIM2, ENABLE) ;
+}
+
+>>>>>>> cyassl/master
#if defined(HAVE_KEIL_RTX) && defined(CYASSL_MDK_SHELL)
#define SHELL_STACKSIZE 1000
static unsigned char Shell_stack[SHELL_STACKSIZE] ;
@@ -118,12 +199,20 @@ void main_task (void)
shell_main() ;
#endif
#else
+<<<<<<< HEAD
/************************************/
/*** USER APPLICATION HERE ***/
/************************************/
printf("USER LOGIC STARTED\n") ;
+=======
+
+ /************************************/
+ /*** USER APPLICATION HERE ***/
+ /************************************/
+
+>>>>>>> cyassl/master
#endif
#ifdef HAVE_KEIL_RTX
@@ -143,6 +232,7 @@ void main_task (void)
/*** main entry ***/
+<<<<<<< HEAD
extern void init_time(void) ;
extern void SystemInit(void);
@@ -156,6 +246,18 @@ int main() {
init_time() ;
+=======
+int main() {
+ /* stm32_Init (); STM32 setup */
+
+ #if !defined(NO_FILESYSTEM)
+ init_card () ; /* initializing SD card */
+ #endif
+
+ init_RTC() ;
+ init_timer() ;
+ SER_Init() ;
+>>>>>>> cyassl/master
#if defined(DEBUG_CYASSL)
printf("Turning ON Debug message\n") ;
diff --git a/IDE/MDK-ARM/MDK-ARM/CyaSSL/shell.c b/IDE/MDK-ARM/MDK-ARM/CyaSSL/shell.c
index 1a0b6ad73..dca753e8b 100644
--- a/IDE/MDK-ARM/MDK-ARM/CyaSSL/shell.c
+++ b/IDE/MDK-ARM/MDK-ARM/CyaSSL/shell.c
@@ -384,6 +384,42 @@ static void ipaddr_comm(void *args)
#endif
+<<<<<<< HEAD
+=======
+static void time_main(void *args)
+{
+ char * datetime ;
+ RTC_TimeTypeDef RTC_Time ;
+ RTC_DateTypeDef RTC_Date ;
+ int year ;
+ if( args == NULL || ((func_args *)args)->argc == 1) {
+ RTC_GetTime(RTC_Format_BIN, &RTC_Time) ;
+ RTC_GetDate(RTC_Format_BIN, &RTC_Date) ;
+ printf("Date: %d/%d/%d, Time: %02d:%02d:%02d\n",
+ RTC_Date.RTC_Month, RTC_Date.RTC_Date, RTC_Date.RTC_Year+2000,
+ RTC_Time.RTC_Hours, RTC_Time.RTC_Minutes, RTC_Time.RTC_Seconds) ;
+ } else if(((func_args *)args)->argc == 3 &&
+ ((func_args *)args)->argv[1][0] == '-' &&
+ ((func_args *)args)->argv[1][1] == 'd' ) {
+ datetime = ((func_args *)args)->argv[2];
+ sscanf(datetime, "%d/%d/%d",
+ (int *)&RTC_Date.RTC_Month, (int *)&RTC_Date.RTC_Date, &year) ;
+ RTC_Date.RTC_Year = year - 2000 ;
+ RTC_Date.RTC_WeekDay = 0 ;
+ RTC_SetDate(RTC_Format_BIN, &RTC_Date) ;
+ } else if(((func_args *)args)->argc == 3 &&
+ ((func_args *)args)->argv[1][0] == '-' &&
+ ((func_args *)args)->argv[1][1] == 't' ) {
+ datetime = ((func_args *)args)->argv[2];
+ sscanf(datetime, "%d:%d:%d",
+ (int *)&RTC_Time.RTC_Hours,
+ (int *)&RTC_Time.RTC_Minutes,
+ (int *)&RTC_Time.RTC_Seconds
+ ) ;
+ RTC_SetTime(RTC_Format_BIN, &RTC_Time) ;
+ } else printf("Invalid argument\n") ;
+}
+>>>>>>> cyassl/master
#if defined(HAVE_KEIL_RTX)
diff --git a/IDE/MDK-ARM/MDK-ARM/CyaSSL/ssl-dummy.c b/IDE/MDK-ARM/MDK-ARM/CyaSSL/ssl-dummy.c
index 024d10373..3229f03be 100644
--- a/IDE/MDK-ARM/MDK-ARM/CyaSSL/ssl-dummy.c
+++ b/IDE/MDK-ARM/MDK-ARM/CyaSSL/ssl-dummy.c
@@ -45,9 +45,18 @@ int CyaSSL_get_using_nonblock(CYASSL* ssl)
CYASSL_LEAVE("CyaSSL_get_using_nonblock", ssl->options.usingNonblock);
return ssl->options.usingNonblock;
}
+<<<<<<< HEAD
Signer* GetCAByName(void* vp, byte* hash)
{
Signer * ca ;
return(ca) ;
}
+=======
+
+Signer* GetCAByName(void* vp, byte* hash)
+{
+ return NULL;
+}
+
+>>>>>>> cyassl/master
diff --git a/IDE/MDK-ARM/MDK-ARM/config/File_Config.c b/IDE/MDK-ARM/MDK-ARM/config/File_Config.c
index 96b6dada2..d832d06c4 100644
--- a/IDE/MDK-ARM/MDK-ARM/config/File_Config.c
+++ b/IDE/MDK-ARM/MDK-ARM/config/File_Config.c
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
/*----------------------------------------------------------------------------
* RL-ARM - FlashFS
*----------------------------------------------------------------------------
@@ -399,3 +400,392 @@
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
+=======
+/*----------------------------------------------------------------------------
+ * RL-ARM - FlashFS
+ *----------------------------------------------------------------------------
+ * Name: FILE_CONFIG.C
+ * Purpose: Configuration of RL FlashFS by user
+ * Rev.: V4.50
+ *----------------------------------------------------------------------------
+ * This code is part of the RealView Run-Time Library.
+ * Copyright (c) 2004-2012 KEIL - An ARM Company. All rights reserved.
+ *---------------------------------------------------------------------------*/
+
+#include
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
+//
+// File System
+// ==============
+// Define File System global parameters
+
+// Number of open files <4-16>
+// Define number of files that can be
+// opened at the same time.
+// Default: 8
+#define N_FILES 6
+
+// CPU Clock Frequency [Hz]<0-1000000000>
+// Define the CPU Clock frequency used for
+// flash programming and erasing.
+#define CPU_CLK 120000000
+
+//
+// Flash Drive
+// ==============
+// Enable Embedded Flash Drive [F:]
+#define FL0_EN 0
+
+// Base address <0x0-0xFFFFF000:0x1000>
+// Define the target device Base address
+// Default: 0x80000000
+#define FL0_BADR 0x80000000
+
+// Device Size <0x4000-0xFFFFF000:0x4000>
+// Define the size of Flash device in bytes
+// Default: 0x100000 (1MB)
+#define FL0_SIZE 0x0200000
+
+// Content of Erased Memory <0=>0x00 <0xFF=>0xFF
+// Define the initial value for erased Flash data
+// Default: 0xFF
+#define FL0_INITV 0xFF
+
+// Device Description file
+// Specify a file name with a relative path
+// Default: FS_FlashDev.h
+#define FL0_HFILE "FS_FlashDev.h"
+
+// Default Drive [F:]
+// Used when Drive letter not specified
+#define FL0_DEF 1
+
+//
+// SPI Flash Drive
+// ==================
+// Enable SPI Flash Drive [S:]
+#define SF0_EN 0
+
+// Device Size <0x10000-0xFFFFF000:0x8000>
+// Define the size of SPI Flash device in bytes
+// Default: 0x100000 (1MB)
+#define SF0_SIZE 0x0200000
+
+// Content of Erased Memory <0=>0x00 <0xFF=>0xFF
+// Define the initial value for erased Flash data
+// Default: 0xFF
+#define SF0_INITV 0xFF
+
+// Device Description file
+// Specify a file name with a relative path
+// Default: FS_SPI_FlashDev.h
+#define SF0_HFILE "FS_SPI_FlashDev.h"
+
+// Default Drive [S:]
+// Used when Drive letter not specified
+#define SF0_DEF 0
+
+//
+// RAM Drive
+// ============
+// Enable Embedded RAM Drive [R:]
+#define RAM0_EN 0
+
+// Device Size <0x4000-0xFFFFF000:0x4000>
+// Define the size of RAM device in bytes
+// Default: 0x40000
+#define RAM0_SIZE 0x004000
+
+// Number of Sectors <8=>8 <16=>16 <32=>32 <64=>64 <128=>128
+// Define number of virtual sectors for RAM device
+// Default: 32
+#define RAM0_NSECT 64
+
+// Relocate Device Buffer
+// Locate RAM Device Buffer at a specific address.
+// If not enabled, the linker selects base address.
+#define RAM0_RELOC 1
+
+// Base address <0x0-0xFFFFF000:0x1000>
+// Define the target device Base address.
+// Default: 0x81000000
+#define RAM0_BADR 0x81010000
+
+//
+// Default Drive [R:]
+// Used when Drive letter not specified
+#define RAM0_DEF 0
+
+//
+// Memory Card Drive 0
+// ======================
+// Enable Memory Card Drive [M0:]
+#define MC0_EN 1
+
+// Bus Mode <0=>SD-Native <1=>SPI
+// Define Memory Card bus interface mode.
+// SD-Native mode needs MCI peripheral.
+// SPI mode uses SD Card in SPI mode.
+#define MC0_SPI 0
+
+// File System Cache <0=>OFF <1=>1 KB <2=>2 KB <4=>4 KB
+// <8=>8 KB <16=>16 KB <32=>32 KB
+// Define System Cache buffer size for file IO.
+// Increase this number for faster r/w access.
+// Default: 4 kB
+#define MC0_CASZ 16
+
+// Relocate Cache Buffer
+// Locate Cache Buffer at a specific address.
+// Some devices like NXP LPC23xx require a Cache buffer
+// for DMA transfer located at specific address.
+#define MC0_RELOC 0
+
+// Base address <0x0000-0xFFFFFE00:0x200>
+// Define the Cache buffer base address.
+// For LPC23xx/24xx devices this is USB RAM
+// starting at 0x7FD00000.
+#define MC0_CADR 0x7FD00000
+
+//
+// FAT Journal
+// Enable FAT Journal in order to guarantee
+// fail-safe FAT file system operation.
+#define MC0_FSJ 0
+
+// Default Drive [M0:]
+// Used when Drive letter not specified
+#define MC0_DEF 1
+
+//
+// Memory Card Drive 1
+// ======================
+// Enable Memory Card Drive [M1:]
+#define MC1_EN 0
+
+// Bus Mode <0=>SD-Native <1=>SPI
+// Define Memory Card bus interface mode.
+// SD-Native mode needs MCI peripheral.
+// SPI mode uses SD Card in SPI mode.
+#define MC1_SPI 1
+
+// File System Cache <0=>OFF <1=>1 KB <2=>2 KB <4=>4 KB
+// <8=>8 KB <16=>16 KB <32=>32 KB
+// Define System Cache buffer size for file IO.
+// Increase this number for faster r/w access.
+// Default: 4 kB
+#define MC1_CASZ 0
+
+// Relocate Cache Buffer
+// Locate Cache Buffer at a specific address.
+// Some devices like NXP LPC23xx require a Cache buffer
+// for DMA transfer located at specific address.
+#define MC1_RELOC 0
+
+// Base address <0x0000-0xFFFFFE00:0x200>
+// Define the Cache buffer base address.
+// For LPC23xx/24xx devices this is USB RAM
+// starting at 0x7FD00000.
+#define MC1_CADR 0x7FD00000
+
+//
+// FAT Journal
+// Enable FAT Journal in order to guarantee
+// fail-safe FAT file system operation.
+#define MC1_FSJ 0
+
+// Default Drive [M1:]
+// Used when Drive letter not specified
+#define MC1_DEF 0
+
+//
+// USB Flash Drive 0
+// ====================
+// Enable USB Flash Drive [U0:]
+#define USB0_EN 0
+
+// File System Cache <0=>OFF <1=>1 KB <2=>2 KB <4=>4 KB
+// <8=>8 KB <16=>16 KB <32=>32 KB
+// Define System Cache buffer size for file IO.
+// Increase this number for faster r/w access.
+// Default: 4 kB
+#define USB0_CASZ 8
+
+// FAT Journal
+// Enable FAT Journal in order to guarantee
+// fail-safe FAT file system operation.
+#define USB0_FSJ 0
+
+// Default Drive [U0:]
+// Used when Drive letter not specified
+#define USB0_DEF 1
+
+//
+// USB Flash Drive 1
+// ====================
+// Enable USB Flash Drive [U1:]
+#define USB1_EN 0
+
+// File System Cache <0=>OFF <1=>1 KB <2=>2 KB <4=>4 KB
+// <8=>8 KB <16=>16 KB <32=>32 KB
+// Define System Cache buffer size for file IO.
+// Increase this number for faster r/w access.
+// Default: 4 kB
+#define USB1_CASZ 8
+
+// FAT Journal
+// Enable FAT Journal in order to guarantee
+// fail-safe FAT file system operation.
+#define USB1_FSJ 0
+
+// Default Drive [U1:]
+// Used when Drive letter not specified
+#define USB1_DEF 1
+
+//
+// NAND Flash Drive 0
+// ===================
+// Enable NAND Flash Drive [N0:]
+#define NAND0_EN 0
+
+// Page size <528=> 512 + 16 bytes
+// <2112=>2048 + 64 bytes
+// <4224=>4096 + 128 bytes
+// <8448=>8192 + 256 bytes
+// Define program Page size in bytes (User + Spare area).
+#define NAND0_PGSZ 2112
+
+// Block Size <8=>8 pages <16=>16 pages <32=>32 pages
+// <64=>64 pages <128=>128 pages <256=>256 pages
+// Define number of pages in a block.
+#define NAND0_PGCNT 64
+
+// Device Size [blocks] <512-32768>
+// Define number of blocks in NAND Flash device.
+#define NAND0_BLCNT 4096
+
+// Page Caching <0=>OFF <1=>1 page <2=>2 pages <4=>4 pages
+// <8=>8 pages <16=>16 pages <32=>32 pages
+// Define number of cached Pages.
+// Default: 4 pages
+#define NAND0_CAPG 2
+
+// Block Indexing <0=>OFF <1=>1 block <2=>2 blocks <4=>4 blocks
+// <8=>8 blocks <16=>16 blocks <32=>32 blocks
+// <64=>64 blocks <128=>128 blocks <256=>256 blocks
+// Define number of indexed Flash Blocks.
+// Increase this number for better performance.
+// Default: 16 blocks
+#define NAND0_CABL 16
+
+// Software ECC <0=>None <1=>Hamming (SLC)
+// Enable software ECC calculation only,
+// if not supported by hardware.
+#define NAND0_SWECC 1
+
+// File System Cache <0=>OFF <1=>1 KB <2=>2 KB <4=>4 KB
+// <8=>8 KB <16=>16 KB <32=>32 KB
+// Define System Cache buffer size for file IO.
+// Increase this number for faster r/w access.
+// Default: 4 kB
+#define NAND0_CASZ 4
+
+// Relocate Cache Buffers
+// Use this option to locate Cache buffers
+// at specific address in RAM or SDRAM.
+#define NAND0_RELOC 0
+
+// Base address <0x0000-0xFFFFFE00:0x200>
+// Define base address for Cache Buffers.
+#define NAND0_CADR 0x80000000
+
+//
+// FAT Journal
+// Enable FAT Journal in order to guarantee
+// fail-safe FAT file system operation.
+#define NAND0_FSJ 0
+
+// Default Drive [N0:]
+// Used when Drive letter not specified
+#define NAND0_DEF 0
+
+//
+// NAND Flash Drive 1
+// ===================
+// Enable NAND Flash Drive [N1:]
+#define NAND1_EN 0
+
+// Page size <528=> 512 + 16 bytes
+// <2112=>2048 + 64 bytes
+// <4224=>4096 + 128 bytes
+// <8448=>8192 + 256 bytes
+// Define program Page size in bytes (User + Spare area).
+#define NAND1_PGSZ 2112
+
+// Block Size <8=>8 pages <16=>16 pages <32=>32 pages
+// <64=>64 pages <128=>128 pages <256=>256 pages
+// Define number of pages in a block.
+#define NAND1_PGCNT 32
+
+// Device Size [blocks] <512-32768>
+// Define number of blocks in NAND Flash device.
+#define NAND1_BLCNT 512
+
+// Page Caching <0=>OFF <1=>1 page <2=>2 pages <4=>4 pages
+// <8=>8 pages <16=>16 pages <32=>32 pages
+// Define number of cached Pages.
+// Default: 4 pages
+#define NAND1_CAPG 4
+
+// Block Indexing <0=>OFF <1=>1 block <2=>2 blocks <4=>4 blocks
+// <8=>8 blocks <16=>16 blocks <32=>32 blocks
+// <64=>64 blocks <128=>128 blocks <256=>256 blocks
+// Define number of indexed Flash Blocks.
+// Increase this number for better performance.
+// Default: 16 blocks
+#define NAND1_CABL 16
+
+// Software ECC <0=>None <1=>Hamming (SLC)
+// Enable software ECC calculation only,
+// if not supported by hardware.
+#define NAND1_SWECC 0
+
+// File System Cache <0=>OFF <1=>1 KB <2=>2 KB <4=>4 KB
+// <8=>8 KB <16=>16 KB <32=>32 KB
+// Define System Cache buffer size for file IO.
+// Increase this number for faster r/w access.
+// Default: 4 kB
+#define NAND1_CASZ 4
+
+// Relocate Cache Buffers
+// Use this option to locate Cache buffers
+// at specific address in RAM or SDRAM.
+#define NAND1_RELOC 0
+
+// Base address <0x0000-0xFFFFFE00:0x200>
+// Define base address for Cache Buffers.
+#define NAND1_CADR 0x80000000
+
+//
+// FAT Journal
+// Enable FAT Journal in order to guarantee
+// fail-safe FAT file system operation.
+#define NAND1_FSJ 0
+
+// Default Drive [N1:]
+// Used when Drive letter not specified
+#define NAND1_DEF 0
+
+//
+
+//------------- <<< end of configuration section >>> -----------------------
+
+#ifndef __NO_FILE_LIB_C
+#include
+#endif
+
+/*----------------------------------------------------------------------------
+ * end of file
+ *---------------------------------------------------------------------------*/
+>>>>>>> cyassl/master
diff --git a/IDE/MDK-ARM/MDK-ARM/config/RTX_Conf_CM.c b/IDE/MDK-ARM/MDK-ARM/config/RTX_Conf_CM.c
index a03892045..64831708a 100644
--- a/IDE/MDK-ARM/MDK-ARM/config/RTX_Conf_CM.c
+++ b/IDE/MDK-ARM/MDK-ARM/config/RTX_Conf_CM.c
@@ -39,7 +39,11 @@
// Set the stack size for tasks which is assigned by the system.
// Default: 512
#ifndef OS_STKSIZE
+<<<<<<< HEAD
#define OS_STKSIZE 499
+=======
+ #define OS_STKSIZE 250
+>>>>>>> cyassl/master
#endif
// Check for the stack overflow
diff --git a/IDE/MDK-ARM/Projects/MDK-ARM-STM32F2xx.uvopt b/IDE/MDK-ARM/Projects/MDK-ARM-STM32F2xx.uvopt
index 89ee2a1d5..6cec49314 100644
--- a/IDE/MDK-ARM/Projects/MDK-ARM-STM32F2xx.uvopt
+++ b/IDE/MDK-ARM/Projects/MDK-ARM-STM32F2xx.uvopt
@@ -490,7 +490,11 @@
CyaSSL Apps
+<<<<<<< HEAD
0
+=======
+ 1
+>>>>>>> cyassl/master
0
0
0
@@ -614,8 +618,13 @@
0
0
0
+<<<<<<< HEAD
135
149
+=======
+ 209
+ 220
+>>>>>>> cyassl/master
0
..\MDK-ARM\CyaSSL\main.c
main.c
@@ -762,7 +771,11 @@
MDK-ARM
+<<<<<<< HEAD
0
+=======
+ 1
+>>>>>>> cyassl/master
0
0
0
@@ -774,8 +787,13 @@
0
0
0
+<<<<<<< HEAD
39
73
+=======
+ 42
+ 66
+>>>>>>> cyassl/master
0
c:\Keil\ARM\Boards\Keil\MCBSTM32F200\RL\FlashFS\SD_File\Serial.c
Serial.c
@@ -898,7 +916,11 @@
CyaSSL Library
+<<<<<<< HEAD
0
+=======
+ 1
+>>>>>>> cyassl/master
0
0
0
@@ -1050,7 +1072,11 @@
Crypt/Cipher Library
+<<<<<<< HEAD
0
+=======
+ 1
+>>>>>>> cyassl/master
0
0
0
@@ -1428,10 +1454,17 @@
1
0
0
+<<<<<<< HEAD
30
0
560
570
+=======
+ 0
+ 0
+ 0
+ 0
+>>>>>>> cyassl/master
0
..\..\..\ctaocrypt\src\random.c
random.c
@@ -1446,8 +1479,13 @@
0
0
0
+<<<<<<< HEAD
1
1
+=======
+ 0
+ 0
+>>>>>>> cyassl/master
0
..\..\..\ctaocrypt\src\ripemd.c
ripemd.c
@@ -1538,7 +1576,11 @@
Configuration
+<<<<<<< HEAD
0
+=======
+ 1
+>>>>>>> cyassl/master
0
0
0
@@ -1678,7 +1720,11 @@
0
0
0
+<<<<<<< HEAD
163
+=======
+ 165
+>>>>>>> cyassl/master
169
0
..\MDK-ARM\config\startup_stm32f2xx.s
@@ -1698,7 +1744,11 @@
7
73
1
+<<<<<<< HEAD
0
+=======
+ 1
+>>>>>>> cyassl/master
0
0
0
@@ -1714,18 +1764,28 @@
7
74
1
+<<<<<<< HEAD
0
0
0
0
51
57
+=======
+ 1
+ 0
+ 0
+ 0
+ 52
+ 56
+>>>>>>> cyassl/master
0
..\MDK-ARM\CyaSSL\Retarget.c
Retarget.c
0
0
+<<<<<<< HEAD
7
75
@@ -1742,6 +1802,8 @@
0
0
+=======
+>>>>>>> cyassl/master
diff --git a/IDE/MDK-ARM/Projects/MDK-ARM-STM32F2xx.uvproj b/IDE/MDK-ARM/Projects/MDK-ARM-STM32F2xx.uvproj
index 222ef456f..759667845 100644
--- a/IDE/MDK-ARM/Projects/MDK-ARM-STM32F2xx.uvproj
+++ b/IDE/MDK-ARM/Projects/MDK-ARM-STM32F2xx.uvproj
@@ -44,7 +44,11 @@
1
.\MDK-RTX-TCP-FS\
+<<<<<<< HEAD
STM32F2xx-MDK-RTX-TCP-FS
+=======
+ MDK-RTX-TCP-FS
+>>>>>>> cyassl/master
1
0
0
@@ -349,7 +353,11 @@
0
+<<<<<<< HEAD
HAVE_CONFIG_H CYASSL_STM32F2xx __DBG_ITM __RTX USE_STDPERIPH_DRIVER MDK_CONF_RTX_TCP_FS
+=======
+ HAVE_CONFIG_H __DBG_ITM __RTX USE_STDPERIPH_DRIVER MDK_CONF_RTX_TCP_FS
+>>>>>>> cyassl/master
..\MDK-ARM\CyaSSL;C:..\STM32F2xx_StdPeriph_Lib\inc;..\..\..\
@@ -930,11 +938,14 @@
1
..\MDK-ARM\CyaSSL\Retarget.c
+<<<<<<< HEAD
time-STM32F2xx.c
1
..\STM32F2xx_StdPeriph_Lib\time-STM32F2xx.c
+=======
+>>>>>>> cyassl/master
@@ -977,7 +988,11 @@
1
.\MDK-FS\
+<<<<<<< HEAD
STM32F2xx-MDK-FS
+=======
+ MDK-FS
+>>>>>>> cyassl/master
1
0
0
@@ -1282,7 +1297,11 @@
0
+<<<<<<< HEAD
HAVE_CONFIG_H CYASSL_STM32F2xx __DBG_ITM USE_STDPERIPH_DRIVER MDK_CONF_FS
+=======
+ HAVE_CONFIG_H __DBG_ITM USE_STDPERIPH_DRIVER MDK_CONF_FS
+>>>>>>> cyassl/master
..\MDK-ARM\CyaSSL;..\MDK-ARM\inc;..\STM32F2xx_StdPeriph_Lib\inc;..\POSIX\..\..\..\
@@ -2139,11 +2158,14 @@
1
..\MDK-ARM\CyaSSL\Retarget.c
+<<<<<<< HEAD
time-STM32F2xx.c
1
..\STM32F2xx_StdPeriph_Lib\time-STM32F2xx.c
+=======
+>>>>>>> cyassl/master
@@ -2186,7 +2208,11 @@
1
.\MDK-BARE-METAL\
+<<<<<<< HEAD
STM32F2xx-MDK-BARE-METAL
+=======
+ MDK-BARE-METAL
+>>>>>>> cyassl/master
1
0
0
@@ -2491,7 +2517,11 @@
0
+<<<<<<< HEAD
HAVE_CONFIG_H CYASSL_STM32F2xx __DBG_ITM USE_STDPERIPH_DRIVER MDK_CONF_BARE_METAL
+=======
+ HAVE_CONFIG_H __DBG_ITM USE_STDPERIPH_DRIVER MDK_CONF_BARE_METAL
+>>>>>>> cyassl/master
..\MDK-ARM\CyaSSL;..\MDK-ARM\inc;..\STM32F2xx_StdPeriph_Lib\inc;..\POSIX;..\..\..\
@@ -3566,11 +3596,14 @@
1
..\MDK-ARM\CyaSSL\Retarget.c
+<<<<<<< HEAD
time-STM32F2xx.c
1
..\STM32F2xx_StdPeriph_Lib\time-STM32F2xx.c
+=======
+>>>>>>> cyassl/master
diff --git a/configure.ac b/configure.ac
index c1d02e8af..c6bcddb4e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1049,6 +1049,18 @@ then
AC_MSG_ERROR([cannot enable ntru and small, ntru requires TLS which small turns off.])
fi
+# SNI
+AC_ARG_ENABLE([sni],
+ [ --enable-sni Enable SNI (default: disabled)],
+ [ ENABLED_SNI=$enableval ],
+ [ ENABLED_SNI=no ]
+ )
+
+if test "x$ENABLED_SNI" = "xyes"
+then
+ AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI"
+fi
+
#valgrind
AC_ARG_ENABLE([valgrind],
@@ -1415,6 +1427,7 @@ echo " * CRL-MONITOR: $ENABLED_CRL_MONITOR"
echo " * Persistent session cache: $ENABLED_SAVESESSION"
echo " * Persistent cert cache: $ENABLED_SAVECERT"
echo " * NTRU: $ENABLED_NTRU"
+echo " * SNI: $ENABLED_SNI"
echo " * valgrind unit tests: $ENABLED_VALGRIND"
echo " * LIBZ: $ENABLED_LIBZ"
echo " * Examples: $ENABLED_EXAMPLES"
diff --git a/ctaocrypt/src/random.c b/ctaocrypt/src/random.c
index 8b3633ad4..fb99c0c58 100644
--- a/ctaocrypt/src/random.c
+++ b/ctaocrypt/src/random.c
@@ -580,7 +580,14 @@ int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
#elif defined(NO_DEV_RANDOM)
#error "you need to write an os specific GenerateSeed() here"
-int GenerateSeed(OS_Seed* os, byte* output, word32 sz) { return(0) ; }
+
+/*
+int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
+{
+ return 0;
+}
+*/
+
#else /* !USE_WINDOWS_API && !THREADX && !MICRIUM && !NO_DEV_RANDOM */
diff --git a/ctaocrypt/src/tfm.c b/ctaocrypt/src/tfm.c
index a07ee198a..e4a732409 100644
--- a/ctaocrypt/src/tfm.c
+++ b/ctaocrypt/src/tfm.c
@@ -26,7 +26,7 @@
*/
/**
- * Edited by Moisés Guimarães (moises.guimaraes@phoebus.com.br)
+ * Edited by Moisés Guimarães (moisesguimaraesm@gmail.com)
* to fit CyaSSL's needs.
*/
@@ -1183,16 +1183,16 @@ static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
{
- fp_int tmp;
- int err;
-
/* prevent overflows */
if (P->used > (FP_SIZE/2)) {
return FP_VAL;
}
- /* is X negative? */
if (X->sign == FP_NEG) {
+#ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */
+ int err;
+ fp_int tmp;
+
/* yes, copy G and invmod it */
fp_copy(G, &tmp);
if ((err = fp_invmod(&tmp, P, &tmp)) != FP_OKAY) {
@@ -1204,7 +1204,11 @@ int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
X->sign = FP_NEG;
}
return err;
- } else {
+#else
+ return FP_VAL;
+#endif
+ }
+ else {
/* Positive exponent so just exptmod */
return _fp_exptmod(G, X, P, Y);
}
diff --git a/cyassl/ctaocrypt/types.h b/cyassl/ctaocrypt/types.h
index 6f0282798..9d367feab 100644
--- a/cyassl/ctaocrypt/types.h
+++ b/cyassl/ctaocrypt/types.h
@@ -202,30 +202,30 @@ enum {
/* memory allocation types for user hints */
enum {
- DYNAMIC_TYPE_CA = 1,
- DYNAMIC_TYPE_CERT = 2,
- DYNAMIC_TYPE_KEY = 3,
- DYNAMIC_TYPE_FILE = 4,
- DYNAMIC_TYPE_SUBJECT_CN = 5,
- DYNAMIC_TYPE_PUBLIC_KEY = 6,
- DYNAMIC_TYPE_SIGNER = 7,
- DYNAMIC_TYPE_NONE = 8,
- DYNAMIC_TYPE_BIGINT = 9,
- DYNAMIC_TYPE_RSA = 10,
- DYNAMIC_TYPE_METHOD = 11,
- DYNAMIC_TYPE_OUT_BUFFER = 12,
- DYNAMIC_TYPE_IN_BUFFER = 13,
- DYNAMIC_TYPE_INFO = 14,
- DYNAMIC_TYPE_DH = 15,
- DYNAMIC_TYPE_DOMAIN = 16,
- DYNAMIC_TYPE_SSL = 17,
- DYNAMIC_TYPE_CTX = 18,
- DYNAMIC_TYPE_WRITEV = 19,
- DYNAMIC_TYPE_OPENSSL = 20,
- DYNAMIC_TYPE_DSA = 21,
- DYNAMIC_TYPE_CRL = 22,
- DYNAMIC_TYPE_REVOKED = 23,
- DYNAMIC_TYPE_CRL_ENTRY = 24,
+ DYNAMIC_TYPE_CA = 1,
+ DYNAMIC_TYPE_CERT = 2,
+ DYNAMIC_TYPE_KEY = 3,
+ DYNAMIC_TYPE_FILE = 4,
+ DYNAMIC_TYPE_SUBJECT_CN = 5,
+ DYNAMIC_TYPE_PUBLIC_KEY = 6,
+ DYNAMIC_TYPE_SIGNER = 7,
+ DYNAMIC_TYPE_NONE = 8,
+ DYNAMIC_TYPE_BIGINT = 9,
+ DYNAMIC_TYPE_RSA = 10,
+ DYNAMIC_TYPE_METHOD = 11,
+ DYNAMIC_TYPE_OUT_BUFFER = 12,
+ DYNAMIC_TYPE_IN_BUFFER = 13,
+ DYNAMIC_TYPE_INFO = 14,
+ DYNAMIC_TYPE_DH = 15,
+ DYNAMIC_TYPE_DOMAIN = 16,
+ DYNAMIC_TYPE_SSL = 17,
+ DYNAMIC_TYPE_CTX = 18,
+ DYNAMIC_TYPE_WRITEV = 19,
+ DYNAMIC_TYPE_OPENSSL = 20,
+ DYNAMIC_TYPE_DSA = 21,
+ DYNAMIC_TYPE_CRL = 22,
+ DYNAMIC_TYPE_REVOKED = 23,
+ DYNAMIC_TYPE_CRL_ENTRY = 24,
DYNAMIC_TYPE_CERT_MANAGER = 25,
DYNAMIC_TYPE_CRL_MONITOR = 26,
DYNAMIC_TYPE_OCSP_STATUS = 27,
@@ -243,7 +243,8 @@ enum {
DYNAMIC_TYPE_DTLS_MSG = 39,
DYNAMIC_TYPE_CAVIUM_TMP = 40,
DYNAMIC_TYPE_CAVIUM_RSA = 41,
- DYNAMIC_TYPE_X509 = 42
+ DYNAMIC_TYPE_X509 = 42,
+ DYNAMIC_TYPE_TLSX = 43
};
/* stack protection */
diff --git a/cyassl/error.h b/cyassl/error.h
index 0854813d9..3f60642c9 100644
--- a/cyassl/error.h
+++ b/cyassl/error.h
@@ -30,94 +30,95 @@
#endif
enum CyaSSL_ErrorCodes {
- INPUT_CASE_ERROR = -201, /* process input state error */
- PREFIX_ERROR = -202, /* bad index to key rounds */
- MEMORY_ERROR = -203, /* out of memory */
- VERIFY_FINISHED_ERROR = -204, /* verify problem on finished */
- VERIFY_MAC_ERROR = -205, /* verify mac problem */
- PARSE_ERROR = -206, /* parse error on header */
- UNKNOWN_HANDSHAKE_TYPE = -207, /* weird handshake type */
- SOCKET_ERROR_E = -208, /* error state on socket */
- SOCKET_NODATA = -209, /* expected data, not there */
- INCOMPLETE_DATA = -210, /* don't have enough data to
- complete task */
- UNKNOWN_RECORD_TYPE = -211, /* unknown type in record hdr */
- DECRYPT_ERROR = -212, /* error during decryption */
- FATAL_ERROR = -213, /* recvd alert fatal error */
- ENCRYPT_ERROR = -214, /* error during encryption */
- FREAD_ERROR = -215, /* fread problem */
- NO_PEER_KEY = -216, /* need peer's key */
- NO_PRIVATE_KEY = -217, /* need the private key */
- RSA_PRIVATE_ERROR = -218, /* error during rsa priv op */
- NO_DH_PARAMS = -219, /* server missing DH params */
- BUILD_MSG_ERROR = -220, /* build message failure */
+ INPUT_CASE_ERROR = -201, /* process input state error */
+ PREFIX_ERROR = -202, /* bad index to key rounds */
+ MEMORY_ERROR = -203, /* out of memory */
+ VERIFY_FINISHED_ERROR = -204, /* verify problem on finished */
+ VERIFY_MAC_ERROR = -205, /* verify mac problem */
+ PARSE_ERROR = -206, /* parse error on header */
+ UNKNOWN_HANDSHAKE_TYPE = -207, /* weird handshake type */
+ SOCKET_ERROR_E = -208, /* error state on socket */
+ SOCKET_NODATA = -209, /* expected data, not there */
+ INCOMPLETE_DATA = -210, /* don't have enough data to
+ complete task */
+ UNKNOWN_RECORD_TYPE = -211, /* unknown type in record hdr */
+ DECRYPT_ERROR = -212, /* error during decryption */
+ FATAL_ERROR = -213, /* recvd alert fatal error */
+ ENCRYPT_ERROR = -214, /* error during encryption */
+ FREAD_ERROR = -215, /* fread problem */
+ NO_PEER_KEY = -216, /* need peer's key */
+ NO_PRIVATE_KEY = -217, /* need the private key */
+ RSA_PRIVATE_ERROR = -218, /* error during rsa priv op */
+ NO_DH_PARAMS = -219, /* server missing DH params */
+ BUILD_MSG_ERROR = -220, /* build message failure */
- BAD_HELLO = -221, /* client hello malformed */
- DOMAIN_NAME_MISMATCH = -222, /* peer subject name mismatch */
- WANT_READ = -223, /* want read, call again */
- NOT_READY_ERROR = -224, /* handshake layer not ready */
- PMS_VERSION_ERROR = -225, /* pre m secret version error */
- VERSION_ERROR = -226, /* record layer version error */
- WANT_WRITE = -227, /* want write, call again */
- BUFFER_ERROR = -228, /* malformed buffer input */
- VERIFY_CERT_ERROR = -229, /* verify cert error */
- VERIFY_SIGN_ERROR = -230, /* verify sign error */
- CLIENT_ID_ERROR = -231, /* psk client identity error */
- SERVER_HINT_ERROR = -232, /* psk server hint error */
- PSK_KEY_ERROR = -233, /* psk key error */
- ZLIB_INIT_ERROR = -234, /* zlib init error */
- ZLIB_COMPRESS_ERROR = -235, /* zlib compression error */
- ZLIB_DECOMPRESS_ERROR = -236, /* zlib decompression error */
+ BAD_HELLO = -221, /* client hello malformed */
+ DOMAIN_NAME_MISMATCH = -222, /* peer subject name mismatch */
+ WANT_READ = -223, /* want read, call again */
+ NOT_READY_ERROR = -224, /* handshake layer not ready */
+ PMS_VERSION_ERROR = -225, /* pre m secret version error */
+ VERSION_ERROR = -226, /* record layer version error */
+ WANT_WRITE = -227, /* want write, call again */
+ BUFFER_ERROR = -228, /* malformed buffer input */
+ VERIFY_CERT_ERROR = -229, /* verify cert error */
+ VERIFY_SIGN_ERROR = -230, /* verify sign error */
+ CLIENT_ID_ERROR = -231, /* psk client identity error */
+ SERVER_HINT_ERROR = -232, /* psk server hint error */
+ PSK_KEY_ERROR = -233, /* psk key error */
+ ZLIB_INIT_ERROR = -234, /* zlib init error */
+ ZLIB_COMPRESS_ERROR = -235, /* zlib compression error */
+ ZLIB_DECOMPRESS_ERROR = -236, /* zlib decompression error */
- GETTIME_ERROR = -237, /* gettimeofday failed ??? */
- GETITIMER_ERROR = -238, /* getitimer failed ??? */
- SIGACT_ERROR = -239, /* sigaction failed ??? */
- SETITIMER_ERROR = -240, /* setitimer failed ??? */
- LENGTH_ERROR = -241, /* record layer length error */
- PEER_KEY_ERROR = -242, /* can't decode peer key */
- ZERO_RETURN = -243, /* peer sent close notify */
- SIDE_ERROR = -244, /* wrong client/server type */
- NO_PEER_CERT = -245, /* peer didn't send key */
- NTRU_KEY_ERROR = -246, /* NTRU key error */
- NTRU_DRBG_ERROR = -247, /* NTRU drbg error */
- NTRU_ENCRYPT_ERROR = -248, /* NTRU encrypt error */
- NTRU_DECRYPT_ERROR = -249, /* NTRU decrypt error */
- ECC_CURVETYPE_ERROR = -250, /* Bad ECC Curve Type */
- ECC_CURVE_ERROR = -251, /* Bad ECC Curve */
- ECC_PEERKEY_ERROR = -252, /* Bad Peer ECC Key */
- ECC_MAKEKEY_ERROR = -253, /* Bad Make ECC Key */
- ECC_EXPORT_ERROR = -254, /* Bad ECC Export Key */
- ECC_SHARED_ERROR = -255, /* Bad ECC Shared Secret */
- BAD_MUTEX_ERROR = -256, /* Bad mutex */
- NOT_CA_ERROR = -257, /* Not a CA cert error */
- BAD_PATH_ERROR = -258, /* Bad path for opendir */
- BAD_CERT_MANAGER_ERROR = -259, /* Bad Cert Manager */
- OCSP_CERT_REVOKED = -260, /* OCSP Certificate revoked */
- CRL_CERT_REVOKED = -261, /* CRL Certificate revoked */
- CRL_MISSING = -262, /* CRL Not loaded */
- MONITOR_RUNNING_E = -263, /* CRL Monitor already running */
- THREAD_CREATE_E = -264, /* Thread Create Error */
- OCSP_NEED_URL = -265, /* OCSP need an URL for lookup */
- OCSP_CERT_UNKNOWN = -266, /* OCSP responder doesn't know */
- OCSP_LOOKUP_FAIL = -267, /* OCSP lookup not successful */
- MAX_CHAIN_ERROR = -268, /* max chain depth exceeded */
- COOKIE_ERROR = -269, /* dtls cookie error */
- SEQUENCE_ERROR = -270, /* dtls sequence error */
- SUITES_ERROR = -271, /* suites pointer error */
- SSL_NO_PEM_HEADER = -272, /* no PEM header found */
- OUT_OF_ORDER_E = -273, /* out of order message */
- BAD_KEA_TYPE_E = -274, /* bad KEA type found */
- SANITY_CIPHER_E = -275, /* sanity check on cipher error */
- RECV_OVERFLOW_E = -276, /* RXCB returned more than rqed */
- GEN_COOKIE_E = -277, /* Generate Cookie Error */
- NO_PEER_VERIFY = -278, /* Need peer cert verify Error */
- FWRITE_ERROR = -279, /* fwrite problem */
- CACHE_MATCH_ERROR = -280, /* cache hdr match err */
+ GETTIME_ERROR = -237, /* gettimeofday failed ??? */
+ GETITIMER_ERROR = -238, /* getitimer failed ??? */
+ SIGACT_ERROR = -239, /* sigaction failed ??? */
+ SETITIMER_ERROR = -240, /* setitimer failed ??? */
+ LENGTH_ERROR = -241, /* record layer length error */
+ PEER_KEY_ERROR = -242, /* can't decode peer key */
+ ZERO_RETURN = -243, /* peer sent close notify */
+ SIDE_ERROR = -244, /* wrong client/server type */
+ NO_PEER_CERT = -245, /* peer didn't send key */
+ NTRU_KEY_ERROR = -246, /* NTRU key error */
+ NTRU_DRBG_ERROR = -247, /* NTRU drbg error */
+ NTRU_ENCRYPT_ERROR = -248, /* NTRU encrypt error */
+ NTRU_DECRYPT_ERROR = -249, /* NTRU decrypt error */
+ ECC_CURVETYPE_ERROR = -250, /* Bad ECC Curve Type */
+ ECC_CURVE_ERROR = -251, /* Bad ECC Curve */
+ ECC_PEERKEY_ERROR = -252, /* Bad Peer ECC Key */
+ ECC_MAKEKEY_ERROR = -253, /* Bad Make ECC Key */
+ ECC_EXPORT_ERROR = -254, /* Bad ECC Export Key */
+ ECC_SHARED_ERROR = -255, /* Bad ECC Shared Secret */
+ BAD_MUTEX_ERROR = -256, /* Bad mutex */
+ NOT_CA_ERROR = -257, /* Not a CA cert error */
+ BAD_PATH_ERROR = -258, /* Bad path for opendir */
+ BAD_CERT_MANAGER_ERROR = -259, /* Bad Cert Manager */
+ OCSP_CERT_REVOKED = -260, /* OCSP Certificate revoked */
+ CRL_CERT_REVOKED = -261, /* CRL Certificate revoked */
+ CRL_MISSING = -262, /* CRL Not loaded */
+ MONITOR_RUNNING_E = -263, /* CRL Monitor already running */
+ THREAD_CREATE_E = -264, /* Thread Create Error */
+ OCSP_NEED_URL = -265, /* OCSP need an URL for lookup */
+ OCSP_CERT_UNKNOWN = -266, /* OCSP responder doesn't know */
+ OCSP_LOOKUP_FAIL = -267, /* OCSP lookup not successful */
+ MAX_CHAIN_ERROR = -268, /* max chain depth exceeded */
+ COOKIE_ERROR = -269, /* dtls cookie error */
+ SEQUENCE_ERROR = -270, /* dtls sequence error */
+ SUITES_ERROR = -271, /* suites pointer error */
+ SSL_NO_PEM_HEADER = -272, /* no PEM header found */
+ OUT_OF_ORDER_E = -273, /* out of order message */
+ BAD_KEA_TYPE_E = -274, /* bad KEA type found */
+ SANITY_CIPHER_E = -275, /* sanity check on cipher error */
+ RECV_OVERFLOW_E = -276, /* RXCB returned more than rqed */
+ GEN_COOKIE_E = -277, /* Generate Cookie Error */
+ NO_PEER_VERIFY = -278, /* Need peer cert verify Error */
+ FWRITE_ERROR = -279, /* fwrite problem */
+ CACHE_MATCH_ERROR = -280, /* chache hdr match error */
+ UNKNOWN_SNI_HOST_NAME_E = -281, /* Unrecognized host name Error */
/* add strings to SetErrorString !!!!! */
/* begin negotiation parameter errors */
- UNSUPPORTED_SUITE = -290, /* unsupported cipher suite */
- MATCH_SUITE_ERROR = -291 /* can't match cipher suite */
+ UNSUPPORTED_SUITE = -290, /* unsupported cipher suite */
+ MATCH_SUITE_ERROR = -291 /* can't match cipher suite */
/* end negotiation parameter errors only 10 for now */
/* add strings to SetErrorString !!!!! */
};
diff --git a/cyassl/internal.h b/cyassl/internal.h
index 36c615922..89f34b5a6 100644
--- a/cyassl/internal.h
+++ b/cyassl/internal.h
@@ -561,7 +561,7 @@ enum Misc {
digest sz + BLOC_SZ (iv) + pad byte (1) */
MAX_COMP_EXTRA = 1024, /* max compression extra */
MAX_MTU = 1500, /* max expected MTU */
- MAX_UDP_SIZE = MAX_MTU - 100, /* don't exceed MTU w/ 100 byte header */
+ MAX_UDP_SIZE = 8192 - 100, /* was MAX_MTU - 100 */
MAX_DH_SZ = 612, /* 2240 p, pub, g + 2 byte size for each */
MAX_STR_VERSION = 8, /* string rep of protocol version */
@@ -592,18 +592,20 @@ enum Misc {
COOKIE_SZ = 20, /* use a 20 byte cookie */
SUITE_LEN = 2, /* cipher suite sz length */
ENUM_LEN = 1, /* always a byte */
+ OPAQUE16_LEN = 2, /* always 2 bytes */
COMP_LEN = 1, /* compression length */
CURVE_LEN = 2, /* ecc named curve length */
SERVER_ID_LEN = 20, /* server session id 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 */
- HELLO_EXT_SZ = 8, /* total length of the lazy hello extensions */
- HELLO_EXT_LEN = 6, /* length of the lazy hello extensions */
- HELLO_EXT_SIGALGO_SZ = 2, /* length of signature algo extension */
+ 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 */
+ HELLO_EXT_TYPE_SZ = 2, /* length of a hello extension type */
+ HELLO_EXT_SZ = 8, /* total length of the lazy hello extensions */
+ HELLO_EXT_LEN = 6, /* length of the lazy hello extensions */
+ HELLO_EXT_SIGALGO_SZ = 2, /* length of signature algo extension */
HELLO_EXT_SIGALGO_MAX = 32, /* number of items in the signature algo list */
DTLS_HANDSHAKE_HEADER_SZ = 12, /* normal + seq(2) + offset(3) + length(3) */
@@ -832,6 +834,14 @@ enum {
#define MTU_EXTRA 0
#endif
+
+/* embedded callbacks require large static buffers, make sure on */
+#ifdef CYASSL_CALLBACKS
+ #undef LARGE_STATIC_BUFFERS
+ #define LARGE_STATIC_BUFFERS
+#endif
+
+
/* give user option to use 16K static buffers */
#if defined(LARGE_STATIC_BUFFERS)
#define RECORD_SIZE MAX_RECORD_SIZE
@@ -1102,6 +1112,61 @@ typedef struct CYASSL_DTLS_CTX {
int fd;
} CYASSL_DTLS_CTX;
+/* RFC 6066 TLS Extensions */
+#ifdef HAVE_TLS_EXTENSIONS
+
+typedef enum {
+ SERVER_NAME_INDICATION = 0,/*
+ MAX_FRAGMENT_LENGTH = 1,
+ CLIENT_CERTIFICATE_URL = 2,
+ TRUSTED_CA_KEYS = 3,
+ TRUNCATED_HMAC = 4,
+ STATUS_REQUEST = 5,
+ SIGNATURE_ALGORITHMS = 13,*/
+} TLSX_Type;
+
+typedef struct TLSX {
+ TLSX_Type type; /* Extension Type */
+ void* data; /* Extension Data */
+ byte resp; /* IsResponse Flag */
+ struct TLSX* next; /* List Behavior */
+} TLSX;
+
+CYASSL_LOCAL TLSX* TLSX_Find(TLSX* list, TLSX_Type type);
+CYASSL_LOCAL void TLSX_FreeAll(TLSX* list);
+
+#ifndef NO_CYASSL_CLIENT
+CYASSL_LOCAL word16 TLSX_GetRequestSize(CYASSL* ssl);
+CYASSL_LOCAL word16 TLSX_WriteRequest(CYASSL* ssl, byte* output);
+#endif
+
+#ifndef NO_CYASSL_SERVER
+CYASSL_LOCAL word16 TLSX_GetResponseSize(CYASSL* ssl);
+CYASSL_LOCAL word16 TLSX_WriteResponse(CYASSL* ssl, byte* output);
+#endif
+
+CYASSL_LOCAL int TLSX_Parse(CYASSL* ssl, byte* input, word16 length,
+ byte isRequest, Suites *suites);
+
+/* Server Name Indication */
+#ifdef HAVE_SNI
+
+typedef enum {
+ HOST_NAME = 0
+} SNI_Type;
+
+typedef struct SNI {
+ SNI_Type type; /* SNI Type */
+ union { char* host_name; } data; /* SNI Data */
+ struct SNI* next; /* List Behavior */
+} SNI;
+
+CYASSL_LOCAL int TLSX_UseSNI(TLSX** extensions, byte type, const void* data,
+ word16 size);
+
+#endif /* HAVE_SNI */
+
+#endif /* HAVE_TLS_EXTENSIONS */
/* CyaSSL context type */
struct CYASSL_CTX {
@@ -1159,6 +1224,9 @@ struct CYASSL_CTX {
#ifdef HAVE_CAVIUM
int devId; /* cavium device id to use */
#endif
+#ifdef HAVE_TLS_EXTENSIONS
+ TLSX* extensions; /* RFC 6066 TLS Extensions data */
+#endif
};
@@ -1685,6 +1753,7 @@ struct CYASSL {
DtlsPool* dtls_pool;
DtlsMsg* dtls_msg_list;
void* IOCB_CookieCtx; /* gen cookie ctx */
+ word32 dtls_expected_rx;
#endif
#ifdef CYASSL_CALLBACKS
HandShakeInfo handShakeInfo; /* info saved during handshake */
@@ -1700,6 +1769,9 @@ struct CYASSL {
#endif
#ifdef HAVE_CAVIUM
int devId; /* cavium device id to use */
+#endif
+#ifdef HAVE_TLS_EXTENSIONS
+ TLSX* extensions; /* RFC 6066 TLS Extensions data */
#endif
CYASSL_ALERT_HISTORY alert_history;
};
@@ -1820,7 +1892,8 @@ enum AlertDescription {
illegal_parameter = 47,
decrypt_error = 51,
protocol_version = 70,
- no_renegotiation = 100
+ no_renegotiation = 100,
+ unrecognized_name = 112
};
diff --git a/cyassl/ssl.h b/cyassl/ssl.h
index 1db414ba2..338564950 100644
--- a/cyassl/ssl.h
+++ b/cyassl/ssl.h
@@ -929,6 +929,13 @@ CYASSL_API void CyaSSL_FreeArrays(CYASSL*);
CYASSL_API int CyaSSL_UseCavium(CYASSL*, int devId);
CYASSL_API int CyaSSL_CTX_UseCavium(CYASSL_CTX*, int devId);
+/* tls extensions */
+#ifdef HAVE_SNI
+CYASSL_API int CyaSSL_UseSNI(CYASSL* ssl, unsigned char type, const void* data,
+ unsigned short size);
+CYASSL_API int CyaSSL_CTX_UseSNI(CYASSL_CTX* ctx, unsigned char type,
+ const void* data, unsigned short size);
+#endif
#define CYASSL_CRL_MONITOR 0x01 /* monitor this dir flag */
#define CYASSL_CRL_START_MON 0x02 /* start monitoring flag */
diff --git a/examples/client/client.c b/examples/client/client.c
index e0479d839..78c63ba1c 100644
--- a/examples/client/client.c
+++ b/examples/client/client.c
@@ -130,12 +130,18 @@ static void Usage(void)
#ifdef SHOW_SIZES
printf("-z Print structure sizes\n");
#endif
+ printf("-S Use Host Name Indication\n");
}
#ifdef CYASSL_MDK_SHELL
#define exit(code) return(code)
#endif
+#ifdef CYASSL_MDK_SHELL
+ #define exit(code) return(code)
+#endif
+
+
THREAD_RETURN CYASSL_THREAD client_test(void* args)
{
SOCKET_T sockfd = 0;
@@ -176,6 +182,10 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
char* ourCert = (char*)cliCert;
char* ourKey = (char*)cliKey;
+#ifdef HAVE_SNI
+ char* sniHostName = NULL;
+#endif
+
int argc = ((func_args*)args)->argc;
char** argv = ((func_args*)args)->argv;
@@ -191,7 +201,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
(void)sslResume;
(void)trackMemory;
- while ((ch = mygetopt(argc, argv, "?gdusmNrtfxh:p:v:l:A:c:k:b:z")) != -1) {
+ while ((ch = mygetopt(argc, argv, "?gdusmNrtfxh:p:v:l:A:c:k:b:zS:")) != -1){
switch (ch) {
case '?' :
Usage();
@@ -290,6 +300,12 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
#endif
break;
+ case 'S' :
+ #ifdef HAVE_SNI
+ sniHostName = myoptarg;
+ #endif
+ break;
+
default:
Usage();
exit(MY_EX_USAGE);
@@ -356,6 +372,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
default:
err_sys("Bad SSL version");
+ break;
}
if (method == NULL)
@@ -443,6 +460,12 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
CyaSSL_CTX_UseCavium(ctx, CAVIUM_DEV_ID);
#endif
+#ifdef HAVE_SNI
+ if (sniHostName)
+ if (CyaSSL_CTX_UseSNI(ctx, 0, sniHostName, XSTRLEN(sniHostName)))
+ err_sys("UseSNI failed");
+#endif
+
if (benchmark) {
/* time passed in number of connects give average */
int times = benchmark;
diff --git a/examples/server/server.c b/examples/server/server.c
index 002467cc9..da6fccf45 100644
--- a/examples/server/server.c
+++ b/examples/server/server.c
@@ -122,6 +122,7 @@ static void Usage(void)
" add -v 2 for DTLSv1 (default), -v 3 for DTLSv1.2\n");
printf("-f Fewer packets/group messages\n");
printf("-N Use Non-blocking sockets\n");
+ printf("-S Use Host Name Indication\n");
}
#ifdef CYASSL_MDK_SHELL
@@ -159,6 +160,10 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
int argc = ((func_args*)args)->argc;
char** argv = ((func_args*)args)->argv;
+#ifdef HAVE_SNI
+ char* sniHostName = NULL;
+#endif
+
((func_args*)args)->return_code = -1; /* error state */
#ifdef NO_RSA
@@ -168,7 +173,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
#endif
(void)trackMemory;
- while ((ch = mygetopt(argc, argv, "?dbstnNufp:v:l:A:c:k:")) != -1) {
+ while ((ch = mygetopt(argc, argv, "?dbstnNufp:v:l:A:c:k:S:")) != -1) {
switch (ch) {
case '?' :
Usage();
@@ -240,6 +245,12 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
nonBlocking = 1;
break;
+ case 'S' :
+ #ifdef HAVE_SNI
+ sniHostName = myoptarg;
+ #endif
+ break;
+
default:
Usage();
exit(MY_EX_USAGE);
@@ -396,6 +407,12 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
}
#endif
+#ifdef HAVE_SNI
+ if (sniHostName)
+ if (CyaSSL_CTX_UseSNI(ctx, 0, sniHostName, XSTRLEN(sniHostName)))
+ err_sys("UseSNI failed");
+#endif
+
ssl = SSL_new(ctx);
if (ssl == NULL)
err_sys("unable to get SSL");
diff --git a/src/internal.c b/src/internal.c
index b7dc206cd..0cf66a8ec 100644
--- a/src/internal.c
+++ b/src/internal.c
@@ -421,6 +421,9 @@ int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
#ifdef HAVE_CAVIUM
ctx->devId = NO_CAVIUM_DEVICE;
#endif
+#ifdef HAVE_TLS_EXTENSIONS
+ ctx->extensions = NULL;
+#endif
if (InitMutex(&ctx->countMutex) < 0) {
CYASSL_MSG("Mutex error on CTX init");
@@ -452,6 +455,9 @@ void SSL_CtxResourceFree(CYASSL_CTX* ctx)
#ifdef HAVE_OCSP
CyaSSL_OCSP_Cleanup(&ctx->ocsp);
#endif
+#ifdef HAVE_TLS_EXTENSIONS
+ TLSX_FreeAll(ctx->extensions);
+#endif
}
@@ -1286,6 +1292,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
ssl->IOCB_WriteCtx = &ssl->wfd; /* correctly set */
#ifdef CYASSL_DTLS
ssl->IOCB_CookieCtx = NULL; /* we don't use for default cb */
+ ssl->dtls_expected_rx = MAX_MTU;
#endif
#ifndef NO_OLD_TLS
@@ -1435,6 +1442,10 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
ssl->devId = ctx->devId;
#endif
+#ifdef HAVE_TLS_EXTENSIONS
+ ssl->extensions = NULL;
+#endif
+
ssl->rng = NULL;
ssl->arrays = NULL;
@@ -1654,6 +1665,9 @@ void SSL_ResourceFree(CYASSL* ssl)
XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
}
#endif
+#ifdef HAVE_TLS_EXTENSIONS
+ TLSX_FreeAll(ssl->extensions);
+#endif
}
@@ -1830,6 +1844,21 @@ int DtlsPoolSend(CYASSL* ssl)
int sendResult;
buffer* buf = &pool->buf[i];
+ DtlsRecordLayerHeader* dtls = (DtlsRecordLayerHeader*)buf->buffer;
+
+ word16 message_epoch;
+ ato16(dtls->epoch, &message_epoch);
+ if (message_epoch == ssl->keys.dtls_epoch) {
+ /* Increment record sequence number on retransmitted handshake
+ * messages */
+ c32to48(ssl->keys.dtls_sequence_number, dtls->sequence_number);
+ ssl->keys.dtls_sequence_number++;
+ }
+ else {
+ /* The Finished message is sent with the next epoch, keep its
+ * sequence number */
+ }
+
if ((ret = CheckAvailableSize(ssl, buf->length)) != 0)
return ret;
@@ -3325,13 +3354,29 @@ int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff)
if (ssl->options.side == CLIENT_END) {
ssl->options.serverState = SERVER_FINISHED_COMPLETE;
- if (!ssl->options.resuming)
+ if (!ssl->options.resuming) {
ssl->options.handShakeState = HANDSHAKE_DONE;
+#ifdef CYASSL_DTLS
+ if (ssl->options.dtls) {
+ /* Other side has received our Finished, go to next epoch */
+ ssl->keys.dtls_epoch++;
+ ssl->keys.dtls_sequence_number = 1;
+ }
+#endif
+ }
}
else {
ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
- if (ssl->options.resuming)
+ if (ssl->options.resuming) {
ssl->options.handShakeState = HANDSHAKE_DONE;
+#ifdef CYASSL_DTLS
+ if (ssl->options.dtls) {
+ /* Other side has received our Finished, go to next epoch */
+ ssl->keys.dtls_epoch++;
+ ssl->keys.dtls_sequence_number = 1;
+ }
+#endif
+ }
}
*inOutIdx = idx;
@@ -4376,9 +4421,9 @@ static int GetInputData(CYASSL *ssl, word32 size)
#ifdef CYASSL_DTLS
if (ssl->options.dtls) {
- if (size < MAX_MTU)
- dtlsExtra = (int)(MAX_MTU - size);
- inSz = MAX_MTU; /* read ahead up to MTU */
+ if (size < ssl->dtls_expected_rx)
+ dtlsExtra = (int)(ssl->dtls_expected_rx - size);
+ inSz = ssl->dtls_expected_rx;
}
#endif
@@ -5001,18 +5046,25 @@ int SendFinished(CYASSL* ssl)
int ret;
int headerSz = HANDSHAKE_HEADER_SZ;
+ #ifdef CYASSL_DTLS
+ word32 sequence_number = ssl->keys.dtls_sequence_number;
+ word16 epoch = ssl->keys.dtls_epoch;
+ #endif
+
+
+ /* check for available size */
+ if ((ret = CheckAvailableSize(ssl, sizeof(input) + MAX_MSG_EXTRA)) != 0)
+ return ret;
#ifdef CYASSL_DTLS
if (ssl->options.dtls) {
+ /* Send Finished message with the next epoch, but don't commit that
+ * change until the other end confirms its reception. */
headerSz += DTLS_HANDSHAKE_EXTRA;
ssl->keys.dtls_epoch++;
ssl->keys.dtls_sequence_number = 0; /* reset after epoch change */
}
#endif
-
- /* check for available size */
- if ((ret = CheckAvailableSize(ssl, sizeof(input) + MAX_MSG_EXTRA)) != 0)
- return ret;
/* get ouput buffer */
output = ssl->buffers.outputBuffer.buffer +
@@ -5025,24 +5077,52 @@ int SendFinished(CYASSL* ssl)
BuildFinished(ssl, hashes, ssl->options.side == CLIENT_END ? client :
server);
- if ( (sendSz = BuildMessage(ssl, output, input, headerSz +
- finishedSz, handshake)) < 0)
+ sendSz = BuildMessage(ssl, output, input, headerSz + finishedSz, handshake);
+
+ #ifdef CYASSL_DTLS
+ if (ssl->options.dtls) {
+ ssl->keys.dtls_epoch = epoch;
+ ssl->keys.dtls_sequence_number = sequence_number;
+ }
+ #endif
+
+ if (sendSz < 0)
return BUILD_MSG_ERROR;
if (!ssl->options.resuming) {
#ifndef NO_SESSION_CACHE
AddSession(ssl); /* just try */
#endif
- if (ssl->options.side == CLIENT_END)
+ if (ssl->options.side == CLIENT_END) {
BuildFinished(ssl, &ssl->verifyHashes, server);
- else
+ }
+ else {
ssl->options.handShakeState = HANDSHAKE_DONE;
+ #ifdef CYASSL_DTLS
+ if (ssl->options.dtls) {
+ /* Other side will soon receive our Finished, go to next
+ * epoch. */
+ ssl->keys.dtls_epoch++;
+ ssl->keys.dtls_sequence_number = 1;
+ }
+ #endif
+ }
}
else {
- if (ssl->options.side == CLIENT_END)
+ if (ssl->options.side == CLIENT_END) {
ssl->options.handShakeState = HANDSHAKE_DONE;
- else
+ #ifdef CYASSL_DTLS
+ if (ssl->options.dtls) {
+ /* Other side will soon receive our Finished, go to next
+ * epoch. */
+ ssl->keys.dtls_epoch++;
+ ssl->keys.dtls_sequence_number = 1;
+ }
+ #endif
+ }
+ else {
BuildFinished(ssl, &ssl->verifyHashes, client);
+ }
}
#ifdef CYASSL_DTLS
if (ssl->options.dtls) {
@@ -5426,13 +5506,15 @@ int SendAlert(CYASSL* ssl, int severity, int type)
AddRecordHeader(output, ALERT_SIZE, alert, ssl);
output += RECORD_HEADER_SZ;
#ifdef CYASSL_DTLS
- output += DTLS_RECORD_EXTRA;
+ if (ssl->options.dtls)
+ output += DTLS_RECORD_EXTRA;
#endif
XMEMCPY(output, input, ALERT_SIZE);
sendSz = RECORD_HEADER_SZ + ALERT_SIZE;
#ifdef CYASSL_DTLS
- sendSz += DTLS_RECORD_EXTRA;
+ if (ssl->options.dtls)
+ sendSz += DTLS_RECORD_EXTRA;
#endif
}
@@ -5801,6 +5883,10 @@ void SetErrorString(int error, char* str)
XSTRNCPY(str, "Cache restore header match Error", max);
break;
+ case UNKNOWN_SNI_HOST_NAME_E:
+ XSTRNCPY(str, "Unrecognized host name Error", max);
+ break;
+
default :
XSTRNCPY(str, "unknown error number", max);
}
@@ -6692,9 +6778,13 @@ int SetCipherList(Suites* s, const char* list)
+ ssl->suites->suiteSz + SUITE_LEN
+ COMP_LEN + ENUM_LEN;
+#ifdef HAVE_TLS_EXTENSIONS
+ length += TLSX_GetRequestSize(ssl);
+#else
if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) {
length += ssl->suites->hashSigAlgoSz + HELLO_EXT_SZ;
}
+#endif
sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
#ifdef CYASSL_DTLS
@@ -6767,6 +6857,11 @@ int SetCipherList(Suites* s, const char* list)
else
output[idx++] = NO_COMPRESSION;
+#ifdef HAVE_TLS_EXTENSIONS
+ idx += TLSX_WriteRequest(ssl, output + idx);
+
+ (void)idx; /* suppress analyzer warning, keep idx current */
+#else
if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
{
int i;
@@ -6784,6 +6879,7 @@ int SetCipherList(Suites* s, const char* list)
output[idx] = ssl->suites->hashSigAlgo[i];
}
}
+#endif
#ifdef CYASSL_DTLS
if (ssl->options.dtls) {
@@ -6905,8 +7001,29 @@ int SetCipherList(Suites* s, const char* list)
}
*inOutIdx = i;
- if ( (i - begin) < helloSz)
- *inOutIdx = begin + helloSz; /* skip extensions */
+ if ( (i - begin) < helloSz) {
+#ifdef HAVE_TLS_EXTENSIONS
+ if (IsTLS(ssl)) {
+ int ret = 0;
+ word16 totalExtSz;
+ Suites clSuites; /* just for compatibility right now */
+
+ ato16(&input[i], &totalExtSz);
+ i += LENGTH_SZ;
+ if (totalExtSz > helloSz + begin - i)
+ return INCOMPLETE_DATA;
+
+ if ((ret = TLSX_Parse(ssl, (byte *) input + i,
+ totalExtSz, 0, &clSuites)))
+ return ret;
+
+ i += totalExtSz;
+ *inOutIdx = i;
+ }
+ else
+#endif
+ *inOutIdx = begin + helloSz; /* skip extensions */
+ }
ssl->options.serverState = SERVER_HELLO_COMPLETE;
@@ -7778,7 +7895,11 @@ int SetCipherList(Suites* s, const char* list)
+ SUITE_LEN
+ ENUM_LEN;
- /* check for available size */
+#ifdef HAVE_TLS_EXTENSIONS
+ length += TLSX_GetResponseSize(ssl);
+#endif
+
+ /* check for avalaible size */
if ((ret = CheckAvailableSize(ssl, MAX_HELLO_SZ)) != 0)
return ret;
@@ -7826,11 +7947,17 @@ int SetCipherList(Suites* s, const char* list)
output[idx++] = ssl->options.cipherSuite0;
output[idx++] = ssl->options.cipherSuite;
- /* last, compression */
+ /* then compression */
if (ssl->options.usingCompression)
output[idx++] = ZLIB_COMPRESSION;
else
output[idx++] = NO_COMPRESSION;
+
+ /* last, extensions */
+#ifdef HAVE_TLS_EXTENSIONS
+ if (IsTLS(ssl))
+ TLSX_WriteResponse(ssl, output + idx);
+#endif
ssl->buffers.outputBuffer.length += sendSz;
#ifdef CYASSL_DTLS
@@ -9323,11 +9450,14 @@ int SetCipherList(Suites* s, const char* list)
else
i += b; /* ignore, since we're not on */
- ssl->options.clientState = CLIENT_HELLO_COMPLETE;
-
*inOutIdx = i;
if ( (i - begin) < helloSz) {
+#ifdef HAVE_TLS_EXTENSIONS
+ if (IsTLS(ssl)) {
+ int ret = 0;
+#else
if (IsAtLeastTLSv1_2(ssl)) {
+#endif
/* Process the hello extension. Skip unsupported. */
word16 totalExtSz;
@@ -9335,6 +9465,14 @@ int SetCipherList(Suites* s, const char* list)
i += LENGTH_SZ;
if (totalExtSz > helloSz + begin - i)
return INCOMPLETE_DATA;
+
+#ifdef HAVE_TLS_EXTENSIONS
+ if ((ret = TLSX_Parse(ssl, (byte *) input + i,
+ totalExtSz, 1, &clSuites)))
+ return ret;
+
+ i += totalExtSz;
+#else
while (totalExtSz) {
word16 extId, extSz;
@@ -9360,15 +9498,23 @@ int SetCipherList(Suites* s, const char* list)
totalExtSz -= LENGTH_SZ + EXT_ID_SZ + extSz;
}
+#endif
*inOutIdx = i;
}
else
*inOutIdx = begin + helloSz; /* skip extensions */
}
+
+ ssl->options.clientState = CLIENT_HELLO_COMPLETE;
ssl->options.haveSessionId = 1;
/* ProcessOld uses same resume code */
+<<<<<<< HEAD
if (ssl->options.resuming) { /* let's try */
+=======
+ if (ssl->options.resuming && (!ssl->options.dtls ||
+ ssl->options.acceptState == HELLO_VERIFY_SENT)) { /* let's try */
+>>>>>>> cyassl/master
int ret = -1;
CYASSL_SESSION* session = GetSession(ssl,ssl->arrays->masterSecret);
if (!session) {
diff --git a/src/io.c b/src/io.c
index f53e4e25b..0fad73b21 100644
--- a/src/io.c
+++ b/src/io.c
@@ -612,7 +612,6 @@ static int decode_http_response(byte* httpBuf, int httpBufSz, byte** dst)
/* Advance idx past the next \r\n */
char* end = XSTRSTR(&buf[idx], "\r\n");
idx = (int)(end - buf + 2);
- stop = 1;
}
}
}
@@ -629,6 +628,8 @@ static int decode_http_response(byte* httpBuf, int httpBufSz, byte** dst)
static int decode_url(const char* url, int urlSz,
char* outName, char* outPath, int* outPort)
{
+ int result = -1;
+
if (outName != NULL && outPath != NULL && outPort != NULL)
{
if (url == NULL || urlSz == 0)
@@ -648,7 +649,8 @@ static int decode_url(const char* url, int urlSz,
} else cur = 0;
i = 0;
- while (url[cur] != 0 && url[cur] != ':' && url[cur] != '/') {
+ while (url[cur] != 0 && url[cur] != ':' &&
+ url[cur] != '/' && cur < urlSz) {
outName[i++] = url[cur++];
}
outName[i] = 0;
@@ -684,10 +686,11 @@ static int decode_url(const char* url, int urlSz,
outPath[0] = '/';
outPath[1] = 0;
}
+ result = 0;
}
}
- return 0;
+ return result;
}
@@ -732,11 +735,11 @@ int EmbedOcspLookup(void* ctx, const char* url, int urlSz,
if ((tcp_connect(&sfd, domainName, port) == 0) && (sfd > 0)) {
int written;
- written = (int)write(sfd, httpBuf, httpBufSz);
+ written = (int)send(sfd, httpBuf, httpBufSz, 0);
if (written == httpBufSz) {
- written = (int)write(sfd, ocspReqBuf, ocspReqSz);
+ written = (int)send(sfd, ocspReqBuf, ocspReqSz, 0);
if (written == ocspReqSz) {
- httpBufSz = (int)read(sfd, httpBuf, SCRATCH_BUFFER_SIZE);
+ httpBufSz = (int)recv(sfd, httpBuf, SCRATCH_BUFFER_SIZE, 0);
if (httpBufSz > 0) {
ocspRespSz = decode_http_response(httpBuf, httpBufSz,
ocspRespBuf);
diff --git a/src/keys.c b/src/keys.c
index 0c86f3f6e..2146920f2 100644
--- a/src/keys.c
+++ b/src/keys.c
@@ -1421,10 +1421,12 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
#ifdef BUILD_ARC4
word32 sz = specs->key_size;
if (specs->bulk_cipher_algorithm == rc4) {
- enc->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER);
+ if (enc->arc4 == NULL)
+ enc->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER);
if (enc->arc4 == NULL)
return MEMORY_E;
- dec->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER);
+ if (dec->arc4 == NULL)
+ dec->arc4 = (Arc4*)XMALLOC(sizeof(Arc4), heap, DYNAMIC_TYPE_CIPHER);
if (dec->arc4 == NULL)
return MEMORY_E;
#ifdef HAVE_CAVIUM
@@ -1455,10 +1457,14 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
#ifdef HAVE_HC128
if (specs->bulk_cipher_algorithm == hc128) {
int hcRet;
- enc->hc128 = (HC128*)XMALLOC(sizeof(HC128), heap, DYNAMIC_TYPE_CIPHER);
+ if (enc->hc128 == NULL)
+ enc->hc128 =
+ (HC128*)XMALLOC(sizeof(HC128), heap, DYNAMIC_TYPE_CIPHER);
if (enc->hc128 == NULL)
return MEMORY_E;
- dec->hc128 = (HC128*)XMALLOC(sizeof(HC128), heap, DYNAMIC_TYPE_CIPHER);
+ if (dec->hc128 == NULL)
+ dec->hc128 =
+ (HC128*)XMALLOC(sizeof(HC128), heap, DYNAMIC_TYPE_CIPHER);
if (dec->hc128 == NULL)
return MEMORY_E;
if (side == CLIENT_END) {
@@ -1485,10 +1491,14 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
#ifdef BUILD_RABBIT
if (specs->bulk_cipher_algorithm == rabbit) {
int rabRet;
- enc->rabbit = (Rabbit*)XMALLOC(sizeof(Rabbit),heap,DYNAMIC_TYPE_CIPHER);
+ if (enc->rabbit == NULL)
+ enc->rabbit =
+ (Rabbit*)XMALLOC(sizeof(Rabbit), heap, DYNAMIC_TYPE_CIPHER);
if (enc->rabbit == NULL)
return MEMORY_E;
- dec->rabbit = (Rabbit*)XMALLOC(sizeof(Rabbit),heap,DYNAMIC_TYPE_CIPHER);
+ if (dec->rabbit == NULL)
+ dec->rabbit =
+ (Rabbit*)XMALLOC(sizeof(Rabbit), heap, DYNAMIC_TYPE_CIPHER);
if (dec->rabbit == NULL)
return MEMORY_E;
if (side == CLIENT_END) {
@@ -1514,10 +1524,12 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
#ifdef BUILD_DES3
if (specs->bulk_cipher_algorithm == triple_des) {
- enc->des3 = (Des3*)XMALLOC(sizeof(Des3), heap, DYNAMIC_TYPE_CIPHER);
+ if (enc->des3 == NULL)
+ enc->des3 = (Des3*)XMALLOC(sizeof(Des3), heap, DYNAMIC_TYPE_CIPHER);
if (enc->des3 == NULL)
return MEMORY_E;
- dec->des3 = (Des3*)XMALLOC(sizeof(Des3), heap, DYNAMIC_TYPE_CIPHER);
+ if (dec->des3 == NULL)
+ dec->des3 = (Des3*)XMALLOC(sizeof(Des3), heap, DYNAMIC_TYPE_CIPHER);
if (dec->des3 == NULL)
return MEMORY_E;
#ifdef HAVE_CAVIUM
@@ -1551,10 +1563,12 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
#ifdef BUILD_AES
if (specs->bulk_cipher_algorithm == aes) {
- enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+ if (enc->aes == NULL)
+ enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
if (enc->aes == NULL)
return MEMORY_E;
- dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+ if (dec->aes == NULL)
+ dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
if (dec->aes == NULL)
return MEMORY_E;
#ifdef HAVE_CAVIUM
@@ -1592,10 +1606,12 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
#ifdef BUILD_AESGCM
if (specs->bulk_cipher_algorithm == aes_gcm) {
- enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+ if (enc->aes == NULL)
+ enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
if (enc->aes == NULL)
return MEMORY_E;
- dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+ if (dec->aes == NULL)
+ dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
if (dec->aes == NULL)
return MEMORY_E;
@@ -1622,10 +1638,12 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
#ifdef HAVE_AESCCM
if (specs->bulk_cipher_algorithm == aes_ccm) {
- enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+ if (enc->aes == NULL)
+ enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
if (enc->aes == NULL)
return MEMORY_E;
- dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
+ if (dec->aes == NULL)
+ dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER);
if (dec->aes == NULL)
return MEMORY_E;
@@ -1652,12 +1670,14 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
#ifdef HAVE_CAMELLIA
if (specs->bulk_cipher_algorithm == camellia) {
- enc->cam = (Camellia*)XMALLOC(sizeof(Camellia),
- heap, DYNAMIC_TYPE_CIPHER);
+ if (enc->cam == NULL)
+ enc->cam =
+ (Camellia*)XMALLOC(sizeof(Camellia), heap, DYNAMIC_TYPE_CIPHER);
if (enc->cam == NULL)
return MEMORY_E;
- dec->cam = (Camellia*)XMALLOC(sizeof(Camellia),
- heap, DYNAMIC_TYPE_CIPHER);
+ if (dec->cam == NULL)
+ dec->cam =
+ (Camellia*)XMALLOC(sizeof(Camellia), heap, DYNAMIC_TYPE_CIPHER);
if (dec->cam == NULL)
return MEMORY_E;
if (side == CLIENT_END) {
diff --git a/src/ocsp.c b/src/ocsp.c
index dae9c914f..64d082216 100644
--- a/src/ocsp.c
+++ b/src/ocsp.c
@@ -275,7 +275,7 @@ int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
}
}
- if (ocsp->useOverrideUrl || cert->extAuthInfo == NULL) {
+ if (ocsp->useOverrideUrl) {
if (ocsp->overrideUrl[0] != '\0') {
url = ocsp->overrideUrl;
urlSz = (int)XSTRLEN(url);
@@ -283,10 +283,14 @@ int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
else
return OCSP_NEED_URL;
}
- else {
+ else if (cert->extAuthInfoSz == 0 || cert->extAuthInfo == NULL) {
url = (const char *)cert->extAuthInfo;
urlSz = cert->extAuthInfoSz;
}
+ else {
+ CYASSL_MSG("\tcert doesn't have extAuthInfo, assuming CERT_GOOD");
+ return 0;
+ }
ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
if (ocspReqBuf == NULL) {
diff --git a/src/ssl.c b/src/ssl.c
index e8e6e571c..aaf384066 100644
--- a/src/ssl.c
+++ b/src/ssl.c
@@ -88,6 +88,15 @@
#endif /* min */
+#ifndef max
+
+ static INLINE word32 max(word32 a, word32 b)
+ {
+ return a > b ? a : b;
+ }
+
+#endif /* min */
+
#ifndef CYASSL_LEANPSK
char* mystrnstr(const char* s1, const char* s2, unsigned int n)
@@ -440,6 +449,10 @@ static int CyaSSL_read_internal(CYASSL* ssl, void* data, int sz, int peek)
#ifdef HAVE_ERRNO_H
errno = 0;
#endif
+#ifdef CYASSL_DTLS
+ if (ssl->options.dtls)
+ ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);
+#endif
ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE), peek);
@@ -496,6 +509,27 @@ int CyaSSL_CTX_UseCavium(CYASSL_CTX* ctx, int devId)
#endif /* HAVE_CAVIUM */
+#ifdef HAVE_SNI
+
+int CyaSSL_UseSNI(CYASSL* ssl, unsigned char type, const void* data,
+ unsigned short size)
+{
+ if (ssl == NULL)
+ return BAD_FUNC_ARG;
+
+ return TLSX_UseSNI(&ssl->extensions, type, data, size);
+}
+
+int CyaSSL_CTX_UseSNI(CYASSL_CTX* ctx, unsigned char type, const void* data,
+ unsigned short size)
+{
+ if (ctx == NULL)
+ return BAD_FUNC_ARG;
+
+ return TLSX_UseSNI(&ctx->extensions, type, data, size);
+}
+
+#endif /* HAVE_SNI */
#ifndef CYASSL_LEANPSK
int CyaSSL_send(CYASSL* ssl, const void* data, int sz, int flags)
@@ -632,7 +666,18 @@ char* CyaSSL_ERR_error_string(unsigned long errNumber, char* data)
void CyaSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
{
CYASSL_ENTER("CyaSSL_ERR_error_string_n");
- if (len) CyaSSL_ERR_error_string(e, buf);
+ if (len >= MAX_ERROR_SZ)
+ CyaSSL_ERR_error_string(e, buf);
+ else {
+ char tmp[MAX_ERROR_SZ];
+
+ CYASSL_MSG("Error buffer too short, truncating");
+ if (len) {
+ CyaSSL_ERR_error_string(e, tmp);
+ XMEMCPY(buf, tmp, len-1);
+ buf[len-1] = '\0';
+ }
+ }
}
diff --git a/src/tls.c b/src/tls.c
index 0e8021efd..2776b5e86 100644
--- a/src/tls.c
+++ b/src/tls.c
@@ -370,6 +370,12 @@ static INLINE void c16toa(word16 u16, byte* c)
c[1] = u16 & 0xff;
}
+/* convert opaque to 16 bit integer */
+static INLINE void ato16(const byte* c, word16* u16)
+{
+ *u16 = (c[0] << 8) | (c[1]);
+}
+
/* convert 32 bit integer to opaque */
static INLINE void c32toa(word32 u32, byte* c)
@@ -484,6 +490,580 @@ void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
HmacFinal(&hmac, digest);
}
+#ifdef HAVE_TLS_EXTENSIONS
+
+static int TLSX_Append(TLSX** list, TLSX_Type type)
+{
+ TLSX* extension;
+
+ if (list == NULL) /* won't check type since this function is static */
+ return BAD_FUNC_ARG;
+
+ if ((extension = XMALLOC(sizeof(TLSX), 0, DYNAMIC_TYPE_TLSX)) == NULL)
+ return MEMORY_E;
+
+ extension->type = type;
+ extension->data = NULL;
+ extension->resp = 0;
+ extension->next = *list;
+ *list = extension;
+
+ return 0;
+}
+
+#ifndef NO_CYASSL_SERVER
+
+static void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type)
+{
+ TLSX *ext = TLSX_Find(ssl->extensions, type);
+
+ if (ext)
+ ext->resp = 1;
+}
+
+#endif
+
+/* SNI - Server Name Indication */
+
+#ifdef HAVE_SNI
+
+static void TLSX_SNI_Free(SNI* sni)
+{
+ if (sni) {
+ switch (sni->type) {
+ case HOST_NAME:
+ XFREE(sni->data.host_name, 0, DYNAMIC_TYPE_TLSX);
+ break;
+ }
+
+ XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
+ }
+}
+
+static void TLSX_SNI_FreeAll(SNI* list)
+{
+ SNI* sni;
+
+ while ((sni = list)) {
+ list = sni->next;
+ TLSX_SNI_Free(sni);
+ }
+}
+
+static int TLSX_SNI_Append(SNI** list, SNI_Type type, const void* data,
+ word16 size)
+{
+ SNI* sni;
+
+ if (list == NULL)
+ return BAD_FUNC_ARG;
+
+ if ((sni = XMALLOC(sizeof(SNI), 0, DYNAMIC_TYPE_TLSX)) == NULL)
+ return MEMORY_E;
+
+ switch (type) {
+ case HOST_NAME: {
+ sni->data.host_name = XMALLOC(size + 1, 0, DYNAMIC_TYPE_TLSX);
+
+ if (sni->data.host_name) {
+ XSTRNCPY(sni->data.host_name, (const char*) data, size);
+ sni->data.host_name[size] = 0;
+ } else {
+ XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
+ return MEMORY_E;
+ }
+ }
+ break;
+
+ default: /* invalid type */
+ XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
+ return BAD_FUNC_ARG;
+ break;
+ }
+
+ sni->type = type;
+ sni->next = *list;
+ *list = sni;
+
+ return 0;
+}
+
+static word16 TLSX_SNI_GetSize(SNI* list)
+{
+ SNI* sni;
+ word16 length = OPAQUE16_LEN; /* list length */
+
+ while ((sni = list)) {
+ list = sni->next;
+
+ length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */
+
+ switch (sni->type) {
+ case HOST_NAME:
+ length += XSTRLEN((char*) sni->data.host_name);
+ break;
+ }
+ }
+
+ return length;
+}
+
+static word16 TLSX_SNI_Write(SNI* list, byte* output)
+{
+ SNI* sni;
+ word16 length = 0;
+ word16 offset = OPAQUE16_LEN; /* list length offset */
+
+ while ((sni = list)) {
+ list = sni->next;
+
+ output[offset++] = sni->type; /* sni type */
+
+ switch (sni->type) {
+ case HOST_NAME:
+ length = XSTRLEN((char*) sni->data.host_name);
+
+ c16toa(length, output + offset); /* sni length */
+ offset += OPAQUE16_LEN;
+
+ XMEMCPY(output + offset, sni->data.host_name, length);
+
+ offset += length;
+ break;
+ }
+ }
+
+ c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
+
+ return offset;
+}
+
+static SNI* TLSX_SNI_Find(SNI *list, SNI_Type type)
+{
+ SNI *sni = list;
+
+ while (sni && sni->type != type)
+ sni = sni->next;
+
+ return sni;
+}
+
+static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length,
+ byte isRequest)
+{
+#ifndef NO_CYASSL_SERVER
+ word16 size = 0;
+ word16 offset = 0;
+#endif
+
+ TLSX *extension = TLSX_Find(ssl->extensions, SERVER_NAME_INDICATION);
+
+ if (!extension)
+ extension = TLSX_Find(ssl->ctx->extensions, SERVER_NAME_INDICATION);
+
+ if (!extension || !extension->data) {
+ if (!isRequest) {
+ CYASSL_MSG("Unexpected SNI response from server");
+ }
+
+ return 0; /* not using SNI */
+ }
+
+ if (!isRequest) {
+ if (length) {
+ CYASSL_MSG("SNI response should be empty!");
+ }
+
+ return 0; /* nothing to do */
+ }
+
+#ifndef NO_CYASSL_SERVER
+
+ if (OPAQUE16_LEN > length)
+ return INCOMPLETE_DATA;
+
+ ato16(input, &size);
+ offset += OPAQUE16_LEN;
+
+ /* validating sni list length */
+ if (length != OPAQUE16_LEN + size)
+ return INCOMPLETE_DATA;
+
+ for (size = 0; offset < length; offset += size) {
+ SNI *sni;
+ SNI_Type type = input[offset++];
+
+ if (offset + OPAQUE16_LEN > length)
+ return INCOMPLETE_DATA;
+
+ ato16(input + offset, &size);
+ offset += OPAQUE16_LEN;
+
+ if (offset + size > length)
+ return INCOMPLETE_DATA;
+
+ if (!(sni = TLSX_SNI_Find((SNI *) extension->data, type))) {
+ continue; /* not using this SNI type */
+ }
+
+ switch(type) {
+ case HOST_NAME:
+ if (XSTRNCMP(sni->data.host_name,
+ (const char *) input + offset, size)) {
+ SendAlert(ssl, alert_fatal, unrecognized_name);
+
+ return UNKNOWN_SNI_HOST_NAME_E;
+ } else {
+ int r = TLSX_UseSNI(&ssl->extensions, type, (byte *) "", 0);
+
+ if (r) return r; /* throw error */
+ }
+ break;
+ }
+
+ TLSX_SetResponse(ssl, SERVER_NAME_INDICATION);
+ }
+
+#endif
+
+ return 0;
+}
+
+int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size)
+{
+ TLSX* extension = NULL;
+ SNI* sni = NULL;
+ int ret = 0;
+
+ if (extensions == NULL || data == NULL)
+ return BAD_FUNC_ARG;
+
+ if ((ret = TLSX_SNI_Append(&sni, type, data, size)) != 0)
+ return ret;
+
+ extension = *extensions;
+
+ /* find SNI extension if it already exists. */
+ while (extension && extension->type != SERVER_NAME_INDICATION)
+ extension = extension->next;
+
+ /* push new SNI extension if it doesn't exists. */
+ if (!extension) {
+ if ((ret = TLSX_Append(extensions, SERVER_NAME_INDICATION)) != 0) {
+ TLSX_SNI_Free(sni);
+ return ret;
+ }
+
+ extension = *extensions;
+ }
+
+ /* push new SNI object to extension data. */
+ sni->next = (SNI*) extension->data;
+ extension->data = (void*) sni;
+
+ /* look for another server name of the same type to remove (replacement) */
+ while ((sni = sni->next)) {
+ if (sni->next && sni->next->type == type) {
+ SNI *next = sni->next;
+
+ sni->next = next->next;
+ TLSX_SNI_Free(next);
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+#define SNI_FREE_ALL TLSX_SNI_FreeAll
+#define SNI_GET_SIZE TLSX_SNI_GetSize
+#define SNI_WRITE TLSX_SNI_Write
+#define SNI_PARSE TLSX_SNI_Parse
+
+#else
+
+#define SNI_FREE_ALL(x)
+#define SNI_GET_SIZE(x) 0
+#define SNI_WRITE(x) 0
+#define SNI_PARSE(x) 0
+
+#endif /* HAVE_SNI */
+
+TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
+{
+ TLSX* extension = list;
+
+ while (extension && extension->type != type)
+ extension = extension->next;
+
+ return extension;
+}
+
+void TLSX_FreeAll(TLSX* list)
+{
+ TLSX* extension;
+
+ while ((extension = list)) {
+ list = extension->next;
+
+ switch (extension->type) {
+ case SERVER_NAME_INDICATION:
+ SNI_FREE_ALL((SNI *) extension->data);
+ break;
+ }
+
+ XFREE(extension, 0, DYNAMIC_TYPE_TLSX);
+ }
+}
+
+#define IS_OFF(semaphore, light) \
+ ((semaphore)[(light) / 8] ^ (byte) (0x01 << ((light) % 8)))
+
+#define TURN_ON(semaphore, light) \
+ ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8)))
+
+static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest)
+{
+ TLSX* extension;
+ word16 length = 0;
+
+ while ((extension = list)) {
+ list = extension->next;
+
+ if (!isRequest && !extension->resp)
+ continue; /* skip! */
+
+ if (IS_OFF(semaphore, extension->type)) {
+ /* type + data length */
+ length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
+
+ switch (extension->type) {
+ case SERVER_NAME_INDICATION:
+ if (isRequest)
+ length += SNI_GET_SIZE((SNI *) extension->data);
+ break;
+ }
+
+ TURN_ON(semaphore, extension->type);
+ }
+ }
+
+ return length;
+}
+
+static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
+ byte isRequest)
+{
+ TLSX* extension;
+ word16 offset = 0;
+ word16 length_offset = 0;
+
+ while ((extension = list)) {
+ list = extension->next;
+
+ if (!isRequest && !extension->resp)
+ continue; /* skip! */
+
+ if (IS_OFF(semaphore, extension->type)) {
+ /* extension type */
+ c16toa(extension->type, output + offset);
+ offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
+ length_offset = offset;
+
+ /* extension data should be written internally */
+ switch (extension->type) {
+ case SERVER_NAME_INDICATION:
+ if (isRequest)
+ offset += SNI_WRITE((SNI *) extension->data,
+ output + offset);
+ break;
+ }
+
+ /* writing extension data length */
+ c16toa(offset - length_offset,
+ output + length_offset - OPAQUE16_LEN);
+
+ TURN_ON(semaphore, extension->type);
+ }
+ }
+
+ return offset;
+}
+
+#ifndef NO_CYASSL_CLIENT
+
+word16 TLSX_GetRequestSize(CYASSL* ssl)
+{
+ word16 length = 0;
+
+ if (ssl && IsTLS(ssl)) {
+ byte semaphore[16] = {0};
+
+ if (ssl->extensions)
+ length += TLSX_GetSize(ssl->extensions, semaphore, 1);
+
+ if (ssl->ctx && ssl->ctx->extensions)
+ length += TLSX_GetSize(ssl->ctx->extensions, semaphore, 1);
+
+ if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
+ length += ssl->suites->hashSigAlgoSz + HELLO_EXT_LEN;
+ }
+
+ if (length)
+ length += OPAQUE16_LEN; /* for total length storage */
+
+ return length;
+}
+
+word16 TLSX_WriteRequest(CYASSL* ssl, byte* output)
+{
+ word16 offset = 0;
+
+ if (ssl && IsTLS(ssl) && output) {
+ byte semaphore[16] = {0};
+
+ offset += OPAQUE16_LEN; /* extensions length */
+
+ if (ssl->extensions)
+ offset += TLSX_Write(ssl->extensions, output + offset,
+ semaphore, 1);
+
+ if (ssl->ctx && ssl->ctx->extensions)
+ offset += TLSX_Write(ssl->ctx->extensions, output + offset,
+ semaphore, 1);
+
+ if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
+ {
+ int i;
+ /* extension type */
+ c16toa(HELLO_EXT_SIG_ALGO, output + offset);
+ offset += HELLO_EXT_TYPE_SZ;
+
+ /* extension data length */
+ c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, output + offset);
+ offset += OPAQUE16_LEN;
+
+ /* sig algos length */
+ c16toa(ssl->suites->hashSigAlgoSz, output + offset);
+ offset += OPAQUE16_LEN;
+
+ /* sig algos */
+ for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, offset++)
+ output[offset] = ssl->suites->hashSigAlgo[i];
+ }
+
+ if (offset > OPAQUE16_LEN)
+ c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
+ }
+
+ return offset;
+}
+
+#endif /* NO_CYASSL_CLIENT */
+
+#ifndef NO_CYASSL_SERVER
+
+word16 TLSX_GetResponseSize(CYASSL* ssl)
+{
+ word16 length = 0;
+ byte semaphore[16] = {0};
+
+ if (ssl && IsTLS(ssl))
+ length += TLSX_GetSize(ssl->extensions, semaphore, 0);
+
+ /* All the response data is set at the ssl object only, so no ctx here. */
+
+ if (length)
+ length += OPAQUE16_LEN; /* for total length storage */
+
+ return length;
+}
+
+word16 TLSX_WriteResponse(CYASSL *ssl, byte* output)
+{
+ word16 offset = 0;
+
+ if (ssl && IsTLS(ssl) && output) {
+ byte semaphore[16] = {0};
+
+ offset += OPAQUE16_LEN; /* extensions length */
+
+ offset += TLSX_Write(ssl->extensions, output + offset, semaphore, 0);
+
+ if (offset > OPAQUE16_LEN)
+ c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
+ }
+
+ return offset;
+}
+
+#endif /* NO_CYASSL_SERVER */
+
+int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
+ Suites *suites)
+{
+ int ret = 0;
+ word16 offset = 0;
+
+ if (!ssl || !input || !suites)
+ return BAD_FUNC_ARG;
+
+ while (ret == 0 && offset < length) {
+ word16 type;
+ word16 size;
+
+ if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN)
+ return INCOMPLETE_DATA;
+
+ ato16(input + offset, &type);
+ offset += HELLO_EXT_TYPE_SZ;
+
+ ato16(input + offset, &size);
+ offset += OPAQUE16_LEN;
+
+ if (offset + size > length)
+ return INCOMPLETE_DATA;
+
+ switch (type) {
+ case SERVER_NAME_INDICATION:
+ ret = SNI_PARSE(ssl, input + offset, size, isRequest);
+ break;
+
+ case HELLO_EXT_SIG_ALGO:
+ if (isRequest) {
+ /* do not mess with offset inside the switch! */
+ if (IsAtLeastTLSv1_2(ssl)) {
+ ato16(input + offset, &suites->hashSigAlgoSz);
+
+ if (suites->hashSigAlgoSz > size - OPAQUE16_LEN)
+ return INCOMPLETE_DATA;
+
+ XMEMCPY(suites->hashSigAlgo,
+ input + offset + OPAQUE16_LEN,
+ min(suites->hashSigAlgoSz,
+ HELLO_EXT_SIGALGO_MAX));
+ }
+ } else {
+ CYASSL_MSG("Servers MUST NOT send SIG ALGO extension.");
+ }
+
+ break;
+ }
+
+ /* offset should be updated here! */
+ offset += size;
+ }
+
+ return ret;
+}
+
+/* undefining semaphore macros */
+#undef IS_OFF
+#undef TURN_ON
+
+#endif /* HAVE_TLS_EXTENSIONS */
+
#ifndef NO_CYASSL_CLIENT
diff --git a/tests/api.c b/tests/api.c
index 3dbb22801..fe17fa562 100644
--- a/tests/api.c
+++ b/tests/api.c
@@ -47,6 +47,11 @@ static int test_client_CyaSSL_new(void);
static int test_CyaSSL_read_write(void);
#endif /* NO_RSA */
#endif /* NO_FILESYSTEM */
+#ifdef HAVE_TLS_EXTENSIONS
+#ifdef HAVE_SNI
+static void test_CyaSSL_UseSNI(void);
+#endif /* HAVE_TLS_EXTENSIONS */
+#endif /* HAVE_SNI */
/* test function helpers */
static int test_method(CYASSL_METHOD *method, const char *name);
@@ -91,6 +96,11 @@ int ApiTest(void)
test_CyaSSL_read_write();
#endif /* NO_RSA */
#endif /* NO_FILESYSTEM */
+#ifdef HAVE_TLS_EXTENSIONS
+#ifdef HAVE_SNI
+ test_CyaSSL_UseSNI();
+#endif /* HAVE_SNI */
+#endif /* HAVE_TLS_EXTENSIONS */
test_CyaSSL_Cleanup();
printf(" End API Tests\n");
@@ -211,6 +221,34 @@ int test_CyaSSL_CTX_new(CYASSL_METHOD *method)
return TEST_SUCCESS;
}
+#ifdef HAVE_TLS_EXTENSIONS
+#ifdef HAVE_SNI
+void test_CyaSSL_UseSNI(void)
+{
+ CYASSL_CTX *ctx = CyaSSL_CTX_new(CyaSSLv23_client_method());
+ CYASSL *ssl = CyaSSL_new(ctx);
+
+ AssertNotNull(ctx);
+ AssertNotNull(ssl);
+
+ /* error cases */
+ AssertIntNE(0, CyaSSL_CTX_UseSNI(NULL, 0, (void *) "ctx", XSTRLEN("ctx")));
+ AssertIntNE(0, CyaSSL_UseSNI( NULL, 0, (void *) "ssl", XSTRLEN("ssl")));
+ AssertIntNE(0, CyaSSL_CTX_UseSNI(ctx, -1, (void *) "ctx", XSTRLEN("ctx")));
+ AssertIntNE(0, CyaSSL_UseSNI( ssl, -1, (void *) "ssl", XSTRLEN("ssl")));
+ AssertIntNE(0, CyaSSL_CTX_UseSNI(ctx, 0, (void *) NULL, XSTRLEN("ctx")));
+ AssertIntNE(0, CyaSSL_UseSNI( ssl, 0, (void *) NULL, XSTRLEN("ssl")));
+
+ /* success case */
+ AssertIntEQ(0, CyaSSL_CTX_UseSNI(ctx, 0, (void *) "ctx", XSTRLEN("ctx")));
+ AssertIntEQ(0, CyaSSL_UseSNI( ssl, 0, (void *) "ssl", XSTRLEN("ssl")));
+
+ CyaSSL_free(ssl);
+ CyaSSL_CTX_free(ctx);
+}
+#endif /* HAVE_SNI */
+#endif /* HAVE_TLS_EXTENSIONS */
+
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
/* Helper for testing CyaSSL_CTX_use_certificate_file() */
int test_ucf(CYASSL_CTX *ctx, const char* file, int type, int cond,
diff --git a/tests/unit.h b/tests/unit.h
index 097069bd2..f20f52ff7 100644
--- a/tests/unit.h
+++ b/tests/unit.h
@@ -5,6 +5,56 @@
#include /* thread and tcp stuff */
+#define Fail(description, result) do { \
+ printf("\nERROR - %s line %d failed with:", __FILE__, __LINE__); \
+ printf("\n\n test: "); printf description; \
+ printf("\n\n result: "); printf result; \
+ abort(); \
+} while(0)
+
+#define Assert(test, description, result) if (!(test)) Fail(description, result)
+
+#define AssertTrue(x) Assert( (x), ("%s is true", #x), (#x " => FALSE"))
+#define AssertFalse(x) Assert(!(x), ("%s is false", #x), (#x " => TRUE"))
+#define AssertNotNull(x) Assert( (x), ("%s is not null", #x), (#x " => NULL"))
+
+#define AssertNull(x) do { \
+ void* _x = (void *) (x); \
+ \
+ Assert(!_x, ("%s is null", #x), (#x " => %p", _x)); \
+} while(0)
+
+#define AssertInt(x, y, op, er) do { \
+ int _x = x; \
+ int _y = y; \
+ \
+ Assert(_x op _y, ("%s " #op " %s", #x, #y), ("%d " #er " %d", _x, _y)); \
+} while(0)
+
+#define AssertIntEQ(x, y) AssertInt(x, y, ==, !=)
+#define AssertIntNE(x, y) AssertInt(x, y, !=, ==)
+#define AssertIntGT(x, y) AssertInt(x, y, >, <=)
+#define AssertIntLT(x, y) AssertInt(x, y, <, >=)
+#define AssertIntGE(x, y) AssertInt(x, y, >=, <)
+#define AssertIntLE(x, y) AssertInt(x, y, <=, >)
+
+#define AssertStr(x, y, op, er) do { \
+ const char* _x = x; \
+ const char* _y = y; \
+ int _z = strcmp(_x, _y); \
+ \
+ Assert(_z op 0, ("%s " #op " %s", #x, #y), \
+ ("\"%s\" " #er " \"%s\"", _x, _y));\
+} while(0)
+
+#define AssertStrEQ(x, y) AssertStr(x, y, ==, !=)
+#define AssertStrNE(x, y) AssertStr(x, y, !=, ==)
+#define AssertStrGT(x, y) AssertStr(x, y, >, <=)
+#define AssertStrLT(x, y) AssertStr(x, y, <, >=)
+#define AssertStrGE(x, y) AssertStr(x, y, >=, <)
+#define AssertStrLE(x, y) AssertStr(x, y, <=, >)
+
+
int ApiTest(void);
int SuiteTest(void);
int HashTest(void);