improved error checking and some fixes
[openssl.git] / ssl / s3_both.c
index 8864366f59228a97789c79fd3e0f6a3f368d6e59..2ecfbb77cb1704bda84a57110a3256af1f568daa 100644 (file)
  * Hudson (tjh@cryptsoft.com).
  *
  */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
 
 #include <limits.h>
 #include <string.h>
@@ -192,7 +197,7 @@ int ssl3_get_finished(SSL *s, int a, int b)
         * change cipher spec message and is in s->s3->tmp.peer_finish_md
         */ 
 
-       n=ssl3_get_message(s,
+       n=s->method->ssl_get_message(s,
                a,
                b,
                SSL3_MT_FINISHED,
@@ -268,16 +273,23 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
        X509_STORE_CTX xs_ctx;
        X509_OBJECT obj;
 
+       int no_chain;
+
+       if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
+               no_chain = 1;
+       else
+               no_chain = 0;
+
        /* TLSv1 sends a chain with nothing in it, instead of an alert */
        buf=s->init_buf;
-       if (!BUF_MEM_grow(buf,(int)(10)))
+       if (!BUF_MEM_grow_clean(buf,10))
                {
                SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
                return(0);
                }
        if (x != NULL)
                {
-               if(!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL))
+               if(!no_chain && !X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL))
                        {
                        SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
                        return(0);
@@ -286,7 +298,7 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
                for (;;)
                        {
                        n=i2d_X509(x,NULL);
-                       if (!BUF_MEM_grow(buf,(int)(n+l+3)))
+                       if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
                                {
                                SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
                                return(0);
@@ -295,6 +307,10 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
                        l2n3(n,p);
                        i2d_X509(x,&p);
                        l+=n+3;
+
+                       if (no_chain)
+                               break;
+
                        if (X509_NAME_cmp(X509_get_subject_name(x),
                                X509_get_issuer_name(x)) == 0) break;
 
@@ -306,8 +322,8 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
                         * ref count */
                        X509_free(x);
                        }
-
-               X509_STORE_CTX_cleanup(&xs_ctx);
+               if (!no_chain)
+                       X509_STORE_CTX_cleanup(&xs_ctx);
                }
 
        /* Thawte special :-) */
@@ -316,7 +332,7 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
                {
                x=sk_X509_value(s->ctx->extra_certs,i);
                n=i2d_X509(x,NULL);
-               if (!BUF_MEM_grow(buf,(int)(n+l+3)))
+               if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
                        {
                        SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
                        return(0);
@@ -375,8 +391,8 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
                        {
                        while (s->init_num < 4)
                                {
-                               i=ssl3_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],
-                                       4 - s->init_num, 0);
+                               i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
+                                       &p[s->init_num],4 - s->init_num, 0);
                                if (i <= 0)
                                        {
                                        s->rwstate=SSL_READING;
@@ -439,7 +455,7 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
                        SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);
                        goto f_err;
                        }
-               if (l && !BUF_MEM_grow(s->init_buf,(int)l+4))
+               if (l && !BUF_MEM_grow_clean(s->init_buf,(int)l+4))
                        {
                        SSLerr(SSL_F_SSL3_GET_MESSAGE,ERR_R_BUF_LIB);
                        goto err;
@@ -456,7 +472,7 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
        n = s->s3->tmp.message_size - s->init_num;
        while (n > 0)
                {
-               i=ssl3_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],n,0);
+               i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],n,0);
                if (i <= 0)
                        {
                        s->rwstate=SSL_READING;
@@ -481,7 +497,7 @@ err:
 int ssl_cert_type(X509 *x, EVP_PKEY *pkey)
        {
        EVP_PKEY *pk;
-       int ret= -1,i,j;
+       int ret= -1,i;
 
        if (pkey == NULL)
                pk=X509_get_pubkey(x);
@@ -493,35 +509,17 @@ int ssl_cert_type(X509 *x, EVP_PKEY *pkey)
        if (i == EVP_PKEY_RSA)
                {
                ret=SSL_PKEY_RSA_ENC;
-               if (x != NULL)
-                       {
-                       j=X509_get_ext_count(x);
-                       /* check to see if this is a signing only certificate */
-                       /* EAY EAY EAY EAY */
-                       }
                }
        else if (i == EVP_PKEY_DSA)
                {
                ret=SSL_PKEY_DSA_SIGN;
                }
-       else if (i == EVP_PKEY_DH)
+#ifndef OPENSSL_NO_EC
+       else if (i == EVP_PKEY_EC)
                {
-               /* if we just have a key, we needs to be guess */
-
-               if (x == NULL)
-                       ret=SSL_PKEY_DH_DSA;
-               else
-                       {
-                       j=X509_get_signature_type(x);
-                       if (j == EVP_PKEY_RSA)
-                               ret=SSL_PKEY_DH_RSA;
-                       else if (j== EVP_PKEY_DSA)
-                               ret=SSL_PKEY_DH_DSA;
-                       else ret= -1;
-                       }
+               ret = SSL_PKEY_ECC;
                }
-       else
-               ret= -1;
+#endif
 
 err:
        if(!pkey) EVP_PKEY_free(pk);