Avoid warnings: add missing prototype, don't shadow.
[openssl.git] / ssl / ssltest.c
index 2ef9ae760159198be4b5b993039dc027a98a797e..82c3b8d89c6b7060e96fe749af7559df6e0b36e5 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.
+ */
 
-#define _XOPEN_SOURCE 600      /* Or gethostname won't be declared properly
+#define _BSD_SOURCE 1          /* Or gethostname won't be declared properly
                                   on Linux and GNU platforms. */
-#define _XOPEN_SOURCE_EXTENDED 1 /* Or gethostname won't be declared properly
-                                  on Compaq platforms (at least with DEC C).
-                               */
 
 #include <assert.h>
 #include <errno.h>
 #include <string.h>
 #include <time.h>
 
+#define USE_SOCKETS
 #include "e_os.h"
 
 #include <openssl/bio.h>
 #include <openssl/evp.h>
 #include <openssl/x509.h>
 #include <openssl/ssl.h>
+#ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
+#endif
 #include <openssl/err.h>
 #include <openssl/rand.h>
+
+#define _XOPEN_SOURCE_EXTENDED 1 /* Or gethostname won't be declared properly
+                                    on Compaq platforms (at least with DEC C).
+                                    Do not try to put it earlier, or IPv6 includes
+                                    get screwed...
+                                 */
+
 #ifdef OPENSSL_SYS_WINDOWS
 #include <winsock.h>
-#include "../crypto/bio/bss_file.c"
 #else
 #include OPENSSL_UNISTD
 #endif
 #ifdef OPENSSL_SYS_VMS
 #  define TEST_SERVER_CERT "SYS$DISK:[-.APPS]SERVER.PEM"
 #  define TEST_CLIENT_CERT "SYS$DISK:[-.APPS]CLIENT.PEM"
+#elif defined(OPENSSL_SYS_WINCE)
+#  define TEST_SERVER_CERT "\\OpenSSL\\server.pem"
+#  define TEST_CLIENT_CERT "\\OpenSSL\\client.pem"
 #else
 #  define TEST_SERVER_CERT "../apps/server.pem"
 #  define TEST_CLIENT_CERT "../apps/client.pem"
 
 /* There is really no standard for this, so let's assign some tentative
    numbers.  In any case, these numbers are only for this test */
-#define COMP_RLE       1
-#define COMP_ZLIB      2
+#define COMP_RLE       255
+#define COMP_ZLIB      1
 
 static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
 #ifndef OPENSSL_NO_RSA
@@ -201,6 +215,9 @@ static void sv_usage(void)
        fprintf(stderr," -dhe1024dsa   - use 1024 bit key (with 160-bit subprime) for DHE\n");
        fprintf(stderr," -no_dhe       - disable DHE\n");
 #endif
+#ifndef OPENSSL_NO_ECDH
+       fprintf(stderr," -no_ecdhe     - disable ECDHE\n");
+#endif
 #ifndef OPENSSL_NO_SSL2
        fprintf(stderr," -ssl2         - use SSLv2\n");
 #endif
@@ -221,7 +238,12 @@ static void sv_usage(void)
        fprintf(stderr," -f            - Test even cases that can't work\n");
        fprintf(stderr," -time         - measure processor time used by client and server\n");
        fprintf(stderr," -zlib         - use zlib compression\n");
-       fprintf(stderr," -time         - use rle compression\n");
+       fprintf(stderr," -rle          - use rle compression\n");
+#ifndef OPENSSL_NO_ECDH
+       fprintf(stderr," -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n" \
+                      "                 Use \"openssl ecparam -list_curves\" for all names\n"  \
+                      "                 (default is sect163r2).\n");
+#endif
        }
 
 static void print_details(SSL *c_ssl, const char *prefix)
@@ -281,7 +303,7 @@ static void lock_dbg_cb(int mode, int type, const char *file, int line)
                goto err;
                }
 
-       if (type < 0 || type > CRYPTO_NUM_LOCKS)
+       if (type < 0 || type >= CRYPTO_NUM_LOCKS)
                {
                errstr = "type out of bounds";
                goto err;
@@ -345,26 +367,34 @@ int main(int argc, char *argv[])
        char *server_key=NULL;
        char *client_cert=TEST_CLIENT_CERT;
        char *client_key=NULL;
+       char *named_curve = NULL;
        SSL_CTX *s_ctx=NULL;
        SSL_CTX *c_ctx=NULL;
        SSL_METHOD *meth=NULL;
        SSL *c_ssl,*s_ssl;
        int number=1,reuse=0;
-       long bytes=1L;
+       long bytes=256L;
 #ifndef OPENSSL_NO_DH
        DH *dh;
        int dhe1024 = 0, dhe1024dsa = 0;
+#endif
+#ifndef OPENSSL_NO_ECDH
+       EC_KEY *ecdh = NULL;
 #endif
        int no_dhe = 0;
+       int no_ecdhe = 0;
        int print_time = 0;
        clock_t s_time = 0, c_time = 0;
        int comp = 0;
        COMP_METHOD *cm = NULL;
+       STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
 
        verbose = 0;
        debug = 0;
        cipher = 0;
-       
+
+       bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); 
+
        CRYPTO_set_locking_callback(lock_dbg_cb);
 
        /* enable memory leak checking unless explicitly disabled */
@@ -382,7 +412,6 @@ int main(int argc, char *argv[])
 
        RAND_seed(rnd_seed, sizeof rnd_seed);
 
-       bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
        bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE);
 
        argc--;
@@ -400,14 +429,26 @@ int main(int argc, char *argv[])
                        debug=1;
                else if (strcmp(*argv,"-reuse") == 0)
                        reuse=1;
-#ifndef OPENSSL_NO_DH
                else if (strcmp(*argv,"-dhe1024") == 0)
+                       {
+#ifndef OPENSSL_NO_DH
                        dhe1024=1;
+#else
+                       fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
+#endif
+                       }
                else if (strcmp(*argv,"-dhe1024dsa") == 0)
+                       {
+#ifndef OPENSSL_NO_DH
                        dhe1024dsa=1;
+#else
+                       fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
 #endif
+                       }
                else if (strcmp(*argv,"-no_dhe") == 0)
                        no_dhe=1;
+               else if (strcmp(*argv,"-no_ecdhe") == 0)
+                       no_ecdhe=1;
                else if (strcmp(*argv,"-ssl2") == 0)
                        ssl2=1;
                else if (strcmp(*argv,"-tls1") == 0)
@@ -494,6 +535,16 @@ int main(int argc, char *argv[])
                        {
                        comp = COMP_RLE;
                        }
+               else if (strcmp(*argv,"-named_curve") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+#ifndef OPENSSL_NO_ECDH                
+                       named_curve = *(++argv);
+#else
+                       fprintf(stderr,"ignoring -named_curve, since I'm compiled without ECDH\n");
+                       ++argv;
+#endif
+                       }
                else if (strcmp(*argv,"-app_verify") == 0)
                        {
                        app_verify = 1;
@@ -520,7 +571,7 @@ bad:
                        "the test anyway (and\n-d to see what happens), "
                        "or add one of -ssl2, -ssl3, -tls1, -reuse\n"
                        "to avoid protocol mismatch.\n");
-               exit(1);
+               EXIT(1);
                }
 
        if (print_time)
@@ -544,7 +595,14 @@ bad:
        if (cm != NULL)
                {
                if (cm->type != NID_undef)
-                       SSL_COMP_add_compression_method(comp, cm);
+                       {
+                       if (SSL_COMP_add_compression_method(comp, cm) != 0)
+                               {
+                               fprintf(stderr,
+                                       "Failed to add compression method\n");
+                               ERR_print_errors_fp(stderr);
+                               }
+                       }
                else
                        {
                        fprintf(stderr,
@@ -555,6 +613,19 @@ bad:
                        ERR_print_errors_fp(stderr);
                        }
                }
+       ssl_comp_methods = SSL_COMP_get_compression_methods();
+       fprintf(stderr, "Available compression methods:\n");
+       {
+       int j, n = sk_SSL_COMP_num(ssl_comp_methods);
+       if (n == 0)
+               fprintf(stderr, "  NONE\n");
+       else
+               for (j = 0; j < n; j++)
+                       {
+                       SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
+                       fprintf(stderr, "  %d: %s\n", c->id, c->name);
+                       }
+       }
 
 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
        if (ssl2)
@@ -609,6 +680,44 @@ bad:
        (void)no_dhe;
 #endif
 
+#ifndef OPENSSL_NO_ECDH
+       if (!no_ecdhe)
+               {
+               ecdh = EC_KEY_new();
+               if (ecdh != NULL)
+                       {
+                       if (named_curve)
+                               {
+                               int nid = OBJ_sn2nid(named_curve);
+
+                               if (nid == 0)
+                                       {
+                                       BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve);
+                                       EC_KEY_free(ecdh);
+                                       goto end;
+                                       }
+
+                               ecdh->group = EC_GROUP_new_by_nid(nid);
+                               if (ecdh->group == NULL)
+                                       {
+                                       BIO_printf(bio_err, "unable to create curve (%s)\n", named_curve);
+                                       EC_KEY_free(ecdh);
+                                       goto end;
+                                       }
+                               }
+                       
+                       if (ecdh->group == NULL)
+                               ecdh->group=EC_GROUP_new_by_nid(NID_sect163r2);
+
+                       SSL_CTX_set_tmp_ecdh(s_ctx, ecdh);
+                       SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE);
+                       EC_KEY_free(ecdh);
+                       }
+               }
+#else
+       (void)no_ecdhe;
+#endif
+
 #ifndef OPENSSL_NO_RSA
        SSL_CTX_set_tmp_rsa_callback(s_ctx,tmp_rsa_cb);
 #endif
@@ -676,10 +785,16 @@ bad:
 #ifndef OPENSSL_NO_KRB5
        if (c_ssl  &&  c_ssl->kssl_ctx)
                 {
-                char   localhost[257];
+                char   localhost[MAXHOSTNAMELEN+2];
 
-               if (gethostname(localhost, 256) == 0)
+               if (gethostname(localhost, sizeof localhost-1) == 0)
                         {
+                       localhost[sizeof localhost-1]='\0';
+                       if(strlen(localhost) == sizeof localhost-1)
+                               {
+                               BIO_printf(bio_err,"localhost name too long\n");
+                               goto end;
+                               }
                        kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER,
                                 localhost);
                        }
@@ -735,7 +850,9 @@ end:
 #ifndef OPENSSL_NO_RSA
        free_tmp_rsa();
 #endif
+#ifndef OPENSSL_NO_ENGINE
        ENGINE_cleanup();
+#endif
        CRYPTO_cleanup_all_ex_data();
        ERR_free_strings();
        ERR_remove_state(0);
@@ -825,6 +942,8 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
                        int i, r;
                        clock_t c_clock = clock();
 
+                       memset(cbuf, 0, sizeof(cbuf));
+
                        if (debug)
                                if (SSL_in_init(c_ssl))
                                        printf("client waiting in SSL_connect - %s\n",
@@ -909,6 +1028,8 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
                        int i, r;
                        clock_t s_clock = clock();
 
+                       memset(sbuf, 0, sizeof(sbuf));
+
                        if (debug)
                                if (SSL_in_init(s_ssl))
                                        printf("server waiting in SSL_accept - %s\n",
@@ -1053,10 +1174,10 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
                                        if (num > 1)
                                                --num; /* test restartability even more thoroughly */
                                        
-                                       r = BIO_nwrite(io1, &dataptr, (int)num);
+                                       r = BIO_nwrite0(io1, &dataptr);
                                        assert(r > 0);
-                                       assert(r <= (int)num);
-                                       num = r;
+                                       if (r < (int)num)
+                                               num = r;
                                        r = BIO_read(io2, dataptr, (int)num);
                                        if (r != (int)num) /* can't happen */
                                                {
@@ -1065,6 +1186,13 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
                                                goto err;
                                                }
                                        progress = 1;
+                                       r = BIO_nwrite(io1, &dataptr, (int)num);
+                                       if (r != (int)num) /* can't happen */
+                                               {
+                                               fprintf(stderr, "ERROR: BIO_nwrite() did not accept "
+                                                       "BIO_nwrite0() bytes");
+                                               goto err;
+                                               }
                                        
                                        if (debug)
                                                printf((io2 == client_io) ?
@@ -1145,6 +1273,9 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
        int c_write,s_write;
        int do_server=0,do_client=0;
 
+       memset(cbuf,0,sizeof(cbuf));
+       memset(sbuf,0,sizeof(sbuf));
+
        c_to_s=BIO_new(BIO_s_mem());
        s_to_c=BIO_new(BIO_s_mem());
        if ((s_to_c == NULL) || (c_to_s == NULL))
@@ -1426,7 +1557,8 @@ static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
        {
        char *s,buf[256];
 
-       s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),buf,256);
+       s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),buf,
+                           sizeof buf);
        if (s != NULL)
                {
                if (ok)
@@ -1476,9 +1608,21 @@ static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
        {
        if (rsa_tmp == NULL)
                {
+               rsa_tmp = RSA_new();
+               if(!rsa_tmp)
+                       {
+                       BIO_printf(bio_err, "Memory error...");
+                       goto end;
+                       }
                BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
                (void)BIO_flush(bio_err);
-               rsa_tmp=RSA_generate_key(keylength,RSA_F4,NULL,NULL);
+               if(!RSA_generate_key_ex(rsa_tmp,keylength,RSA_F4,NULL))
+                       {
+                       BIO_printf(bio_err, "Error generating key.");
+                       RSA_free(rsa_tmp);
+                       rsa_tmp = NULL;
+                       }
+end:
                BIO_printf(bio_err,"\n");
                (void)BIO_flush(bio_err);
                }