Zero the premaster secret after deriving the master secret in DH
[openssl.git] / ssl / ssl_lib.c
index 635b25062e8b4775d7a9d73554fbad327f3cc89e..24f314e5b93f3302cd1f053a8651df62748ec523 100644 (file)
@@ -119,7 +119,9 @@ int SSL_clear(SSL *s)
        s->client_version=s->version;
        s->rwstate=SSL_NOTHING;
        s->rstate=SSL_ST_READ_HEADER;
+#if 0
        s->read_ahead=s->ctx->read_ahead;
+#endif
 
        if (s->init_buf != NULL)
                {
@@ -189,6 +191,10 @@ SSL *SSL_new(SSL_CTX *ctx)
        if (s == NULL) goto err;
        memset(s,0,sizeof(SSL));
 
+#ifndef        NO_KRB5
+       s->kssl_ctx = kssl_ctx_new();
+#endif /* NO_KRB5 */
+
        if (ctx->cert != NULL)
                {
                /* Earlier library versions used to copy the pointer to
@@ -229,6 +235,7 @@ SSL *SSL_new(SSL_CTX *ctx)
        s->server=(ctx->method->ssl_accept == ssl_undefined_function)?0:1;
        s->options=ctx->options;
        s->mode=ctx->mode;
+       s->read_ahead=ctx->read_ahead; /* used to happen in SSL_clear */
        SSL_clear(s);
 
        CRYPTO_new_ex_data(ssl_meth,s,&s->ex_data);
@@ -573,6 +580,13 @@ int SSL_get_read_ahead(SSL *s)
 
 int SSL_pending(SSL *s)
        {
+       /* SSL_pending cannot work properly if read-ahead is enabled
+        * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)),
+        * and it is impossible to fix since SSL_pending cannot report
+        * errors that may be observed while scanning the new data.
+        * (Note that SSL_pending() is often used as a boolean value,
+        * so we'd better not return -1.)
+        */
        return(s->method->ssl_pending(s));
        }
 
@@ -1087,6 +1101,13 @@ int SSL_SESSION_cmp(SSL_SESSION *a,SSL_SESSION *b)
        return(memcmp(a->session_id,b->session_id,a->session_id_length));
        }
 
+/* These wrapper functions should remain rather than redeclaring
+ * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each
+ * variable. The reason is that the functions aren't static, they're exposed via
+ * ssl.h. */
+static IMPLEMENT_LHASH_HASH_FN(SSL_SESSION_hash, SSL_SESSION *)
+static IMPLEMENT_LHASH_COMP_FN(SSL_SESSION_cmp, SSL_SESSION *)
+
 SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
        {
        SSL_CTX *ret=NULL;
@@ -1150,7 +1171,8 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
        ret->default_passwd_callback_userdata=NULL;
        ret->client_cert_cb=NULL;
 
-       ret->sessions=lh_new(SSL_SESSION_hash,SSL_SESSION_cmp);
+       ret->sessions=lh_new(LHASH_HASH_FN(SSL_SESSION_hash),
+                       LHASH_COMP_FN(SSL_SESSION_cmp));
        if (ret->sessions == NULL) goto err;
        ret->cert_store=X509_STORE_new();
        if (ret->cert_store == NULL) goto err;
@@ -1197,8 +1219,10 @@ err2:
        return(NULL);
        }
 
+#if 0
 static void SSL_COMP_free(SSL_COMP *comp)
     { OPENSSL_free(comp); }
+#endif
 
 void SSL_CTX_free(SSL_CTX *a)
        {
@@ -1237,8 +1261,12 @@ void SSL_CTX_free(SSL_CTX *a)
                sk_X509_NAME_pop_free(a->client_CA,X509_NAME_free);
        if (a->extra_certs != NULL)
                sk_X509_pop_free(a->extra_certs,X509_free);
+#if 0 /* This should never be done, since it removes a global database */
        if (a->comp_methods != NULL)
                sk_SSL_COMP_pop_free(a->comp_methods,SSL_COMP_free);
+#else
+       a->comp_methods = NULL;
+#endif
        OPENSSL_free(a);
        }
 
@@ -1369,6 +1397,11 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher)
        mask|=SSL_aNULL;
        emask|=SSL_aNULL;
 
+#ifndef NO_KRB5
+       mask|=SSL_kKRB5|SSL_aKRB5;
+       emask|=SSL_kKRB5|SSL_aKRB5;
+#endif
+
        c->mask=mask;
        c->export_mask=emask;
        c->valid=1;
@@ -1401,6 +1434,11 @@ X509 *ssl_get_server_send_cert(SSL *s)
                else
                        i=SSL_PKEY_RSA_ENC;
                }
+       else if (kalg & SSL_aKRB5)
+               {
+               /* VRS something else here? */
+               return(NULL);
+               }
        else /* if (kalg & SSL_aNULL) */
                {
                SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,SSL_R_INTERNAL_ERROR);
@@ -1540,6 +1578,8 @@ int SSL_get_error(SSL *s,int i)
                        reason=BIO_get_retry_reason(bio);
                        if (reason == BIO_RR_CONNECT)
                                return(SSL_ERROR_WANT_CONNECT);
+                       else if (reason == BIO_RR_ACCEPT)
+                               return(SSL_ERROR_WANT_ACCEPT);
                        else
                                return(SSL_ERROR_SYSCALL); /* unknown */
                        }
@@ -1558,6 +1598,8 @@ int SSL_get_error(SSL *s,int i)
                        reason=BIO_get_retry_reason(bio);
                        if (reason == BIO_RR_CONNECT)
                                return(SSL_ERROR_WANT_CONNECT);
+                       else if (reason == BIO_RR_ACCEPT)
+                               return(SSL_ERROR_WANT_ACCEPT);
                        else
                                return(SSL_ERROR_SYSCALL);
                        }
@@ -1676,6 +1718,10 @@ SSL *SSL_dup(SSL *s)
 
                if (s->cert != NULL)
                        {
+                       if (ret->cert != NULL)
+                               {
+                               ssl_cert_free(ret->cert);
+                               }
                        ret->cert = ssl_cert_dup(s->cert);
                        if (ret->cert == NULL)
                                goto err;