Browse Source

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

toddouska 13 years ago
parent
commit
948a901cfc
10 changed files with 205 additions and 31 deletions
  1. 29 0
      certs/dh2048.pem
  2. 1 0
      certs/include.am
  3. 8 1
      ctaocrypt/src/asn.c
  4. 6 2
      cyassl/internal.h
  5. 11 1
      cyassl/ssl.h
  6. 28 0
      cyassl/test.h
  7. 5 1
      examples/echoserver/echoserver.c
  8. 5 1
      examples/server/server.c
  9. 19 4
      src/internal.c
  10. 93 21
      src/ssl.c

+ 29 - 0
certs/dh2048.pem

@@ -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-----

+ 1 - 0
certs/include.am

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

+ 8 - 1
ctaocrypt/src/asn.c

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

+ 6 - 2
cyassl/internal.h

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

+ 11 - 1
cyassl/ssl.h

@@ -672,7 +672,7 @@ CYASSL_API char*  CyaSSL_X509_get_subjectCN(CYASSL_X509*);
 /* connect enough to get peer cert */
 /* connect enough to get peer cert */
 CYASSL_API int  CyaSSL_connect_cert(CYASSL* ssl);
 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,
 CYASSL_API int  CyaSSL_SetTmpDH(CYASSL*, unsigned char* p, int pSz,
                                 unsigned char* g, int gSz);
                                 unsigned char* g, int gSz);
 CYASSL_API int  CyaSSL_SetTmpDH_buffer(CYASSL*, unsigned char* b, long sz,
 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);
     CYASSL_API int  CyaSSL_SetTmpDH_file(CYASSL*, const char* f, int format);
 #endif
 #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 */
 /* keyblock size in bytes or -1 */
 CYASSL_API int CyaSSL_get_keyblock_size(CYASSL*);
 CYASSL_API int CyaSSL_get_keyblock_size(CYASSL*);
 CYASSL_API int CyaSSL_get_keys(CYASSL*,unsigned char** ms, unsigned int* msLen,
 CYASSL_API int CyaSSL_get_keys(CYASSL*,unsigned char** ms, unsigned int* msLen,

+ 28 - 0
cyassl/test.h

@@ -106,6 +106,7 @@ static const char* cliCert  = "./certs/client-cert.pem";
 static const char* cliKey   = "./certs/client-key.pem";
 static const char* cliKey   = "./certs/client-key.pem";
 static const char* ntruCert = "./certs/ntru-cert.pem";
 static const char* ntruCert = "./certs/ntru-cert.pem";
 static const char* ntruKey  = "./certs/ntru-key.raw";
 static const char* ntruKey  = "./certs/ntru-key.raw";
+static const char* dhParam  = "./certs/dh2048.pem";
 
 
 typedef struct tcp_ready {
 typedef struct tcp_ready {
     int ready;              /* predicate */
     int ready;              /* predicate */
@@ -594,6 +595,33 @@ static INLINE void SetDH(SSL* ssl)
     CyaSSL_SetTmpDH(ssl, p, sizeof(p), g, sizeof(g));
     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 
 #ifdef USE_WINDOWS_API 
 
 
 /* do back x number of directories */
 /* do back x number of directories */

+ 5 - 1
examples/echoserver/echoserver.c

@@ -149,7 +149,11 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
         ssl = SSL_new(ctx);
         ssl = SSL_new(ctx);
         if (ssl == NULL) err_sys("SSL_new failed");
         if (ssl == NULL) err_sys("SSL_new failed");
         SSL_set_fd(ssl, clientfd);
         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) {
         if (SSL_accept(ssl) != SSL_SUCCESS) {
             printf("SSL_accept failed\n");
             printf("SSL_accept failed\n");
             SSL_free(ssl);
             SSL_free(ssl);

+ 5 - 1
examples/server/server.c

@@ -150,7 +150,11 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
 
 
     SSL_set_fd(ssl, clientfd);
     SSL_set_fd(ssl, clientfd);
 #ifdef NO_PSK
 #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
 #endif
 
 
 #ifdef NON_BLOCKING
 #ifdef NON_BLOCKING

+ 19 - 4
src/internal.c

@@ -328,6 +328,8 @@ void InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
     ctx->certificate.buffer = 0;
     ctx->certificate.buffer = 0;
     ctx->certChain.buffer   = 0;
     ctx->certChain.buffer   = 0;
     ctx->privateKey.buffer  = 0;
     ctx->privateKey.buffer  = 0;
+    ctx->serverDH_P.buffer  = 0;
+    ctx->serverDH_G.buffer  = 0;
     ctx->haveDH             = 0;
     ctx->haveDH             = 0;
     ctx->haveNTRU           = 0;    /* start off */
     ctx->haveNTRU           = 0;    /* start off */
     ctx->haveECDSA          = 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 */
 /* In case contexts are held in array and don't want to free actual ctx */
 void SSL_CtxResourceFree(CYASSL_CTX* 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->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
     XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
     XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
     XFREE(ctx->certChain.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.closeNotify  = 0;
     ssl->options.sentNotify   = 0;
     ssl->options.sentNotify   = 0;
     ssl->options.usingCompression = 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.haveNTRU  = ctx->haveNTRU;
     ssl->options.haveECDSA = ctx->haveECDSA;
     ssl->options.haveECDSA = ctx->haveECDSA;
     ssl->options.havePeerCert = 0; 
     ssl->options.havePeerCert = 0; 
@@ -727,12 +734,17 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
     ssl->options.quietShutdown = ctx->quietShutdown;
     ssl->options.quietShutdown = ctx->quietShutdown;
     ssl->options.certOnly = 0;
     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.certificate = ctx->certificate;
     ssl->buffers.certChain = ctx->certChain;
     ssl->buffers.certChain = ctx->certChain;
     ssl->buffers.key = ctx->privateKey;
     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.weOwnCert = 0;
     ssl->buffers.weOwnKey  = 0;
     ssl->buffers.weOwnKey  = 0;
+    ssl->buffers.weOwnDH   = 0;
 
 
 #ifdef OPENSSL_EXTRA
 #ifdef OPENSSL_EXTRA
     ssl->peerCert.issuer.sz    = 0;
     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_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
     XFREE(ssl->buffers.serverDH_Pub.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);
     XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
 
 
     /* CYASSL_CTX always owns certChain */
     /* CYASSL_CTX always owns certChain */

+ 93 - 21
src/ssl.c

@@ -167,9 +167,6 @@ int CyaSSL_negotiate(CYASSL* ssl)
 }
 }
 
 
 
 
-
-
-
 /* server Diffie-Hellman parameters */
 /* server Diffie-Hellman parameters */
 int CyaSSL_SetTmpDH(CYASSL* ssl, unsigned char* p, int pSz, unsigned char* g,
 int CyaSSL_SetTmpDH(CYASSL* ssl, unsigned char* p, int pSz, unsigned char* g,
                     int gSz)
                     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)
     if (ssl->options.side != SERVER_END)
         return SIDE_ERROR;
         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);
         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);
         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,
     ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->ctx->heap,
                                                     DYNAMIC_TYPE_DH);
                                                     DYNAMIC_TYPE_DH);
     if (ssl->buffers.serverDH_P.buffer == NULL)
     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,
     InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH,
                havePSK, ssl->options.haveNTRU, ssl->options.haveECDSA,
                havePSK, ssl->options.haveNTRU, ssl->options.haveECDSA,
                ssl->ctx->method->side);
                ssl->ctx->method->side);
+
     CYASSL_LEAVE("CyaSSL_SetTmpDH", 0);
     CYASSL_LEAVE("CyaSSL_SetTmpDH", 0);
     return 0;
     return 0;
 }
 }
@@ -534,8 +533,9 @@ int AddCA(CYASSL_CTX* ctx, buffer der)
             dynamicType = (type == CA_TYPE) ? DYNAMIC_TYPE_CA :
             dynamicType = (type == CA_TYPE) ? DYNAMIC_TYPE_CA :
                                               DYNAMIC_TYPE_CERT;
                                               DYNAMIC_TYPE_CERT;
         } else if (type == DH_PARAM_TYPE) {
         } 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 {
         } else {
             XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----", sizeof(header));
             XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----", sizeof(header));
             XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----", sizeof(footer));
             XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----", sizeof(footer));
@@ -640,7 +640,8 @@ int AddCA(CYASSL_CTX* ctx, buffer der)
         else
         else
             return SSL_BAD_FILE;
             return SSL_BAD_FILE;
 
 
-        info->consumed = (long)(consumedEnd - (char*)buff);
+        if (info)
+            info->consumed = (long)(consumedEnd - (char*)buff);
 
 
         /* set up der buffer */
         /* set up der buffer */
         neededSz = (long)(footerEnd - headerEnd);
         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;
     buffer der;
     int    ret;
     int    ret;
     int    weOwnDer = 0;
     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.buffer = buf;
     der.length = sz;
     der.length = sz;
@@ -1207,7 +1209,8 @@ int CyaSSL_SetTmpDH_buffer(CYASSL* ssl, unsigned char* buf, long sz, int format)
         return SSL_BAD_FILETYPE;
         return SSL_BAD_FILETYPE;
 
 
     if (format == SSL_FILETYPE_PEM) {
     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) {
         if (ret < 0) {
             XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
             XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
             return ret;
             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)
     if (DhParamsLoad(der.buffer, der.length, p, &pSz, g, &gSz) < 0)
         ret = SSL_BAD_FILETYPE;
         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)
     if (weOwnDer)
         XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
         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;
     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)
 #if !defined(NO_FILESYSTEM)
 
 
 /* server Diffie-Hellman parameters */
 /* 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   staticBuffer[FILE_BUFFER_SIZE];
     byte*  myBuffer = staticBuffer;
     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)
     if ( (ret = XFREAD(myBuffer, sz, 1, file)) < 0)
         ret = SSL_BAD_FILE;
         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);
     XFCLOSE(file);
     if (dynamic) XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
     if (dynamic) XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
 
 
     return ret;
     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 /* !NO_FILESYSTEM */
 #endif /* OPENSSL_EXTRA */
 #endif /* OPENSSL_EXTRA */
 
 
@@ -2080,7 +2119,7 @@ int AddSession(CYASSL* ssl)
 
 
         for (i = 0; i < SESSION_ROWS; i++) {
         for (i = 0; i < SESSION_ROWS; i++) {
             double diff = SessionCache[i].totalCount - E;
             double diff = SessionCache[i].totalCount - E;
-            diff *= diff;                /* sqaure    */
+            diff *= diff;                /* square    */
             diff /= E;                   /* normalize */
             diff /= E;                   /* normalize */
 
 
             chiSquare += diff;
             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)
     char* CyaSSL_CIPHER_description(CYASSL_CIPHER* cipher, char* in, int len)
     {
     {
         (void)cipher;
         (void)cipher;