SSL_get_[rw]fd were documented but not implemented.
[openssl.git] / ssl / ssl_lib.c
index c757ea874e638d885ff59f5e8985d69c0b88525a..463ed16020afa8e79582a059423cd583e95b6521 100644 (file)
  */
 
 
-#include <assert.h>
+#ifdef REF_CHECK
+#  include <assert.h>
+#endif
 #include <stdio.h>
 #include <openssl/objects.h>
 #include <openssl/lhash.h>
 #include <openssl/x509v3.h>
 #include "ssl_locl.h"
+#include "kssl_lcl.h"
 
 const char *SSL_version_str=OPENSSL_VERSION_TEXT;
 
@@ -105,7 +108,7 @@ int SSL_clear(SSL *s)
 #else
        if (s->new_session)
                {
-               SSLerr(SSL_F_SSL_CLEAR,SSL_R_INTERNAL_ERROR);
+               SSLerr(SSL_F_SSL_CLEAR,ERR_R_INTERNAL_ERROR);
                return 0;
                }
 #endif
@@ -191,9 +194,9 @@ SSL *SSL_new(SSL_CTX *ctx)
        if (s == NULL) goto err;
        memset(s,0,sizeof(SSL));
 
-#ifndef        NO_KRB5
+#ifndef        OPENSSL_NO_KRB5
        s->kssl_ctx = kssl_ctx_new();
-#endif /* NO_KRB5 */
+#endif /* OPENSSL_NO_KRB5 */
 
        if (ctx->cert != NULL)
                {
@@ -218,6 +221,7 @@ SSL *SSL_new(SSL_CTX *ctx)
        s->verify_mode=ctx->verify_mode;
        s->verify_depth=ctx->verify_depth;
        s->verify_callback=ctx->default_verify_callback;
+       s->generate_session_id=ctx->generate_session_id;
        s->purpose = ctx->purpose;
        s->trust = ctx->trust;
        CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
@@ -282,44 +286,70 @@ int SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx,
     return 1;
     }
 
-int SSL_CTX_set_purpose(SSL_CTX *s, int purpose)
-{
-       if(X509_PURPOSE_get_by_id(purpose) == -1) {
-               SSLerr(SSL_F_SSL_CTX_SET_PURPOSE, SSL_R_INVALID_PURPOSE);
-               return 0;
+int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb)
+       {
+       CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+       ctx->generate_session_id = cb;
+       CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+       return 1;
        }
-       s->purpose = purpose;
+
+int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb)
+       {
+       CRYPTO_w_lock(CRYPTO_LOCK_SSL);
+       ssl->generate_session_id = cb;
+       CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
        return 1;
+       }
+
+int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
+                               unsigned int id_len)
+       {
+       /* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how
+        * we can "construct" a session to give us the desired check - ie. to
+        * find if there's a session in the hash table that would conflict with
+        * any new session built out of this id/id_len and the ssl_version in
+        * use by this SSL. */
+       SSL_SESSION r, *p;
+       r.ssl_version = ssl->version;
+       r.session_id_length = id_len;
+       memcpy(r.session_id, id, id_len);
+       /* NB: SSLv2 always uses a fixed 16-byte session ID, so even if a
+        * callback is calling us to check the uniqueness of a shorter ID, it
+        * must be compared as a padded-out ID because that is what it will be
+        * converted to when the callback has finished choosing it. */
+       if((r.ssl_version == SSL2_VERSION) &&
+                       (id_len < SSL2_SSL_SESSION_ID_LENGTH))
+               {
+               memset(r.session_id + id_len, 0,
+                       SSL2_SSL_SESSION_ID_LENGTH - id_len);
+               r.session_id_length = SSL2_SSL_SESSION_ID_LENGTH;
+               }
+
+       CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
+       p = (SSL_SESSION *)lh_retrieve(ssl->ctx->sessions, &r);
+       CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
+       return (p != NULL);
+       }
+
+int SSL_CTX_set_purpose(SSL_CTX *s, int purpose)
+{
+       return X509_PURPOSE_set(&s->purpose, purpose);
 }
 
 int SSL_set_purpose(SSL *s, int purpose)
 {
-       if(X509_PURPOSE_get_by_id(purpose) == -1) {
-               SSLerr(SSL_F_SSL_SET_PURPOSE, SSL_R_INVALID_PURPOSE);
-               return 0;
-       }
-       s->purpose = purpose;
-       return 1;
+       return X509_PURPOSE_set(&s->purpose, purpose);
 }
-       
+
 int SSL_CTX_set_trust(SSL_CTX *s, int trust)
 {
-       if(X509_TRUST_get_by_id(trust) == -1) {
-               SSLerr(SSL_F_SSL_CTX_SET_TRUST, SSL_R_INVALID_TRUST);
-               return 0;
-       }
-       s->trust = trust;
-       return 1;
+       return X509_TRUST_set(&s->trust, trust);
 }
 
 int SSL_set_trust(SSL *s, int trust)
 {
-       if(X509_TRUST_get_by_id(trust) == -1) {
-               SSLerr(SSL_F_SSL_SET_TRUST, SSL_R_INVALID_TRUST);
-               return 0;
-       }
-       s->trust = trust;
-       return 1;
+       return X509_TRUST_set(&s->trust, trust);
 }
 
 void SSL_free(SSL *s)
@@ -414,6 +444,11 @@ BIO *SSL_get_wbio(SSL *s)
        { return(s->wbio); }
 
 int SSL_get_fd(SSL *s)
+       {
+       return(SSL_get_rfc(s));
+       }
+
+int SSL_get_rfd(SSL *s)
        {
        int ret= -1;
        BIO *b,*r;
@@ -425,7 +460,19 @@ int SSL_get_fd(SSL *s)
        return(ret);
        }
 
-#ifndef NO_SOCK
+int SSL_get_wfd(SSL *s)
+       {
+       int ret= -1;
+       BIO *b,*r;
+
+       b=SSL_get_wbio(s);
+       r=BIO_find_type(b,BIO_TYPE_DESCRIPTOR);
+       if (r != NULL)
+               BIO_get_fd(r,&ret);
+       return(ret);
+       }
+
+#ifndef OPENSSL_NO_SOCK
 int SSL_set_fd(SSL *s,int fd)
        {
        int ret=0;
@@ -719,7 +766,7 @@ long SSL_get_default_timeout(SSL *s)
        return(s->method->get_timeout());
        }
 
-int SSL_read(SSL *s,char *buf,int num)
+int SSL_read(SSL *s,void *buf,int num)
        {
        if (s->handshake_func == 0)
                {
@@ -735,8 +782,14 @@ int SSL_read(SSL *s,char *buf,int num)
        return(s->method->ssl_read(s,buf,num));
        }
 
-int SSL_peek(SSL *s,char *buf,int num)
+int SSL_peek(SSL *s,void *buf,int num)
        {
+       if (s->handshake_func == 0)
+               {
+               SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED);
+               return -1;
+               }
+
        if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
                {
                return(0);
@@ -744,7 +797,7 @@ int SSL_peek(SSL *s,char *buf,int num)
        return(s->method->ssl_peek(s,buf,num));
        }
 
-int SSL_write(SSL *s,const char *buf,int num)
+int SSL_write(SSL *s,const void *buf,int num)
        {
        if (s->handshake_func == 0)
                {
@@ -1023,6 +1076,9 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p)
        int i,j=0;
        SSL_CIPHER *c;
        unsigned char *q;
+#ifndef OPENSSL_NO_KRB5
+        int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx);
+#endif /* OPENSSL_NO_KRB5 */
 
        if (sk == NULL) return(0);
        q=p;
@@ -1030,6 +1086,10 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p)
        for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
                {
                c=sk_SSL_CIPHER_value(sk,i);
+#ifndef OPENSSL_NO_KRB5
+                if ((c->algorithms & SSL_KRB5) && nokrb5)
+                    continue;
+#endif /* OPENSSL_NO_KRB5 */                    
                j=ssl_put_cipher_by_char(s,c,p);
                p+=j;
                }
@@ -1092,6 +1152,11 @@ unsigned long SSL_SESSION_hash(SSL_SESSION *a)
        return(l);
        }
 
+/* NB: If this function (or indeed the hash function which uses a sort of
+ * coarser function than this one) is changed, ensure
+ * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
+ * able to construct an SSL_SESSION that will collide with any existing session
+ * with a matching session ID. */
 int SSL_SESSION_cmp(SSL_SESSION *a,SSL_SESSION *b)
        {
        if (a->ssl_version != b->ssl_version)
@@ -1143,6 +1208,7 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
        ret->new_session_cb=NULL;
        ret->remove_session_cb=NULL;
        ret->get_session_cb=NULL;
+       ret->generate_session_id=NULL;
 
        memset((char *)&ret->stats,0,sizeof(ret->stats));
 
@@ -1316,14 +1382,14 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher)
 
        kl=SSL_C_EXPORT_PKEYLENGTH(cipher);
 
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
        rsa_tmp=(c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL);
        rsa_tmp_export=(c->rsa_tmp_cb != NULL ||
                (rsa_tmp && RSA_size(c->rsa_tmp)*8 <= kl));
 #else
        rsa_tmp=rsa_tmp_export=0;
 #endif
-#ifndef NO_DH
+#ifndef OPENSSL_NO_DH
        dh_tmp=(c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
        dh_tmp_export=(c->dh_tmp_cb != NULL ||
                (dh_tmp && DH_size(c->dh_tmp)*8 <= kl));
@@ -1397,7 +1463,7 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher)
        mask|=SSL_aNULL;
        emask|=SSL_aNULL;
 
-#ifndef NO_KRB5
+#ifndef OPENSSL_NO_KRB5
        mask|=SSL_kKRB5|SSL_aKRB5;
        emask|=SSL_kKRB5|SSL_aKRB5;
 #endif
@@ -1441,7 +1507,7 @@ X509 *ssl_get_server_send_cert(SSL *s)
                }
        else /* if (kalg & SSL_aNULL) */
                {
-               SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,SSL_R_INTERNAL_ERROR);
+               SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR);
                return(NULL);
                }
        if (c->pkeys[i].x509 == NULL) return(NULL);
@@ -1470,7 +1536,7 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,SSL_CIPHER *cipher)
                }
        else /* if (alg & SSL_aNULL) */
                {
-               SSLerr(SSL_F_SSL_GET_SIGN_PKEY,SSL_R_INTERNAL_ERROR);
+               SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR);
                return(NULL);
                }
        }
@@ -1718,6 +1784,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;
@@ -1942,7 +2012,7 @@ SSL_CTX *SSL_get_SSL_CTX(SSL *ssl)
        return(ssl->ctx);
        }
 
-#ifndef NO_STDIO
+#ifndef OPENSSL_NO_STDIO
 int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
        {
        return(X509_STORE_set_default_paths(ctx->cert_store));
@@ -2044,7 +2114,7 @@ int SSL_want(SSL *s)
  * \param cb the callback
  */
 
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
 void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,RSA *(*cb)(SSL *ssl,
                                                          int is_export,
                                                          int keylength))
@@ -2081,7 +2151,7 @@ RSA *cb(SSL *ssl,int is_export,int keylength)
  * \param dh the callback
  */
 
-#ifndef NO_DH
+#ifndef OPENSSL_NO_DH
 void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int is_export,
                                                        int keylength))
     {
@@ -2095,7 +2165,7 @@ void SSL_set_tmp_dh_callback(SSL *ssl,DH *(*dh)(SSL *ssl,int is_export,
     }
 #endif
 
-#if defined(_WINDLL) && defined(WIN16)
+#if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16)
 #include "../crypto/bio/bss_file.c"
 #endif