Merge branch 'master' of github.com:cyassl/cyassl

This commit is contained in:
toddouska
2012-08-08 11:36:08 -07:00
3 changed files with 76 additions and 8 deletions

View File

@ -374,6 +374,7 @@ enum Misc {
SEED_LEN = RAN_LEN * 2, /* tls prf seed length */ SEED_LEN = RAN_LEN * 2, /* tls prf seed length */
ID_LEN = 32, /* session id length */ ID_LEN = 32, /* session id length */
MAX_COOKIE_LEN = 32, /* max dtls cookie size */ MAX_COOKIE_LEN = 32, /* max dtls cookie size */
COOKIE_SZ = 20, /* use a 20 byte cookie */
SUITE_LEN = 2, /* cipher suite sz length */ SUITE_LEN = 2, /* cipher suite sz length */
ENUM_LEN = 1, /* always a byte */ ENUM_LEN = 1, /* always a byte */
COMP_LEN = 1, /* compression length */ COMP_LEN = 1, /* compression length */
@ -650,6 +651,8 @@ int SetCipherList(Suites*, const char* list);
#endif #endif
#ifdef CYASSL_DTLS #ifdef CYASSL_DTLS
CYASSL_LOCAL
int EmbedGenerateCookie(byte *buf, int sz, void *ctx);
CYASSL_LOCAL CYASSL_LOCAL
int IsUDP(void*); int IsUDP(void*);
#endif #endif
@ -1127,6 +1130,7 @@ typedef struct Arrays {
byte masterSecret[SECRET_LEN]; byte masterSecret[SECRET_LEN];
#ifdef CYASSL_DTLS #ifdef CYASSL_DTLS
byte cookie[MAX_COOKIE_LEN]; byte cookie[MAX_COOKIE_LEN];
byte cookieSz;
#endif #endif
#ifndef NO_PSK #ifndef NO_PSK
char client_identity[MAX_PSK_ID_LEN]; char client_identity[MAX_PSK_ID_LEN];

View File

@ -4398,6 +4398,7 @@ int SetCipherList(Suites* s, const char* list)
#ifdef CYASSL_DTLS #ifdef CYASSL_DTLS
if (ssl->options.dtls) { if (ssl->options.dtls) {
length += ENUM_LEN; /* cookie */ length += ENUM_LEN; /* cookie */
if (ssl->arrays.cookieSz != 0) length += ssl->arrays.cookieSz;
sendSz = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ; sendSz = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA; idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
} }
@ -4442,7 +4443,13 @@ int SetCipherList(Suites* s, const char* list)
/* then DTLS cookie */ /* then DTLS cookie */
#ifdef CYASSL_DTLS #ifdef CYASSL_DTLS
if (ssl->options.dtls) { if (ssl->options.dtls) {
output[idx++] = 0; byte cookieSz = ssl->arrays.cookieSz;
output[idx++] = cookieSz;
if (cookieSz) {
XMEMCPY(&output[idx], ssl->arrays.cookie, cookieSz);
idx += cookieSz;
}
} }
#endif #endif
/* then cipher suites */ /* then cipher suites */
@ -4513,8 +4520,15 @@ int SetCipherList(Suites* s, const char* list)
cookieSz = input[(*inOutIdx)++]; cookieSz = input[(*inOutIdx)++];
if (cookieSz) if (cookieSz) {
*inOutIdx += cookieSz; /* skip for now */ #ifdef CYASSL_DTLS
if (cookieSz < MAX_COOKIE_LEN) {
XMEMCPY(ssl->arrays.cookie, input + *inOutIdx, cookieSz);
ssl->arrays.cookieSz = cookieSz;
}
#endif
*inOutIdx += cookieSz;
}
ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE; ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
return 0; return 0;
@ -6411,11 +6425,16 @@ int SetCipherList(Suites* s, const char* list)
if (ssl->options.dtls) { if (ssl->options.dtls) {
b = input[i++]; b = input[i++];
if (b) { if (b) {
byte cookie[MAX_COOKIE_LEN];
byte cookieSz;
if (b > MAX_COOKIE_LEN) if (b > MAX_COOKIE_LEN)
return BUFFER_ERROR; return BUFFER_ERROR;
if (i + b > totalSz) if (i + b > totalSz)
return INCOMPLETE_DATA; return INCOMPLETE_DATA;
XMEMCPY(ssl->arrays.cookie, input + i, b); cookieSz = EmbedGenerateCookie(cookie, COOKIE_SZ, ssl);
if ((b != cookieSz) || XMEMCMP(cookie, input + i, b) != 0)
return PARSE_ERROR;
i += b; i += b;
} }
} }
@ -6604,11 +6623,12 @@ int SetCipherList(Suites* s, const char* list)
return SendBuffered(ssl); return SendBuffered(ssl);
} }
#ifdef CYASSL_DTLS
int SendHelloVerifyRequest(CYASSL* ssl) int SendHelloVerifyRequest(CYASSL* ssl)
{ {
byte* output; byte* output;
int length = VERSION_SZ + ENUM_LEN; byte cookieSz = COOKIE_SZ;
int length = VERSION_SZ + ENUM_LEN + cookieSz;
int idx = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ; int idx = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
int sendSz = length + idx; int sendSz = length + idx;
int ret; int ret;
@ -6625,7 +6645,10 @@ int SetCipherList(Suites* s, const char* list)
XMEMCPY(output + idx, &ssl->chVersion, VERSION_SZ); XMEMCPY(output + idx, &ssl->chVersion, VERSION_SZ);
idx += VERSION_SZ; idx += VERSION_SZ;
output[idx++] = 0; /* no cookie for now */
output[idx++] = cookieSz;
if ((ret = EmbedGenerateCookie(output + idx, cookieSz, ssl)) < 0)
return ret;
HashOutput(ssl, output, sendSz, 0); HashOutput(ssl, output, sendSz, 0);
#ifdef CYASSL_CALLBACKS #ifdef CYASSL_CALLBACKS
@ -6641,7 +6664,7 @@ int SetCipherList(Suites* s, const char* list)
return SendBuffered(ssl); return SendBuffered(ssl);
} }
#endif
static int DoClientKeyExchange(CYASSL* ssl, byte* input, static int DoClientKeyExchange(CYASSL* ssl, byte* input,
word32* inOutIdx) word32* inOutIdx)

View File

@ -29,6 +29,7 @@
#endif #endif
#include <cyassl/internal.h> #include <cyassl/internal.h>
#include <cyassl/ctaocrypt/sha.h>
/* if user writes own I/O callbacks they can define CYASSL_USER_IO to remove /* if user writes own I/O callbacks they can define CYASSL_USER_IO to remove
automatic setting of default I/O functions EmbedSend() and EmbedReceive() automatic setting of default I/O functions EmbedSend() and EmbedReceive()
@ -200,6 +201,46 @@ int EmbedSend(char *buf, int sz, void *ctx)
} }
/* The DTLS Generate Cookie callback
* return : number of bytes copied into buf, or error
*/
int EmbedGenerateCookie(byte *buf, int sz, void *ctx)
{
CYASSL* ssl = (CYASSL*)ctx;
int sd = ssl->wfd;
struct sockaddr_storage peer;
socklen_t peerSz = sizeof(peer);
byte cookieSrc[sizeof(struct in6_addr) + sizeof(int)];
int cookieSrcSz = 0;
Sha sha;
getpeername(sd, (struct sockaddr*)&peer, &peerSz);
if (peer.ss_family == AF_INET) {
struct sockaddr_in *s = (struct sockaddr_in*)&peer;
cookieSrcSz = sizeof(struct in_addr) + sizeof(s->sin_port);
XMEMCPY(cookieSrc, &s->sin_port, sizeof(s->sin_port));
XMEMCPY(cookieSrc + sizeof(s->sin_port),
&s->sin_addr, sizeof(struct in_addr));
}
else if (peer.ss_family == AF_INET6) {
struct sockaddr_in6 *s = (struct sockaddr_in6*)&peer;
cookieSrcSz = sizeof(struct in6_addr) + sizeof(s->sin6_port);
XMEMCPY(cookieSrc, &s->sin6_port, sizeof(s->sin6_port));
XMEMCPY(cookieSrc + sizeof(s->sin6_port),
&s->sin6_addr, sizeof(struct in6_addr));
}
InitSha(&sha);
ShaUpdate(&sha, cookieSrc, cookieSrcSz);
ShaFinal(&sha, buf);
return SHA_DIGEST_SIZE;
}
#endif /* CYASSL_USER_IO */ #endif /* CYASSL_USER_IO */
CYASSL_API void CyaSSL_SetIORecv(CYASSL_CTX *ctx, CallbackIORecv CBIORecv) CYASSL_API void CyaSSL_SetIORecv(CYASSL_CTX *ctx, CallbackIORecv CBIORecv)