add DH param setting by file and buffer, by ctx too

This commit is contained in:
toddouska
2011-11-01 14:05:14 -07:00
parent f97759c9e1
commit 948a901cfc
10 changed files with 206 additions and 32 deletions

29
certs/dh2048.pem Normal file
View File

@ -0,0 +1,29 @@
Diffie-Hellman-Parameters: (2048 bit)
prime:
00:b0:a1:08:06:9c:08:13:ba:59:06:3c:bc:30:d5:
f5:00:c1:4f:44:a7:d6:ef:4a:c6:25:27:1c:e8:d2:
96:53:0a:5c:91:dd:a2:c2:94:84:bf:7d:b2:44:9f:
9b:d2:c1:8a:c5:be:72:5c:a7:e7:91:e6:d4:9f:73:
07:85:5b:66:48:c7:70:fa:b4:ee:02:c9:3d:9a:4a:
da:3d:c1:46:3e:19:69:d1:17:46:07:a3:4d:9f:2b:
96:17:39:6d:30:8d:2a:f3:94:d3:75:cf:a0:75:e6:
f2:92:1f:1a:70:05:aa:04:83:57:30:fb:da:76:93:
38:50:e8:27:fd:63:ee:3c:e5:b7:c8:09:ae:6f:50:
35:8e:84:ce:4a:00:e9:12:7e:5a:31:d7:33:fc:21:
13:76:cc:16:30:db:0c:fc:c5:62:a7:35:b8:ef:b7:
b0:ac:c0:36:f6:d9:c9:46:48:f9:40:90:00:2b:1b:
aa:6c:e3:1a:c3:0b:03:9e:1b:c2:46:e4:48:4e:22:
73:6f:c3:5f:d4:9a:d6:30:07:48:d6:8c:90:ab:d4:
f6:f1:e3:48:d3:58:4b:a6:b9:cd:29:bf:68:1f:08:
4b:63:86:2f:5c:6b:d6:b6:06:65:f7:a6:dc:00:67:
6b:bb:c3:a9:41:83:fb:c7:fa:c8:e2:1e:7e:af:00:
3f:93
generator: 2 (0x2)
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEAsKEIBpwIE7pZBjy8MNX1AMFPRKfW70rGJScc6NKWUwpckd2iwpSE
v32yRJ+b0sGKxb5yXKfnkebUn3MHhVtmSMdw+rTuAsk9mkraPcFGPhlp0RdGB6NN
nyuWFzltMI0q85TTdc+gdebykh8acAWqBINXMPvadpM4UOgn/WPuPOW3yAmub1A1
joTOSgDpEn5aMdcz/CETdswWMNsM/MVipzW477ewrMA29tnJRkj5QJAAKxuqbOMa
wwsDnhvCRuRITiJzb8Nf1JrWMAdI1oyQq9T28eNI01hLprnNKb9oHwhLY4YvXGvW
tgZl96bcAGdru8OpQYP7x/rI4h5+rwA/kwIBAg==
-----END DH PARAMETERS-----

View File

@ -10,6 +10,7 @@ certs_DATA+= \
certs/client-key.pem \
certs/ecc-key.pem \
certs/ntru-cert.pem \
certs/dh2048.pem \
certs/server-cert.pem \
certs/server-ecc.pem \
certs/server-keyEnc.pem \

View File

@ -909,18 +909,24 @@ int DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
byte* g, word32* gInOutSz)
{
word32 i = 0;
byte b = input[i++];
byte b;
int length;
if (GetSequence(input, &i, &length, inSz) < 0)
return ASN_PARSE_E;
b = input[i++];
if (b != ASN_INTEGER)
return ASN_PARSE_E;
if (GetLength(input, &i, &length, inSz) < 0)
return ASN_PARSE_E;
if ( (b = input[i++]) == 0x00)
length--;
else
i--;
if (length <= *pInOutSz) {
XMEMCPY(p, &input[i], length);
*pInOutSz = length;
@ -930,6 +936,7 @@ int DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
i += length;
b = input[i++];
if (b != ASN_INTEGER)
return ASN_PARSE_E;

View File

@ -290,6 +290,7 @@ enum Misc {
ALERT_SIZE = 2, /* level + description */
REQUEST_HEADER = 2, /* always use 2 bytes */
VERIFY_HEADER = 2, /* always use 2 bytes */
MAX_DH_SIZE = 513, /* 4096 bit plus possible leading 0 */
MAX_SUITE_SZ = 200, /* 100 suites for now! */
RAN_LEN = 32, /* random length */
@ -569,6 +570,8 @@ struct CYASSL_CTX {
buffer certChain;
/* chain after self, in DER, with leading size for each cert */
buffer privateKey;
buffer serverDH_P;
buffer serverDH_G;
Signer* caList; /* CYASSL_CTX owns this, SSL will reference */
Suites suites;
void* heap; /* for user memory overrides */
@ -843,8 +846,8 @@ typedef struct Buffers {
buffer certChain; /* CYASSL_CTX owns */
/* chain after self, in DER, with leading size for each cert */
buffer domainName; /* for client check */
buffer serverDH_P;
buffer serverDH_G;
buffer serverDH_P; /* CYASSL_CTX owns, unless we own */
buffer serverDH_G; /* CYASSL_CTX owns, unless we own */
buffer serverDH_Pub;
buffer serverDH_Priv;
bufferStatic inputBuffer;
@ -856,6 +859,7 @@ typedef struct Buffers {
when got WANT_WRITE */
byte weOwnCert; /* SSL own cert flag */
byte weOwnKey; /* SSL own key flag */
byte weOwnDH; /* SSL own dh (p,g) flag */
} Buffers;

View File

@ -672,7 +672,7 @@ CYASSL_API char* CyaSSL_X509_get_subjectCN(CYASSL_X509*);
/* connect enough to get peer cert */
CYASSL_API int CyaSSL_connect_cert(CYASSL* ssl);
/* server CTX Diffie-Hellman parameters */
/* server Diffie-Hellman parameters */
CYASSL_API int CyaSSL_SetTmpDH(CYASSL*, unsigned char* p, int pSz,
unsigned char* g, int gSz);
CYASSL_API int CyaSSL_SetTmpDH_buffer(CYASSL*, unsigned char* b, long sz,
@ -681,6 +681,16 @@ CYASSL_API int CyaSSL_SetTmpDH_buffer(CYASSL*, unsigned char* b, long sz,
CYASSL_API int CyaSSL_SetTmpDH_file(CYASSL*, const char* f, int format);
#endif
/* server ctx Diffie-Hellman parameters */
CYASSL_API int CyaSSL_CTX_SetTmpDH(CYASSL_CTX*, unsigned char* p, int pSz,
unsigned char* g, int gSz);
CYASSL_API int CyaSSL_CTX_SetTmpDH_buffer(CYASSL_CTX*, unsigned char* b,
long sz, int format);
#ifndef NO_FILESYSTEM
CYASSL_API int CyaSSL_CTX_SetTmpDH_file(CYASSL_CTX*, const char* f,
int format);
#endif
/* keyblock size in bytes or -1 */
CYASSL_API int CyaSSL_get_keyblock_size(CYASSL*);
CYASSL_API int CyaSSL_get_keys(CYASSL*,unsigned char** ms, unsigned int* msLen,

View File

@ -106,6 +106,7 @@ static const char* cliCert = "./certs/client-cert.pem";
static const char* cliKey = "./certs/client-key.pem";
static const char* ntruCert = "./certs/ntru-cert.pem";
static const char* ntruKey = "./certs/ntru-key.raw";
static const char* dhParam = "./certs/dh2048.pem";
typedef struct tcp_ready {
int ready; /* predicate */
@ -594,6 +595,33 @@ static INLINE void SetDH(SSL* ssl)
CyaSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g));
}
static INLINE void SetDHCtx(SSL_CTX* ctx)
{
/* dh1024 p */
static unsigned char p[] =
{
0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3,
0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E,
0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59,
0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2,
0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD,
0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF,
0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02,
0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C,
0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7,
0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50,
0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B,
};
/* dh1024 g */
static unsigned char g[] =
{
0x02,
};
CyaSSL_CTX_SetTmpDH(ctx, p, sizeof(p), g, sizeof(g));
}
#ifdef USE_WINDOWS_API
/* do back x number of directories */

View File

@ -149,7 +149,11 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
ssl = SSL_new(ctx);
if (ssl == NULL) err_sys("SSL_new failed");
SSL_set_fd(ssl, clientfd);
SetDH(ssl);
#ifdef NO_FILESYSTEM
SetDH(ssl);
#else
CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
#endif
if (SSL_accept(ssl) != SSL_SUCCESS) {
printf("SSL_accept failed\n");
SSL_free(ssl);

View File

@ -150,7 +150,11 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
SSL_set_fd(ssl, clientfd);
#ifdef NO_PSK
SetDH(ssl); /* will repick suites with DHE, higher priority than PSK */
#ifdef NO_FILESYSTEM
SetDH(ssl); /* will repick suites with DHE, higher priority than PSK */
#else
CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
#endif
#endif
#ifdef NON_BLOCKING

View File

@ -328,6 +328,8 @@ void InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
ctx->certificate.buffer = 0;
ctx->certChain.buffer = 0;
ctx->privateKey.buffer = 0;
ctx->serverDH_P.buffer = 0;
ctx->serverDH_G.buffer = 0;
ctx->haveDH = 0;
ctx->haveNTRU = 0; /* start off */
ctx->haveECDSA = 0; /* start off */
@ -384,6 +386,8 @@ void InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
/* In case contexts are held in array and don't want to free actual ctx */
void SSL_CtxResourceFree(CYASSL_CTX* ctx)
{
XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
@ -681,7 +685,10 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
ssl->options.closeNotify = 0;
ssl->options.sentNotify = 0;
ssl->options.usingCompression = 0;
ssl->options.haveDH = ctx->haveDH;
if (ssl->options.side == SERVER_END)
ssl->options.haveDH = ctx->haveDH;
else
ssl->options.haveDH = 0;
ssl->options.haveNTRU = ctx->haveNTRU;
ssl->options.haveECDSA = ctx->haveECDSA;
ssl->options.havePeerCert = 0;
@ -727,12 +734,17 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
ssl->options.quietShutdown = ctx->quietShutdown;
ssl->options.certOnly = 0;
/* CYASSL_CTX still owns certificate, certChain, key, and caList buffers */
/* ctx still owns certificate, certChain, key, dh, and caList buffers */
ssl->buffers.certificate = ctx->certificate;
ssl->buffers.certChain = ctx->certChain;
ssl->buffers.key = ctx->privateKey;
if (ssl->options.side == SERVER_END) {
ssl->buffers.serverDH_P = ctx->serverDH_P;
ssl->buffers.serverDH_G = ctx->serverDH_G;
}
ssl->buffers.weOwnCert = 0;
ssl->buffers.weOwnKey = 0;
ssl->buffers.weOwnDH = 0;
#ifdef OPENSSL_EXTRA
ssl->peerCert.issuer.sz = 0;
@ -810,8 +822,11 @@ void SSL_ResourceFree(CYASSL* ssl)
{
XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
/* parameters (p,g) may be owned by ctx */
if (ssl->buffers.weOwnDH) {
XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
}
XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
/* CYASSL_CTX always owns certChain */

116
src/ssl.c
View File

@ -167,9 +167,6 @@ int CyaSSL_negotiate(CYASSL* ssl)
}
/* server Diffie-Hellman parameters */
int CyaSSL_SetTmpDH(CYASSL* ssl, unsigned char* p, int pSz, unsigned char* g,
int gSz)
@ -182,11 +179,12 @@ int CyaSSL_SetTmpDH(CYASSL* ssl, unsigned char* p, int pSz, unsigned char* g,
if (ssl->options.side != SERVER_END)
return SIDE_ERROR;
if (ssl->buffers.serverDH_P.buffer)
if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH)
XFREE(ssl->buffers.serverDH_P.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
if (ssl->buffers.serverDH_G.buffer)
if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH)
XFREE(ssl->buffers.serverDH_G.buffer, ssl->ctx->heap, DYNAMIC_TYPE_DH);
ssl->buffers.weOwnDH = 1; /* SSL owns now */
ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->ctx->heap,
DYNAMIC_TYPE_DH);
if (ssl->buffers.serverDH_P.buffer == NULL)
@ -212,6 +210,7 @@ int CyaSSL_SetTmpDH(CYASSL* ssl, unsigned char* p, int pSz, unsigned char* g,
InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH,
havePSK, ssl->options.haveNTRU, ssl->options.haveECDSA,
ssl->ctx->method->side);
CYASSL_LEAVE("CyaSSL_SetTmpDH", 0);
return 0;
}
@ -534,8 +533,9 @@ int AddCA(CYASSL_CTX* ctx, buffer der)
dynamicType = (type == CA_TYPE) ? DYNAMIC_TYPE_CA :
DYNAMIC_TYPE_CERT;
} else if (type == DH_PARAM_TYPE) {
XSTRNCPY(header, "-----BEGIN DH PARAMETERS-----", sizeof(header));
XSTRNCPY(footer, "-----END DH PARAMETERS-----", sizeof(footer));
dynamicType = DYNAMIC_TYPE_KEY;
} else {
XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----", sizeof(header));
XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----", sizeof(footer));
@ -640,7 +640,8 @@ int AddCA(CYASSL_CTX* ctx, buffer der)
else
return SSL_BAD_FILE;
info->consumed = (long)(consumedEnd - (char*)buff);
if (info)
info->consumed = (long)(consumedEnd - (char*)buff);
/* set up der buffer */
neededSz = (long)(footerEnd - headerEnd);
@ -1189,16 +1190,17 @@ int CyaSSL_use_certificate_chain_file(CYASSL* ssl, const char* file)
}
/* server Diffie-Hellman parameters */
int CyaSSL_SetTmpDH_buffer(CYASSL* ssl, unsigned char* buf, long sz, int format)
/* server wrapper for ctx or ssl Diffie-Hellman parameters */
static int CyaSSL_SetTmpDH_buffer_wrapper(CYASSL_CTX* ctx, CYASSL* ssl,
unsigned char* buf, long sz, int format)
{
buffer der;
int ret;
int weOwnDer = 0;
byte p[1024];
byte g[1024];
int pSz = sizeof(p);
int gSz = sizeof(g);
byte p[MAX_DH_SIZE];
byte g[MAX_DH_SIZE];
word32 pSz = sizeof(p);
word32 gSz = sizeof(g);
der.buffer = buf;
der.length = sz;
@ -1207,7 +1209,8 @@ int CyaSSL_SetTmpDH_buffer(CYASSL* ssl, unsigned char* buf, long sz, int format)
return SSL_BAD_FILETYPE;
if (format == SSL_FILETYPE_PEM) {
ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, NULL, NULL, NULL);
der.buffer = NULL;
ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap, NULL,NULL);
if (ret < 0) {
XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
return ret;
@ -1217,8 +1220,12 @@ int CyaSSL_SetTmpDH_buffer(CYASSL* ssl, unsigned char* buf, long sz, int format)
if (DhParamsLoad(der.buffer, der.length, p, &pSz, g, &gSz) < 0)
ret = SSL_BAD_FILETYPE;
else
ret = CyaSSL_SetTmpDH(ssl, p, pSz, g, gSz);
else {
if (ssl)
ret = CyaSSL_SetTmpDH(ssl, p, pSz, g, gSz);
else
ret = CyaSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
}
if (weOwnDer)
XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
@ -1226,11 +1233,26 @@ int CyaSSL_SetTmpDH_buffer(CYASSL* ssl, unsigned char* buf, long sz, int format)
return ret;
}
/* server Diffie-Hellman parameters */
int CyaSSL_SetTmpDH_buffer(CYASSL* ssl, unsigned char* buf, long sz, int format)
{
return CyaSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
}
/* server ctx Diffie-Hellman parameters */
int CyaSSL_CTX_SetTmpDH_buffer(CYASSL_CTX* ctx, unsigned char* buf, long sz,
int format)
{
return CyaSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
}
#if !defined(NO_FILESYSTEM)
/* server Diffie-Hellman parameters */
int CyaSSL_SetTmpDH_file(CYASSL* ssl, const char* fname, int format)
static int CyaSSL_SetTmpDH_file_wrapper(CYASSL_CTX* ctx, CYASSL* ssl,
const char* fname, int format)
{
byte staticBuffer[FILE_BUFFER_SIZE];
byte* myBuffer = staticBuffer;
@ -1256,16 +1278,33 @@ int CyaSSL_SetTmpDH_file(CYASSL* ssl, const char* fname, int format)
if ( (ret = XFREAD(myBuffer, sz, 1, file)) < 0)
ret = SSL_BAD_FILE;
else
ret = CyaSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
else {
if (ssl)
ret = CyaSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
else
ret = CyaSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
}
XFCLOSE(file);
if (dynamic) XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
return ret;
}
/* server Diffie-Hellman parameters */
int CyaSSL_SetTmpDH_file(CYASSL* ssl, const char* fname, int format)
{
return CyaSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
}
/* server Diffie-Hellman parameters */
int CyaSSL_CTX_SetTmpDH_file(CYASSL_CTX* ctx, const char* fname, int format)
{
return CyaSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
}
#endif /* !NO_FILESYSTEM */
#endif /* OPENSSL_EXTRA */
@ -2080,7 +2119,7 @@ int AddSession(CYASSL* ssl)
for (i = 0; i < SESSION_ROWS; i++) {
double diff = SessionCache[i].totalCount - E;
diff *= diff; /* sqaure */
diff *= diff; /* square */
diff /= E; /* normalize */
chiSquare += diff;
@ -3636,6 +3675,39 @@ int CyaSSL_set_compression(CYASSL* ssl)
}
/* server ctx Diffie-Hellman parameters */
int CyaSSL_CTX_SetTmpDH(CYASSL_CTX* ctx, unsigned char* p, int pSz,
unsigned char* g, int gSz)
{
CYASSL_ENTER("CyaSSL_CTX_SetTmpDH");
if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap,DYNAMIC_TYPE_DH);
if (ctx->serverDH_P.buffer == NULL)
return MEMORY_E;
ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap,DYNAMIC_TYPE_DH);
if (ctx->serverDH_G.buffer == NULL) {
XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
return MEMORY_E;
}
ctx->serverDH_P.length = pSz;
ctx->serverDH_G.length = gSz;
XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
ctx->haveDH = 1;
CYASSL_LEAVE("CyaSSL_CTX_SetTmpDH", 0);
return 0;
}
char* CyaSSL_CIPHER_description(CYASSL_CIPHER* cipher, char* in, int len)
{
(void)cipher;