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);