forked from wolfSSL/wolfssl
Merge branch 'alpn'
This commit is contained in:
@ -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) {
|
||||
|
@ -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);
|
||||
|
22
src/ssl.c
22
src/ssl.c
@ -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 */
|
||||
|
34
src/tls.c
34
src/tls.c
@ -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
|
||||
|
24
tests/api.c
24
tests/api.c
@ -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},
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
Reference in New Issue
Block a user