new feature: if ctx==NULL in SSL_CTX_ctrl perform syntax checking only for some opera...
[openssl.git] / ssl / ssl_lib.c
index 5a639c1f49a21caaaefde08d695bde64d2d74f10..d529b8541f65d5908b34ea310ba2212a2d179a0f 100644 (file)
@@ -1132,6 +1132,17 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
                return(s->cert->cert_flags|=larg);
        case SSL_CTRL_CLEAR_CERT_FLAGS:
                return(s->cert->cert_flags &=~larg);
+
+       case SSL_CTRL_GET_RAW_CIPHERLIST:
+               if (parg)
+                       {
+                       if (s->cert->ciphers_raw == NULL)
+                               return 0;
+                       *(unsigned char **)parg = s->cert->ciphers_raw;
+                       return (int)s->cert->ciphers_rawlen;
+                       }
+               else
+                       return ssl_put_cipher_by_char(s,NULL,NULL);
        default:
                return(s->method->ssl_ctrl(s,cmd,larg,parg));
                }
@@ -1158,6 +1169,20 @@ LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx)
 long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,void *parg)
        {
        long l;
+       /* For some cases with ctx == NULL perform syntax checks */
+       if (ctx == NULL)
+               {
+               switch (cmd)
+                       {
+               case SSL_CTRL_SET_CURVES_LIST:
+                       return tls1_set_curves_list(NULL, NULL, parg);
+               case SSL_CTRL_SET_SIGALGS_LIST:
+               case SSL_CTRL_SET_CLIENT_SIGALGS_LIST:
+                       return tls1_set_sigalgs_list(NULL, parg, 0);
+               default:
+                       return 0;
+                       }
+               }
 
        switch (cmd)
                {
@@ -1412,6 +1437,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
        SSL_CIPHER *c;
        CERT *ct = s->cert;
        unsigned char *q;
+       int no_scsv = s->renegotiate;
        /* Set disabled masks for this session */
        ssl_set_client_disabled(s);
 
@@ -1426,13 +1452,22 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
                        c->algorithm_mkey & ct->mask_k ||
                        c->algorithm_auth & ct->mask_a)
                        continue;
+#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
+               if (c->id == SSL3_CK_SCSV)
+                       {
+                       if (no_scsv)
+                               continue;
+                       else
+                               no_scsv = 1;
+                       }
+#endif
                j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
                p+=j;
                }
        /* If p == q, no ciphers and caller indicates an error. Otherwise
         * add SCSV if not renegotiating.
         */
-       if (p != q && !s->renegotiate)
+       if (p != q && !no_scsv)
                {
                static SSL_CIPHER scsv =
                        {
@@ -1471,6 +1506,16 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
                sk_SSL_CIPHER_zero(sk);
                }
 
+       if (s->cert->ciphers_raw)
+               OPENSSL_free(s->cert->ciphers_raw);
+       s->cert->ciphers_raw = BUF_memdup(p, num);
+       if (s->cert->ciphers_raw == NULL)
+               {
+               SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
+               goto err;
+               }
+       s->cert->ciphers_rawlen = (size_t)num;
+
        for (i=0; i<num; i+=n)
                {
                /* Check for SCSV */
@@ -2833,14 +2878,6 @@ void ssl_clear_cipher_ctx(SSL *s)
 /* Fix this function so that it takes an optional type parameter */
 X509 *SSL_get_certificate(const SSL *s)
        {
-       if (s->server)
-               {
-               CERT_PKEY *certpkey;
-               certpkey = ssl_get_server_send_pkey(s);
-               if (certpkey && certpkey->x509)
-                       return certpkey->x509;
-               }
-
        if (s->cert != NULL)
                return(s->cert->key->x509);
        else