forked from wolfSSL/wolfssl
Renames TLSX_Append to TLSX_Push, adding data param and making sure the list doesn't holds duplicate extensions.
Adds SecureRenegotiation functions
This commit is contained in:
365
src/tls.c
365
src/tls.c
@@ -703,31 +703,49 @@ int TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
|
|||||||
|
|
||||||
#ifdef HAVE_TLS_EXTENSIONS
|
#ifdef HAVE_TLS_EXTENSIONS
|
||||||
|
|
||||||
|
|
||||||
#define IS_OFF(semaphore, light) \
|
#define IS_OFF(semaphore, light) \
|
||||||
((semaphore)[(light) / 8] ^ (byte) (0x01 << ((light) % 8)))
|
((semaphore)[(light) / 8] ^ (byte) (0x01 << ((light) % 8)))
|
||||||
|
|
||||||
|
|
||||||
#define TURN_ON(semaphore, light) \
|
#define TURN_ON(semaphore, light) \
|
||||||
((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8)))
|
((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8)))
|
||||||
|
|
||||||
static int TLSX_Append(TLSX** list, TLSX_Type type)
|
|
||||||
|
static int TLSX_Push(TLSX** list, TLSX_Type type, void* data)
|
||||||
{
|
{
|
||||||
TLSX* extension;
|
TLSX* extension;
|
||||||
|
|
||||||
if (list == NULL) /* won't check type since this function is static */
|
extension = (TLSX*)XMALLOC(sizeof(TLSX), 0, DYNAMIC_TYPE_TLSX);
|
||||||
return BAD_FUNC_ARG;
|
if (extension == NULL)
|
||||||
|
|
||||||
if ((extension = XMALLOC(sizeof(TLSX), 0, DYNAMIC_TYPE_TLSX)) == NULL)
|
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
|
|
||||||
extension->type = type;
|
extension->type = type;
|
||||||
extension->data = NULL;
|
extension->data = data;
|
||||||
extension->resp = 0;
|
extension->resp = 0;
|
||||||
extension->next = *list;
|
extension->next = *list;
|
||||||
*list = extension;
|
*list = extension;
|
||||||
|
|
||||||
|
/* remove duplicated extensions, there should be only one of each type. */
|
||||||
|
do {
|
||||||
|
if (extension->next && extension->next->type == type) {
|
||||||
|
TLSX *next = extension->next;
|
||||||
|
|
||||||
|
extension->next = next->next;
|
||||||
|
next->next = NULL;
|
||||||
|
|
||||||
|
TLSX_FreeAll(next);
|
||||||
|
|
||||||
|
/* there is no way to occur more than */
|
||||||
|
/* two extensions of the same type. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while ((extension = extension->next));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_CYASSL_SERVER
|
#ifndef NO_CYASSL_SERVER
|
||||||
|
|
||||||
void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type);
|
void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type);
|
||||||
@@ -784,7 +802,7 @@ static int TLSX_SNI_Append(SNI** list, byte type, const void* data, word16 size)
|
|||||||
sni->data.host_name = XMALLOC(size + 1, 0, DYNAMIC_TYPE_TLSX);
|
sni->data.host_name = XMALLOC(size + 1, 0, DYNAMIC_TYPE_TLSX);
|
||||||
|
|
||||||
if (sni->data.host_name) {
|
if (sni->data.host_name) {
|
||||||
XSTRNCPY(sni->data.host_name, (const char*) data, size);
|
XSTRNCPY(sni->data.host_name, (const char*)data, size);
|
||||||
sni->data.host_name[size] = 0;
|
sni->data.host_name[size] = 0;
|
||||||
} else {
|
} else {
|
||||||
XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
|
XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
|
||||||
@@ -823,7 +841,7 @@ static word16 TLSX_SNI_GetSize(SNI* list)
|
|||||||
|
|
||||||
switch (sni->type) {
|
switch (sni->type) {
|
||||||
case CYASSL_SNI_HOST_NAME:
|
case CYASSL_SNI_HOST_NAME:
|
||||||
length += XSTRLEN((char*) sni->data.host_name);
|
length += XSTRLEN((char*)sni->data.host_name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -844,7 +862,7 @@ static word16 TLSX_SNI_Write(SNI* list, byte* output)
|
|||||||
|
|
||||||
switch (sni->type) {
|
switch (sni->type) {
|
||||||
case CYASSL_SNI_HOST_NAME:
|
case CYASSL_SNI_HOST_NAME:
|
||||||
length = XSTRLEN((char*) sni->data.host_name);
|
length = XSTRLEN((char*)sni->data.host_name);
|
||||||
|
|
||||||
c16toa(length, output + offset); /* sni length */
|
c16toa(length, output + offset); /* sni length */
|
||||||
offset += OPAQUE16_LEN;
|
offset += OPAQUE16_LEN;
|
||||||
@@ -941,7 +959,7 @@ static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length,
|
|||||||
if (offset + size > length)
|
if (offset + size > length)
|
||||||
return BUFFER_ERROR;
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
if (!(sni = TLSX_SNI_Find((SNI *) extension->data, type))) {
|
if (!(sni = TLSX_SNI_Find((SNI*)extension->data, type))) {
|
||||||
continue; /* not using this SNI type */
|
continue; /* not using this SNI type */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -949,7 +967,7 @@ static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length,
|
|||||||
case CYASSL_SNI_HOST_NAME: {
|
case CYASSL_SNI_HOST_NAME: {
|
||||||
byte matched = (XSTRLEN(sni->data.host_name) == size)
|
byte matched = (XSTRLEN(sni->data.host_name) == size)
|
||||||
&& (XSTRNCMP(sni->data.host_name,
|
&& (XSTRNCMP(sni->data.host_name,
|
||||||
(const char *) input + offset, size) == 0);
|
(const char*)input + offset, size) == 0);
|
||||||
|
|
||||||
if (matched || sni->options & CYASSL_SNI_ANSWER_ON_MISMATCH) {
|
if (matched || sni->options & CYASSL_SNI_ANSWER_ON_MISMATCH) {
|
||||||
int r = TLSX_UseSNI(&ssl->extensions,
|
int r = TLSX_UseSNI(&ssl->extensions,
|
||||||
@@ -979,7 +997,7 @@ static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length,
|
|||||||
|
|
||||||
int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size)
|
int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size)
|
||||||
{
|
{
|
||||||
TLSX* extension = NULL;
|
TLSX* extension = TLSX_Find(*extensions, SERVER_NAME_INDICATION);
|
||||||
SNI* sni = NULL;
|
SNI* sni = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@@ -989,37 +1007,30 @@ int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size)
|
|||||||
if ((ret = TLSX_SNI_Append(&sni, type, data, size)) != 0)
|
if ((ret = TLSX_SNI_Append(&sni, type, data, size)) != 0)
|
||||||
return ret;
|
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 (!extension) {
|
||||||
if ((ret = TLSX_Append(extensions, SERVER_NAME_INDICATION)) != 0) {
|
if ((ret = TLSX_Push(extensions, SERVER_NAME_INDICATION, (void*)sni))
|
||||||
|
!= 0) {
|
||||||
TLSX_SNI_Free(sni);
|
TLSX_SNI_Free(sni);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
extension = *extensions;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
/* push new SNI object to extension data. */
|
||||||
|
sni->next = (SNI*)extension->data;
|
||||||
|
extension->data = (void*)sni;
|
||||||
|
|
||||||
/* push new SNI object to extension data. */
|
/* look for another server name of the same type to remove */
|
||||||
sni->next = (SNI*) extension->data;
|
do {
|
||||||
extension->data = (void*) sni;
|
if (sni->next && sni->next->type == type) {
|
||||||
|
SNI *next = sni->next;
|
||||||
|
|
||||||
/* look for another server name of the same type to remove (replacement) */
|
sni->next = next->next;
|
||||||
do {
|
TLSX_SNI_Free(next);
|
||||||
if (sni->next && sni->next->type == type) {
|
|
||||||
SNI *next = sni->next;
|
|
||||||
|
|
||||||
sni->next = next->next;
|
break;
|
||||||
TLSX_SNI_Free(next);
|
}
|
||||||
|
} while ((sni = sni->next));
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
} while ((sni = sni->next));
|
|
||||||
|
|
||||||
return SSL_SUCCESS;
|
return SSL_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -1237,9 +1248,8 @@ static int TLSX_MFL_Parse(CYASSL* ssl, byte* input, word16 length,
|
|||||||
|
|
||||||
int TLSX_UseMaxFragment(TLSX** extensions, byte mfl)
|
int TLSX_UseMaxFragment(TLSX** extensions, byte mfl)
|
||||||
{
|
{
|
||||||
TLSX* extension = NULL;
|
byte* data = NULL;
|
||||||
byte* data = NULL;
|
int ret = 0;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (extensions == NULL)
|
if (extensions == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
@@ -1253,29 +1263,11 @@ int TLSX_UseMaxFragment(TLSX** extensions, byte mfl)
|
|||||||
data[0] = mfl;
|
data[0] = mfl;
|
||||||
|
|
||||||
/* push new MFL extension. */
|
/* push new MFL extension. */
|
||||||
if ((ret = TLSX_Append(extensions, MAX_FRAGMENT_LENGTH)) != 0) {
|
if ((ret = TLSX_Push(extensions, MAX_FRAGMENT_LENGTH, data)) != 0) {
|
||||||
XFREE(data, 0, DYNAMIC_TYPE_TLSX);
|
XFREE(data, 0, DYNAMIC_TYPE_TLSX);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* place new mfl to extension data. */
|
|
||||||
extension = *extensions;
|
|
||||||
extension->data = (void*) data;
|
|
||||||
|
|
||||||
/* remove duplicated extensions */
|
|
||||||
do {
|
|
||||||
if (extension->next && extension->next->type == MAX_FRAGMENT_LENGTH) {
|
|
||||||
TLSX *next = extension->next;
|
|
||||||
|
|
||||||
extension->next = next->next;
|
|
||||||
next->next = NULL;
|
|
||||||
|
|
||||||
TLSX_FreeAll(next);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while ((extension = extension->next));
|
|
||||||
|
|
||||||
return SSL_SUCCESS;
|
return SSL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1304,7 +1296,7 @@ int TLSX_UseTruncatedHMAC(TLSX** extensions)
|
|||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
if (!TLSX_Find(*extensions, TRUNCATED_HMAC))
|
if (!TLSX_Find(*extensions, TRUNCATED_HMAC))
|
||||||
if ((ret = TLSX_Append(extensions, TRUNCATED_HMAC)) != 0)
|
if ((ret = TLSX_Push(extensions, TRUNCATED_HMAC, NULL)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return SSL_SUCCESS;
|
return SSL_SUCCESS;
|
||||||
@@ -1556,7 +1548,7 @@ int TLSX_ValidateEllipticCurves(CYASSL* ssl, byte first, byte second) {
|
|||||||
|
|
||||||
int TLSX_UseSupportedCurve(TLSX** extensions, word16 name)
|
int TLSX_UseSupportedCurve(TLSX** extensions, word16 name)
|
||||||
{
|
{
|
||||||
TLSX* extension = NULL;
|
TLSX* extension = TLSX_Find(*extensions, ELLIPTIC_CURVES);
|
||||||
EllipticCurve* curve = NULL;
|
EllipticCurve* curve = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@@ -1566,37 +1558,29 @@ int TLSX_UseSupportedCurve(TLSX** extensions, word16 name)
|
|||||||
if ((ret = TLSX_EllipticCurve_Append(&curve, name)) != 0)
|
if ((ret = TLSX_EllipticCurve_Append(&curve, name)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
extension = *extensions;
|
|
||||||
|
|
||||||
/* find EllipticCurve extension if it already exists. */
|
|
||||||
while (extension && extension->type != ELLIPTIC_CURVES)
|
|
||||||
extension = extension->next;
|
|
||||||
|
|
||||||
/* push new EllipticCurve extension if it doesn't exists. */
|
|
||||||
if (!extension) {
|
if (!extension) {
|
||||||
if ((ret = TLSX_Append(extensions, ELLIPTIC_CURVES)) != 0) {
|
if ((ret = TLSX_Push(extensions, ELLIPTIC_CURVES, curve)) != 0) {
|
||||||
XFREE(curve, 0, DYNAMIC_TYPE_TLSX);
|
XFREE(curve, 0, DYNAMIC_TYPE_TLSX);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
extension = *extensions;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
/* push new EllipticCurve object to extension data. */
|
||||||
|
curve->next = (EllipticCurve*)extension->data;
|
||||||
|
extension->data = (void*)curve;
|
||||||
|
|
||||||
/* push new EllipticCurve object to extension data. */
|
/* look for another curve of the same name to remove (replacement) */
|
||||||
curve->next = (EllipticCurve*) extension->data;
|
do {
|
||||||
extension->data = (void*) curve;
|
if (curve->next && curve->next->name == name) {
|
||||||
|
EllipticCurve *next = curve->next;
|
||||||
|
|
||||||
/* look for another curve of the same name to remove (replacement) */
|
curve->next = next->next;
|
||||||
do {
|
XFREE(next, 0, DYNAMIC_TYPE_TLSX);
|
||||||
if (curve->next && curve->next->name == name) {
|
|
||||||
EllipticCurve *next = curve->next;
|
|
||||||
|
|
||||||
curve->next = next->next;
|
break;
|
||||||
XFREE(next, 0, DYNAMIC_TYPE_TLSX);
|
}
|
||||||
|
} while ((curve = curve->next));
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
} while ((curve = curve->next));
|
|
||||||
|
|
||||||
return SSL_SUCCESS;
|
return SSL_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -1627,6 +1611,113 @@ int TLSX_UseSupportedCurve(TLSX** extensions, word16 name)
|
|||||||
#define EC_VALIDATE_REQUEST(a, b)
|
#define EC_VALIDATE_REQUEST(a, b)
|
||||||
|
|
||||||
#endif /* HAVE_SUPPORTED_CURVES */
|
#endif /* HAVE_SUPPORTED_CURVES */
|
||||||
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
|
|
||||||
|
static byte TLSX_SCR_GetSize(SecureRenegotiation* data, int isRequest)
|
||||||
|
{
|
||||||
|
byte length = OPAQUE8_LEN; /* RenegotiationInfo length */
|
||||||
|
|
||||||
|
if (data->secure_renegotiation) {
|
||||||
|
/* client sends client_verify_data only */
|
||||||
|
length += TLS_FINISHED_SZ;
|
||||||
|
|
||||||
|
/* server also sends server_verify_data */
|
||||||
|
if (!isRequest)
|
||||||
|
length += TLS_FINISHED_SZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static word16 TLSX_SCR_Write(SecureRenegotiation* data, byte* output,
|
||||||
|
int isRequest)
|
||||||
|
{
|
||||||
|
word16 offset = OPAQUE8_LEN; /* RenegotiationInfo length */
|
||||||
|
|
||||||
|
output[0] = TLSX_SCR_GetSize(data, isRequest);
|
||||||
|
|
||||||
|
if (data->secure_renegotiation) {
|
||||||
|
/* client sends client_verify_data only */
|
||||||
|
XMEMCPY(output + offset, data->client_verify_data, TLS_FINISHED_SZ);
|
||||||
|
offset += TLS_FINISHED_SZ;
|
||||||
|
|
||||||
|
/* server also sends server_verify_data */
|
||||||
|
if (!isRequest) {
|
||||||
|
XMEMCPY(output + offset, data->server_verify_data, TLS_FINISHED_SZ);
|
||||||
|
offset += TLS_FINISHED_SZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TLSX_SCR_Parse(CYASSL* ssl, byte* input, word16 length,
|
||||||
|
byte isRequest)
|
||||||
|
{
|
||||||
|
if (length != ENUM_LEN)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
switch (*input) {
|
||||||
|
case CYASSL_MFL_2_9 : ssl->max_fragment = 512; break;
|
||||||
|
case CYASSL_MFL_2_10: ssl->max_fragment = 1024; break;
|
||||||
|
case CYASSL_MFL_2_11: ssl->max_fragment = 2048; break;
|
||||||
|
case CYASSL_MFL_2_12: ssl->max_fragment = 4096; break;
|
||||||
|
case CYASSL_MFL_2_13: ssl->max_fragment = 8192; break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SendAlert(ssl, alert_fatal, illegal_parameter);
|
||||||
|
|
||||||
|
return UNKNOWN_MAX_FRAG_LEN_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NO_CYASSL_SERVER
|
||||||
|
if (isRequest) {
|
||||||
|
int r = TLSX_UseMaxFragment(&ssl->extensions, *input);
|
||||||
|
|
||||||
|
if (r != SSL_SUCCESS) return r; /* throw error */
|
||||||
|
|
||||||
|
TLSX_SetResponse(ssl, MAX_FRAGMENT_LENGTH);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TLSX_UseSecureRenegotiation(TLSX** extensions)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
SecureRenegotiation* data = NULL;
|
||||||
|
|
||||||
|
data = (SecureRenegotiation*)XMALLOC(sizeof(SecureRenegotiation), NULL,
|
||||||
|
DYNAMIC_TYPE_TLSX);
|
||||||
|
if (data == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
|
||||||
|
XMEMSET(data, 0, sizeof(SecureRenegotiation));
|
||||||
|
|
||||||
|
ret = TLSX_Push(extensions, SECURE_RENEGOTIATION, data);
|
||||||
|
if (ret != 0) {
|
||||||
|
XFREE(data, 0, DYNAMIC_TYPE_TLSX);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define SCR_FREE_ALL(data) XFREE(data, NULL, DYNAMIC_TYPE_TLSX)
|
||||||
|
#define SCR_GET_SIZE TLSX_SCR_GetSize
|
||||||
|
#define SCR_WRITE TLSX_SCR_Write
|
||||||
|
#define SCR_PARSE TLSX_SCR_Parse
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define SCR_FREE_ALL(a)
|
||||||
|
#define SCR_GET_SIZE(a, b) 0
|
||||||
|
#define SCR_WRITE(a, b, c) 0
|
||||||
|
#define SCR_PARSE(a, b, c, d) 0
|
||||||
|
|
||||||
|
#endif /* HAVE_SECURE_RENEGOTIATION */
|
||||||
|
|
||||||
TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
|
TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
|
||||||
{
|
{
|
||||||
@@ -1647,7 +1738,7 @@ void TLSX_FreeAll(TLSX* list)
|
|||||||
|
|
||||||
switch (extension->type) {
|
switch (extension->type) {
|
||||||
case SERVER_NAME_INDICATION:
|
case SERVER_NAME_INDICATION:
|
||||||
SNI_FREE_ALL((SNI *) extension->data);
|
SNI_FREE_ALL((SNI*)extension->data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAX_FRAGMENT_LENGTH:
|
case MAX_FRAGMENT_LENGTH:
|
||||||
@@ -1661,6 +1752,10 @@ void TLSX_FreeAll(TLSX* list)
|
|||||||
case ELLIPTIC_CURVES:
|
case ELLIPTIC_CURVES:
|
||||||
EC_FREE_ALL(extension->data);
|
EC_FREE_ALL(extension->data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SECURE_RENEGOTIATION:
|
||||||
|
SCR_FREE_ALL(extension->data);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFREE(extension, 0, DYNAMIC_TYPE_TLSX);
|
XFREE(extension, 0, DYNAMIC_TYPE_TLSX);
|
||||||
@@ -1682,30 +1777,35 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest)
|
|||||||
if (!isRequest && !extension->resp)
|
if (!isRequest && !extension->resp)
|
||||||
continue; /* skip! */
|
continue; /* skip! */
|
||||||
|
|
||||||
if (IS_OFF(semaphore, extension->type)) {
|
if (!IS_OFF(semaphore, extension->type))
|
||||||
/* type + data length */
|
continue; /* skip! */
|
||||||
length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
|
|
||||||
|
|
||||||
switch (extension->type) {
|
/* type + data length */
|
||||||
case SERVER_NAME_INDICATION:
|
length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
|
||||||
if (isRequest)
|
|
||||||
length += SNI_GET_SIZE((SNI *) extension->data);
|
|
||||||
break;
|
|
||||||
case MAX_FRAGMENT_LENGTH:
|
|
||||||
length += MFL_GET_SIZE(extension->data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TRUNCATED_HMAC:
|
switch (extension->type) {
|
||||||
/* empty extension. */
|
case SERVER_NAME_INDICATION:
|
||||||
break;
|
if (isRequest)
|
||||||
|
length += SNI_GET_SIZE(extension->data);
|
||||||
|
break;
|
||||||
|
case MAX_FRAGMENT_LENGTH:
|
||||||
|
length += MFL_GET_SIZE(extension->data);
|
||||||
|
break;
|
||||||
|
|
||||||
case ELLIPTIC_CURVES:
|
case TRUNCATED_HMAC:
|
||||||
length += EC_GET_SIZE((EllipticCurve *) extension->data);
|
/* empty extension. */
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
TURN_ON(semaphore, extension->type);
|
case ELLIPTIC_CURVES:
|
||||||
|
length += EC_GET_SIZE(extension->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SECURE_RENEGOTIATION:
|
||||||
|
length += SCR_GET_SIZE(extension->data, isRequest);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TURN_ON(semaphore, extension->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
@@ -1724,41 +1824,44 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
|
|||||||
if (!isRequest && !extension->resp)
|
if (!isRequest && !extension->resp)
|
||||||
continue; /* skip! */
|
continue; /* skip! */
|
||||||
|
|
||||||
if (IS_OFF(semaphore, extension->type)) {
|
if (!IS_OFF(semaphore, extension->type))
|
||||||
/* extension type */
|
continue; /* skip! */
|
||||||
c16toa(extension->type, output + offset);
|
|
||||||
offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
|
|
||||||
length_offset = offset;
|
|
||||||
|
|
||||||
/* extension data should be written internally */
|
/* extension type */
|
||||||
switch (extension->type) {
|
c16toa(extension->type, output + offset);
|
||||||
case SERVER_NAME_INDICATION:
|
offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
|
||||||
if (isRequest)
|
length_offset = offset;
|
||||||
offset += SNI_WRITE((SNI *) extension->data,
|
|
||||||
output + offset);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAX_FRAGMENT_LENGTH:
|
/* extension data should be written internally */
|
||||||
offset += MFL_WRITE((byte *) extension->data,
|
switch (extension->type) {
|
||||||
output + offset);
|
case SERVER_NAME_INDICATION:
|
||||||
break;
|
if (isRequest)
|
||||||
|
offset += SNI_WRITE((SNI*)extension->data, output + offset);
|
||||||
|
break;
|
||||||
|
|
||||||
case TRUNCATED_HMAC:
|
case MAX_FRAGMENT_LENGTH:
|
||||||
/* empty extension. */
|
offset += MFL_WRITE((byte*)extension->data, output + offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TRUNCATED_HMAC:
|
||||||
|
/* empty extension. */
|
||||||
|
break;
|
||||||
|
|
||||||
case ELLIPTIC_CURVES:
|
case ELLIPTIC_CURVES:
|
||||||
offset += EC_WRITE((EllipticCurve *) extension->data,
|
offset += EC_WRITE((EllipticCurve*)extension->data,
|
||||||
output + offset);
|
output + offset);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
/* writing extension data length */
|
case SECURE_RENEGOTIATION:
|
||||||
c16toa(offset - length_offset,
|
offset += SCR_WRITE((SecureRenegotiation*)extension->data,
|
||||||
output + length_offset - OPAQUE16_LEN);
|
output + offset, isRequest);
|
||||||
|
break;
|
||||||
TURN_ON(semaphore, extension->type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* writing extension data length */
|
||||||
|
c16toa(offset - length_offset, output + length_offset - OPAQUE16_LEN);
|
||||||
|
|
||||||
|
TURN_ON(semaphore, extension->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
@@ -1927,6 +2030,12 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
|
|||||||
ret = EC_PARSE(ssl, input + offset, size, isRequest);
|
ret = EC_PARSE(ssl, input + offset, size, isRequest);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SECURE_RENEGOTIATION:
|
||||||
|
CYASSL_MSG("Secure Renegotiation extension received");
|
||||||
|
|
||||||
|
ret = SCR_PARSE(ssl, input + offset, size, isRequest);
|
||||||
|
break;
|
||||||
|
|
||||||
case HELLO_EXT_SIG_ALGO:
|
case HELLO_EXT_SIG_ALGO:
|
||||||
if (isRequest) {
|
if (isRequest) {
|
||||||
/* do not mess with offset inside the switch! */
|
/* do not mess with offset inside the switch! */
|
||||||
|
Reference in New Issue
Block a user