fix function codes for error
[openssl.git] / ssl / s3_srvr.c
index b4b95c3edb20e8bc41d94f0ff52aad3768b63d0b..7f6df691643ef93f3de780d0fdadc3fd0d55b4cd 100644 (file)
@@ -1,4 +1,4 @@
-/* ssl/s3_srvr.c */
+/* ssl/s3_srvr.c -*- mode:C; c-file-style: "eay" -*- */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -186,7 +186,7 @@ IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
 int ssl3_accept(SSL *s)
        {
        BUF_MEM *buf;
-       unsigned long l,Time=(unsigned long)time(NULL);
+       unsigned long alg_k,Time=(unsigned long)time(NULL);
        void (*cb)(const SSL *ssl,int type,int val)=NULL;
        long num1;
        int ret= -1;
@@ -323,10 +323,11 @@ int ssl3_accept(SSL *s)
 
                case SSL3_ST_SW_CERT_A:
                case SSL3_ST_SW_CERT_B:
-                       /* Check if it is anon DH or anon ECDH */
-                       /* or normal PSK */
-                       if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)
-                               && !(s->s3->tmp.new_cipher->algorithms & SSL_kPSK))
+                       /* Check if it is anon DH or anon ECDH, */
+                       /* normal PSK or KRB5 */
+                       if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+                               && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
+                               && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
                                {
                                ret=ssl3_send_server_certificate(s);
                                if (ret <= 0) goto end;
@@ -339,13 +340,13 @@ int ssl3_accept(SSL *s)
 
                case SSL3_ST_SW_KEY_EXCH_A:
                case SSL3_ST_SW_KEY_EXCH_B:
-                       l=s->s3->tmp.new_cipher->algorithms;
+                       alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
                        /* clear this, it may get reset by
                         * send_server_key_exchange */
                        if ((s->options & SSL_OP_EPHEMERAL_RSA)
 #ifndef OPENSSL_NO_KRB5
-                               && !(l & SSL_KRB5)
+                               && !(alg_k & SSL_kKRB5)
 #endif /* OPENSSL_NO_KRB5 */
                                )
                                /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
@@ -372,10 +373,11 @@ int ssl3_accept(SSL *s)
                        /* PSK: send ServerKeyExchange if PSK identity
                         * hint if provided */
 #ifndef OPENSSL_NO_PSK
-                           || ((l & SSL_kPSK) && s->ctx->psk_identity_hint)
+                           || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
 #endif
-                           || (l & SSL_kEECDH)
-                           || ((l & SSL_kRSA)
+                           || (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH))
+                           || (alg_k & SSL_kEECDH)
+                           || ((alg_k & SSL_kRSA)
                                && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
                                    || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
                                        && EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
@@ -405,15 +407,15 @@ int ssl3_accept(SSL *s)
                                /* never request cert in anonymous ciphersuites
                                 * (see section "Certificate request" in SSL 3 drafts
                                 * and in RFC 2246): */
-                               ((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) &&
+                               ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
                                 /* ... except when the application insists on verification
                                  * (against the specs, but s3_clnt.c accepts this for SSL 3) */
                                 !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
-                                 /* never request cert in Kerberos ciphersuites */
-                                (s->s3->tmp.new_cipher->algorithms & SSL_aKRB5)
+                                /* never request cert in Kerberos ciphersuites */
+                               (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)
                                /* With normal PSK Certificates and
                                 * Certificate Requests are omitted */
-                                || (s->s3->tmp.new_cipher->algorithms & SSL_kPSK))
+                               || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
                                {
                                /* no cert request */
                                skip=1;
@@ -713,9 +715,9 @@ int ssl3_get_client_hello(SSL *s)
         */
        if (s->state == SSL3_ST_SR_CLNT_HELLO_A)
                {
-               s->first_packet=1;
                s->state=SSL3_ST_SR_CLNT_HELLO_B;
                }
+       s->first_packet=1;
        n=s->method->ssl_get_message(s,
                SSL3_ST_SR_CLNT_HELLO_B,
                SSL3_ST_SR_CLNT_HELLO_C,
@@ -724,6 +726,7 @@ int ssl3_get_client_hello(SSL *s)
                &ok);
 
        if (!ok) return((int)n);
+       s->first_packet=0;
        d=p=(unsigned char *)s->init_msg;
 
        /* use version from inside client hello, not from record header
@@ -941,7 +944,7 @@ int ssl3_get_client_hello(SSL *s)
                        }
                }
                if (ssl_check_clienthello_tlsext(s) <= 0) {
-                       SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLSEXT);
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
                        goto err;
                }
 #endif
@@ -1022,7 +1025,7 @@ int ssl3_get_client_hello(SSL *s)
                        for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
                                {
                                c=sk_SSL_CIPHER_value(sk,i);
-                               if (c->algorithms & SSL_eNULL)
+                               if (c->algorithm_enc & SSL_eNULL)
                                        nc=c;
                                if (SSL_C_IS_EXPORT(c))
                                        ec=c;
@@ -1206,7 +1209,7 @@ int ssl3_send_server_key_exchange(SSL *s)
        EVP_MD_CTX_init(&md_ctx);
        if (s->state == SSL3_ST_SW_KEY_EXCH_A)
                {
-               type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK;
+               type=s->s3->tmp.new_cipher->algorithm_mkey;
                cert=s->cert;
 
                buf=s->init_buf;
@@ -1447,8 +1450,8 @@ int ssl3_send_server_key_exchange(SSL *s)
                        n+=2+nr[i];
                        }
 
-               if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)
-                       && !(s->s3->tmp.new_cipher->algorithms & SSL_kPSK))
+               if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+                       && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
                        {
                        if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
                                == NULL)
@@ -1709,7 +1712,7 @@ int ssl3_get_client_key_exchange(SSL *s)
        {
        int i,al,ok;
        long n;
-       unsigned long l;
+       unsigned long alg_k;
        unsigned char *p;
 #ifndef OPENSSL_NO_RSA
        RSA *rsa=NULL;
@@ -1720,7 +1723,7 @@ int ssl3_get_client_key_exchange(SSL *s)
        DH *dh_srvr;
 #endif
 #ifndef OPENSSL_NO_KRB5
-        KSSL_ERR kssl_err;
+       KSSL_ERR kssl_err;
 #endif /* OPENSSL_NO_KRB5 */
 
 #ifndef OPENSSL_NO_ECDH
@@ -1740,10 +1743,10 @@ int ssl3_get_client_key_exchange(SSL *s)
        if (!ok) return((int)n);
        p=(unsigned char *)s->init_msg;
 
-       l=s->s3->tmp.new_cipher->algorithms;
+       alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
 
 #ifndef OPENSSL_NO_RSA
-       if (l & SSL_kRSA)
+       if (alg_k & SSL_kRSA)
                {
                /* FIX THIS UP EAY EAY EAY EAY */
                if (s->s3->tmp.use_rsa_tmp)
@@ -1849,7 +1852,7 @@ int ssl3_get_client_key_exchange(SSL *s)
        else
 #endif
 #ifndef OPENSSL_NO_DH
-               if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+               if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
                {
                n2s(p,i);
                if (n != i+2)
@@ -1912,25 +1915,25 @@ int ssl3_get_client_key_exchange(SSL *s)
        else
 #endif
 #ifndef OPENSSL_NO_KRB5
-        if (l & SSL_kKRB5)
-                {
-                krb5_error_code                krb5rc;
+       if (alg_k & SSL_kKRB5)
+               {
+               krb5_error_code         krb5rc;
                krb5_data               enc_ticket;
                krb5_data               authenticator;
                krb5_data               enc_pms;
-                KSSL_CTX               *kssl_ctx = s->kssl_ctx;
+               KSSL_CTX                *kssl_ctx = s->kssl_ctx;
                EVP_CIPHER_CTX          ciph_ctx;
                EVP_CIPHER              *enc = NULL;
                unsigned char           iv[EVP_MAX_IV_LENGTH];
                unsigned char           pms[SSL_MAX_MASTER_KEY_LENGTH
-                                               + EVP_MAX_BLOCK_LENGTH];
-               int                     padl, outl;
+                                              + EVP_MAX_BLOCK_LENGTH];
+               int                  padl, outl;
                krb5_timestamp          authtime = 0;
                krb5_ticket_times       ttimes;
 
                EVP_CIPHER_CTX_init(&ciph_ctx);
 
-                if (!kssl_ctx)  kssl_ctx = kssl_ctx_new();
+               if (!kssl_ctx)  kssl_ctx = kssl_ctx_new();
 
                n2s(p,i);
                enc_ticket.length = i;
@@ -1981,19 +1984,19 @@ int ssl3_get_client_key_exchange(SSL *s)
                        goto err;
                        }
 
-                if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,
+               if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,
                                        &kssl_err)) != 0)
-                        {
+                       {
 #ifdef KSSL_DEBUG
-                        printf("kssl_sget_tkt rtn %d [%d]\n",
-                                krb5rc, kssl_err.reason);
-                        if (kssl_err.text)
-                                printf("kssl_err text= %s\n", kssl_err.text);
+                       printf("kssl_sget_tkt rtn %d [%d]\n",
+                               krb5rc, kssl_err.reason);
+                       if (kssl_err.text)
+                               printf("kssl_err text= %s\n", kssl_err.text);
 #endif /* KSSL_DEBUG */
-                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                                kssl_err.reason);
-                        goto err;
-                        }
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+                               kssl_err.reason);
+                       goto err;
+                       }
 
                /*  Note: no authenticator is not considered an error,
                **  but will return authtime == 0.
@@ -2002,29 +2005,29 @@ int ssl3_get_client_key_exchange(SSL *s)
                                        &authtime, &kssl_err)) != 0)
                        {
 #ifdef KSSL_DEBUG
-                        printf("kssl_check_authent rtn %d [%d]\n",
-                                krb5rc, kssl_err.reason);
-                        if (kssl_err.text)
-                                printf("kssl_err text= %s\n", kssl_err.text);
+                       printf("kssl_check_authent rtn %d [%d]\n",
+                               krb5rc, kssl_err.reason);
+                       if (kssl_err.text)
+                               printf("kssl_err text= %s\n", kssl_err.text);
 #endif /* KSSL_DEBUG */
-                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                                kssl_err.reason);
-                        goto err;
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+                               kssl_err.reason);
+                       goto err;
                        }
 
                if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0)
                        {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc);
-                        goto err;
+                       goto err;
                        }
 
 #ifdef KSSL_DEBUG
-                kssl_ctx_show(kssl_ctx);
+               kssl_ctx_show(kssl_ctx);
 #endif /* KSSL_DEBUG */
 
                enc = kssl_map_enc(kssl_ctx->enctype);
-                if (enc == NULL)
-                    goto err;
+               if (enc == NULL)
+                   goto err;
 
                memset(iv, 0, sizeof iv);       /* per RFC 1510 */
 
@@ -2060,34 +2063,53 @@ int ssl3_get_client_key_exchange(SSL *s)
                                SSL_R_DATA_LENGTH_TOO_LONG);
                        goto err;
                        }
+               if (!((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
+                   {
+                   /* The premaster secret must contain the same version number as the
+                    * ClientHello to detect version rollback attacks (strangely, the
+                    * protocol does not offer such protection for DH ciphersuites).
+                    * However, buggy clients exist that send random bytes instead of
+                    * the protocol version.
+                    * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. 
+                    * (Perhaps we should have a separate BUG value for the Kerberos cipher)
+                    */
+                   if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&
+                          (p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
+                       {
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+                              SSL_AD_DECODE_ERROR);
+                       goto err;
+                       }
+                   }
+
                EVP_CIPHER_CTX_cleanup(&ciph_ctx);
 
-                s->session->master_key_length=
-                        s->method->ssl3_enc->generate_master_secret(s,
-                                s->session->master_key, pms, outl);
+               s->session->master_key_length=
+                       s->method->ssl3_enc->generate_master_secret(s,
+                               s->session->master_key, pms, outl);
 
-                if (kssl_ctx->client_princ)
-                        {
-                        int len = strlen(kssl_ctx->client_princ);
-                        if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH ) 
-                                {
-                                s->session->krb5_client_princ_len = len;
-                                memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len);
-                                }
-                        }
+               if (kssl_ctx->client_princ)
+                       {
+                       size_t len = strlen(kssl_ctx->client_princ);
+                       if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH ) 
+                               {
+                               s->session->krb5_client_princ_len = len;
+                               memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len);
+                               }
+                       }
 
 
-                /*  Was doing kssl_ctx_free() here,
+               /*  Was doing kssl_ctx_free() here,
                **  but it caused problems for apache.
-                **  kssl_ctx = kssl_ctx_free(kssl_ctx);
-                **  if (s->kssl_ctx)  s->kssl_ctx = NULL;
-                */
-                }
+               **  kssl_ctx = kssl_ctx_free(kssl_ctx);
+               **  if (s->kssl_ctx)  s->kssl_ctx = NULL;
+               */
+               }
        else
 #endif /* OPENSSL_NO_KRB5 */
 
 #ifndef OPENSSL_NO_ECDH
-               if ((l & SSL_kECDH) || (l & SSL_kEECDH))
+               if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
                {
                int ret = 1;
                int field_size = 0;
@@ -2095,19 +2117,19 @@ int ssl3_get_client_key_exchange(SSL *s)
                const EC_GROUP *group;
                const BIGNUM *priv_key;
 
-                /* initialize structures for server's ECDH key pair */
+               /* initialize structures for server's ECDH key pair */
                if ((srvr_ecdh = EC_KEY_new()) == NULL) 
                        {
-                       SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                            ERR_R_MALLOC_FAILURE);
-                       goto err;
+                       goto err;
                        }
 
                /* Let's get server private key and group information */
-               if (l & SSL_kECDH) 
+               if (alg_k & (SSL_kECDHr|SSL_kECDHe))
                        { 
-                        /* use the certificate */
-                       tkey = s->cert->key->privatekey->pkey.ec;
+                       /* use the certificate */
+                       tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec;
                        }
                else
                        {
@@ -2136,20 +2158,20 @@ int ssl3_get_client_key_exchange(SSL *s)
                        goto err;
                        }
 
-                if (n == 0L) 
-                        {
+               if (n == 0L) 
+                       {
                        /* Client Publickey was in Client Certificate */
 
-                        if (l & SSL_kEECDH)
+                        if (alg_k & SSL_kEECDH)
                                 {
                                 al=SSL_AD_HANDSHAKE_FAILURE;
                                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY);
                                 goto f_err;
                                 }
-                        if (((clnt_pub_pkey=X509_get_pubkey(s->session->peer))
+                       if (((clnt_pub_pkey=X509_get_pubkey(s->session->peer))
                            == NULL) || 
                            (clnt_pub_pkey->type != EVP_PKEY_EC))
-                               {
+                               {
                                /* XXX: For now, we do not support client
                                 * authentication using ECDH certificates
                                 * so this branch (n == 0L) of the code is
@@ -2161,11 +2183,11 @@ int ssl3_get_client_key_exchange(SSL *s)
                                 * the two ECDH shares are for the same
                                 * group.
                                 */
-                               al=SSL_AD_HANDSHAKE_FAILURE;
-                               SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+                               al=SSL_AD_HANDSHAKE_FAILURE;
+                               SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                                    SSL_R_UNABLE_TO_DECODE_ECDH_CERTS);
-                               goto f_err;
-                               }
+                               goto f_err;
+                               }
 
                        if (EC_POINT_copy(clnt_ecpoint,
                            EC_KEY_get0_public_key(clnt_pub_pkey->pkey.ec)) == 0)
@@ -2174,10 +2196,10 @@ int ssl3_get_client_key_exchange(SSL *s)
                                        ERR_R_EC_LIB);
                                goto err;
                                }
-                        ret = 2; /* Skip certificate verify processing */
-                        }
-                else
-                        {
+                       ret = 2; /* Skip certificate verify processing */
+                       }
+               else
+                       {
                        /* Get client's public key from encoded point
                         * in the ClientKeyExchange message.
                         */
@@ -2188,21 +2210,21 @@ int ssl3_get_client_key_exchange(SSL *s)
                                goto err;
                                }
 
-                        /* Get encoded point length */
-                        i = *p; 
+                       /* Get encoded point length */
+                       i = *p; 
                        p += 1;
-                        if (EC_POINT_oct2point(group, 
+                       if (EC_POINT_oct2point(group, 
                            clnt_ecpoint, p, i, bn_ctx) == 0)
                                {
                                SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                                    ERR_R_EC_LIB);
                                goto err;
                                }
-                        /* p is pointing to somewhere in the buffer
-                         * currently, so set it to the start 
-                         */ 
-                        p=(unsigned char *)s->init_buf->data;
-                        }
+                       /* p is pointing to somewhere in the buffer
+                        * currently, so set it to the start 
+                        */ 
+                       p=(unsigned char *)s->init_buf->data;
+                       }
 
                /* Compute the shared pre-master secret */
                field_size = EC_GROUP_get_degree(group);
@@ -2213,12 +2235,12 @@ int ssl3_get_client_key_exchange(SSL *s)
                        goto err;
                        }
                i = ECDH_compute_key(p, (field_size+7)/8, clnt_ecpoint, srvr_ecdh, NULL);
-                if (i <= 0)
-                        {
-                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+               if (i <= 0)
+                       {
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                            ERR_R_ECDH_LIB);
-                        goto err;
-                        }
+                       goto err;
+                       }
 
                EVP_PKEY_free(clnt_pub_pkey);
                EC_POINT_free(clnt_ecpoint);
@@ -2227,16 +2249,16 @@ int ssl3_get_client_key_exchange(SSL *s)
                BN_CTX_free(bn_ctx);
 
                /* Compute the master secret */
-                s->session->master_key_length = s->method->ssl3_enc-> \
+               s->session->master_key_length = s->method->ssl3_enc-> \
                    generate_master_secret(s, s->session->master_key, p, i);
                
-                OPENSSL_cleanse(p, i);
-                return (ret);
+               OPENSSL_cleanse(p, i);
+               return (ret);
                }
        else
 #endif
 #ifndef OPENSSL_NO_PSK
-               if (l & SSL_kPSK)
+               if (alg_k & SSL_kPSK)
                        {
                        unsigned char *t = NULL;
                        unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
@@ -2325,8 +2347,8 @@ int ssl3_get_client_key_exchange(SSL *s)
                        psk_err = 0;
                psk_err:
                        OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
-                        if (psk_err != 0)
-                                goto f_err;
+                       if (psk_err != 0)
+                               goto f_err;
                        }
                else
 #endif
@@ -2672,14 +2694,15 @@ int ssl3_send_server_certificate(SSL *s)
        if (s->state == SSL3_ST_SW_CERT_A)
                {
                x=ssl_get_server_send_cert(s);
-               if (x == NULL &&
-                        /* VRS: allow null cert if auth == KRB5 */
-                        (s->s3->tmp.new_cipher->algorithms
-                                & (SSL_MKEY_MASK|SSL_AUTH_MASK))
-                        != (SSL_aKRB5|SSL_kKRB5))
-                       {
-                       SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
-                       return(0);
+               if (x == NULL)
+                       {
+                       /* VRS: allow null cert if auth == KRB5 */
+                       if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) ||
+                           (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5))
+                               {
+                               SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
+                               return(0);
+                               }
                        }
 
                l=ssl3_output_cert_chain(s,x);