Merge branch 'alpn'

This commit is contained in:
toddouska
2015-10-16 14:06:33 -07:00
7 changed files with 111 additions and 15 deletions

View File

@ -785,8 +785,8 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
#ifdef HAVE_ALPN
if (alpnList != NULL) {
int err;
char *protocol_name = NULL;
word16 protocol_nameSz = 0;
char *protocol_name = NULL, *list = NULL;
word16 protocol_nameSz = 0, listSz = 0;
err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name, &protocol_nameSz);
if (err == SSL_SUCCESS)
@ -796,9 +796,17 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
printf("No ALPN response sent (no match)\n");
else
printf("Getting ALPN protocol name failed\n");
err = wolfSSL_ALPN_GetPeerProtocol(ssl, &list, &listSz);
if (err == SSL_SUCCESS)
printf("List of protocol names sent by Client: %s (%d)\n",
list, listSz);
else
printf("Get list of client's protocol name failed\n");
free(list);
}
#endif
if(echoData == 0 && throughput == 0) {
ret = SSL_read(ssl, input, sizeof(input)-1);
if (ret > 0) {

View File

@ -1843,6 +1843,9 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
#ifdef HAVE_MAX_FRAGMENT
ssl->max_fragment = MAX_RECORD_SIZE;
#endif
#ifdef HAVE_ALPN
ssl->alpn_client_list = NULL;
#endif
#endif
/* default alert state (none) */
@ -2063,7 +2066,14 @@ void SSL_ResourceFree(WOLFSSL* ssl)
#endif /* HAVE_PK_CALLBACKS */
#ifdef HAVE_TLS_EXTENSIONS
TLSX_FreeAll(ssl->extensions);
#ifdef HAVE_ALPN
if (ssl->alpn_client_list != NULL) {
XFREE(ssl->alpn_client_list, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ssl->alpn_client_list = NULL;
}
#endif
#endif /* HAVE_TLS_EXTENSIONS */
#ifdef HAVE_NETX
if (ssl->nxCtx.nxPacket)
nx_packet_release(ssl->nxCtx.nxPacket);

View File

@ -952,6 +952,28 @@ int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
(void **)protocol_name, size);
}
int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
{
if (list == NULL || listSz == NULL)
return BAD_FUNC_ARG;
if (ssl->alpn_client_list == NULL)
return BUFFER_ERROR;
*listSz = (word16)XSTRLEN(ssl->alpn_client_list);
if (*listSz == 0)
return BUFFER_ERROR;
*list = (char *)XMALLOC((*listSz)+1, NULL, DYNAMIC_TYPE_OUT_BUFFER);
if (*list == NULL)
return MEMORY_ERROR;
XSTRNCPY(*list, ssl->alpn_client_list, (*listSz)+1);
(*list)[*listSz] = 0;
return SSL_SUCCESS;
}
#endif /* HAVE_ALPN */
/* Secure Renegotiation */

View File

@ -995,9 +995,9 @@ static int TLSX_SetALPN(TLSX** extensions, const void* data, word16 size)
static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length,
byte isRequest)
{
word16 size = 0;
word16 offset = 0;
word16 size = 0, offset = 0, idx = 0;
int r = BUFFER_ERROR;
byte match = 0;
TLSX *extension;
ALPN *alpn = NULL, *list;
@ -1023,20 +1023,46 @@ static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, byte *input, word16 length,
list = (ALPN*)extension->data;
/* keep the list sent by client */
if (isRequest) {
if (ssl->alpn_client_list != NULL)
XFREE(ssl->alpn_client_list, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ssl->alpn_client_list = (char *)XMALLOC(size, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (ssl->alpn_client_list == NULL)
return MEMORY_ERROR;
}
for (size = 0; offset < length; offset += size) {
size = input[offset++];
if (offset + size > length)
return BUFFER_ERROR;
if (isRequest) {
XMEMCPY(ssl->alpn_client_list+idx, (char*)input + offset, size);
idx += size;
ssl->alpn_client_list[idx++] = ',';
}
if (!match) {
alpn = TLSX_ALPN_Find(list, (char*)input + offset, size);
if (alpn != NULL) {
WOLFSSL_MSG("ALPN protocol match");
match = 1;
/* skip reading other values if not required */
if (!isRequest)
break;
}
}
}
if (alpn == NULL) {
if (isRequest)
ssl->alpn_client_list[idx-1] = 0;
if (!match) {
WOLFSSL_MSG("No ALPN protocol match");
/* do nothing if no protocol match between client and server and option
@ -1159,7 +1185,7 @@ int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz)
#else /* HAVE_ALPN */
#define ALPN_FREE_ALL(list)
#define ALPN_FREE_ALL(list) 0
#define ALPN_GET_SIZE(list) 0
#define ALPN_WRITE(a, b) 0
#define ALPN_PARSE(a, b, c, d) 0

View File

@ -1311,6 +1311,26 @@ static void verify_ALPN_matching_spdy2(WOLFSSL* ssl)
AssertIntEQ(0, XMEMCMP(nego_proto, proto, protoSz));
}
static void verify_ALPN_client_list(WOLFSSL* ssl)
{
/* http/1.1,spdy/1,spdy/2,spdy/3 */
char alpn_list[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x2c,
0x73, 0x70, 0x64, 0x79, 0x2f, 0x31, 0x2c,
0x73, 0x70, 0x64, 0x79, 0x2f, 0x32, 0x2c,
0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
char *clist = NULL;
word16 clistSz = 0;
AssertIntEQ(SSL_SUCCESS, wolfSSL_ALPN_GetPeerProtocol(ssl, &clist,
&clistSz));
/* check value */
AssertIntEQ(1, sizeof(alpn_list) == clistSz);
AssertIntEQ(0, XMEMCMP(alpn_list, clist, clistSz));
XFREE(clist, 0, DYNAMIC_TYPE_OUT_BUFFER);
}
static void test_wolfSSL_UseALPN_connection(void)
{
unsigned long i;
@ -1335,6 +1355,10 @@ static void test_wolfSSL_UseALPN_connection(void)
{0, 0, use_ALPN_all_continue, verify_ALPN_not_matching_continue},
{0, 0, use_ALPN_unknown_continue, 0},
/* success case read protocol send by client */
{0, 0, use_ALPN_all, 0},
{0, 0, use_ALPN_one, verify_ALPN_client_list},
/* missmatch behavior with same list
* the first and only this one must be taken */
{0, 0, use_ALPN_all, 0},

View File

@ -1551,6 +1551,7 @@ WOLFSSL_LOCAL int TLSX_UseALPN(TLSX** extensions, const void* data,
word16 size, byte options);
WOLFSSL_LOCAL int TLSX_ALPN_SetOptions(TLSX** extensions, const byte option);
#endif /* HAVE_ALPN */
/* Maximum Fragment Length */
@ -2448,6 +2449,9 @@ struct WOLFSSL {
#ifdef HAVE_SECURE_RENEGOTIATION
SecureRenegotiation* secure_renegotiation; /* valid pointer indicates */
#endif /* user turned on */
#ifdef HAVE_ALPN
char* alpn_client_list; /* keep the client's list */
#endif /* of accepted protocols */
#if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
CallbackSessionTicket session_ticket_cb;
void* session_ticket_ctx;

View File

@ -1372,6 +1372,8 @@ WOLFSSL_API int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
WOLFSSL_API int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name,
unsigned short *size);
WOLFSSL_API int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list,
unsigned short *listSz);
#endif /* HAVE_ALPN */
/* Maximum Fragment Length */