Allow return of supported ciphers.
[openssl.git] / ssl / t1_lib.c
index 6c988d18297fa834be08633365a958c749592f53..37cc6f6abfe01546371c1b3530606b76ecf8b1d5 100644 (file)
 #include <openssl/hmac.h>
 #include <openssl/ocsp.h>
 #include <openssl/rand.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#endif
 #include "ssl_locl.h"
 
 const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
@@ -1089,6 +1093,14 @@ void ssl_set_client_disabled(SSL *s)
        c->valid = 1;
        }
 
+int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c)
+       {
+       CERT *ct = s->cert;
+       if (c->algorithm_ssl & ct->mask_ssl || c->algorithm_mkey & ct->mask_k || c->algorithm_auth & ct->mask_a)
+               return 1;
+       return 0;
+       }
+
 unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
        {
        int extdatalen=0;
@@ -3644,6 +3656,11 @@ static int tls1_set_shared_sigalgs(SSL *s)
        TLS_SIGALGS *salgs = NULL;
        CERT *c = s->cert;
        unsigned int is_suiteb = tls1_suiteb(s);
+       if (c->shared_sigalgs)
+               {
+               OPENSSL_free(c->shared_sigalgs);
+               c->shared_sigalgs = NULL;
+               }
        /* If client use client signature algorithms if not NULL */
        if (!s->server && c->client_sigalgs && !is_suiteb)
                {
@@ -3700,6 +3717,8 @@ int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
        if (!c)
                return 0;
 
+       if (c->peer_sigalgs)
+               OPENSSL_free(c->peer_sigalgs);
        c->peer_sigalgs = OPENSSL_malloc(dsize);
        if (!c->peer_sigalgs)
                return 0;
@@ -4432,3 +4451,47 @@ int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
        }
 
 #endif
+
+#ifndef OPENSSL_NO_DH
+DH *ssl_get_auto_dh(SSL *s)
+       {
+       int dh_secbits = 80;
+       if (s->cert->dh_tmp_auto == 2)
+               return DH_get_1024_160();
+       if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+               {
+               if (s->s3->tmp.new_cipher->strength_bits == 256)
+                       dh_secbits = 128;
+               else
+                       dh_secbits = 80;
+               }
+       else
+               {
+               CERT_PKEY *cpk = ssl_get_server_send_pkey(s);
+               dh_secbits = EVP_PKEY_security_bits(cpk->privatekey);
+               }
+
+       if (dh_secbits >= 128)
+               {
+               DH *dhp = DH_new();
+               if (!dhp)
+                       return NULL;
+               dhp->g = BN_new();
+               if (dhp->g)
+                       BN_set_word(dhp->g, 2);
+               if (dh_secbits >= 192)
+                       dhp->p = get_rfc3526_prime_8192(NULL);
+               else
+                       dhp->p = get_rfc3526_prime_3072(NULL);
+               if (!dhp->p || !dhp->g)
+                       {
+                       DH_free(dhp);
+                       return NULL;
+                       }
+               return dhp;
+               }
+       if (dh_secbits >= 112)
+               return DH_get_2048_224();
+       return DH_get_1024_160();
+       }
+#endif