fix warnings (CHARSET_EBCDIC)
[openssl.git] / apps / s_server.c
index cd1e8b4ee00ed9792be46bc28f375dc5e8413b35..3295eb02072ce05ab22bdb71a93074a1cc9ce4b5 100644 (file)
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * 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 <assert.h>
 #include <stdio.h>
@@ -111,6 +169,7 @@ static int generate_session_id(const SSL *ssl, unsigned char *id,
 static DH *load_dh_param(char *dhfile);
 static DH *get_dh512(void);
 #endif
+
 #ifdef MONOLITH
 static void s_server_init(void);
 #endif
@@ -149,6 +208,7 @@ static DH *get_dh512(void)
        }
 #endif
 
+
 /* static int load_CA(SSL_CTX *ctx, char *file);*/
 
 #undef BUFSIZZ
@@ -177,6 +237,7 @@ static int www=0;
 
 static BIO *bio_s_out=NULL;
 static int s_debug=0;
+static int s_msg=0;
 static int s_quiet=0;
 
 static int hack=0;
@@ -202,6 +263,7 @@ static void s_server_init(void)
 
        bio_s_out=NULL;
        s_debug=0;
+       s_msg=0;
        s_quiet=0;
        hack=0;
        engine_id=NULL;
@@ -224,12 +286,18 @@ static void sv_usage(void)
        BIO_printf(bio_err," -dkey arg     - second private key file to use (usually for DSA)\n");
        BIO_printf(bio_err," -dhparam arg  - DH parameter file to use, in cert file if not specified\n");
        BIO_printf(bio_err,"                 or a default set of parameters is used\n");
+#ifndef OPENSSL_NO_ECDH
+       BIO_printf(bio_err," -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
 #ifdef FIONBIO
        BIO_printf(bio_err," -nbio         - Run with non-blocking IO\n");
 #endif
        BIO_printf(bio_err," -nbio_test    - test with the non-blocking test bio\n");
        BIO_printf(bio_err," -crlf         - convert LF from terminal into CRLF\n");
        BIO_printf(bio_err," -debug        - Print more output\n");
+       BIO_printf(bio_err," -msg          - Show protocol messages\n");
        BIO_printf(bio_err," -state        - Print the SSL states\n");
        BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
        BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
@@ -246,6 +314,9 @@ static void sv_usage(void)
        BIO_printf(bio_err," -no_tls1      - Just disable TLSv1\n");
 #ifndef OPENSSL_NO_DH
        BIO_printf(bio_err," -no_dhe       - Disable ephemeral DH\n");
+#endif
+#ifndef OPENSSL_NO_ECDH
+       BIO_printf(bio_err," -no_ecdhe     - Disable ephemeral ECDH\n");
 #endif
        BIO_printf(bio_err," -bugs         - Turn on SSL bug compatibility\n");
        BIO_printf(bio_err," -www          - Respond to a 'GET /' with a status page\n");
@@ -264,10 +335,10 @@ static char **local_argv;
 static int ebcdic_new(BIO *bi);
 static int ebcdic_free(BIO *a);
 static int ebcdic_read(BIO *b, char *out, int outl);
-static int ebcdic_write(BIO *b, char *in, int inl);
-static long ebcdic_ctrl(BIO *b, int cmd, long num, char *ptr);
+static int ebcdic_write(BIO *b, const char *in, int inl);
+static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr);
 static int ebcdic_gets(BIO *bp, char *buf, int size);
-static int ebcdic_puts(BIO *bp, char *str);
+static int ebcdic_puts(BIO *bp, const char *str);
 
 #define BIO_TYPE_EBCDIC_FILTER (18|0x0200)
 static BIO_METHOD methods_ebcdic=
@@ -332,7 +403,7 @@ static int ebcdic_read(BIO *b, char *out, int outl)
        return(ret);
 }
 
-static int ebcdic_write(BIO *b, char *in, int inl)
+static int ebcdic_write(BIO *b, const char *in, int inl)
 {
        EBCDIC_OUTBUFF *wbuf;
        int ret=0;
@@ -365,7 +436,7 @@ static int ebcdic_write(BIO *b, char *in, int inl)
        return(ret);
 }
 
-static long ebcdic_ctrl(BIO *b, int cmd, long num, char *ptr)
+static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
 {
        long ret;
 
@@ -384,7 +455,7 @@ static long ebcdic_ctrl(BIO *b, int cmd, long num, char *ptr)
 
 static int ebcdic_gets(BIO *bp, char *buf, int size)
 {
-       int i, ret;
+       int i, ret=0;
        if (bp->next_bio == NULL) return(0);
 /*     return(BIO_gets(bp->next_bio,buf,size));*/
        for (i=0; i<size-1; ++i)
@@ -403,7 +474,7 @@ static int ebcdic_gets(BIO *bp, char *buf, int size)
        return (ret < 0 && i == 0) ? ret : i;
 }
 
-static int ebcdic_puts(BIO *bp, char *str)
+static int ebcdic_puts(BIO *bp, const char *str)
 {
        if (bp->next_bio == NULL) return(0);
        return ebcdic_write(bp, str, strlen(str));
@@ -420,10 +491,11 @@ int MAIN(int argc, char *argv[])
        char *CApath=NULL,*CAfile=NULL;
        char *context = NULL;
        char *dhfile = NULL;
+       char *named_curve = NULL;
        int badop=0,bugs=0;
        int ret=1;
        int off=0;
-       int no_tmp_rsa=0,no_dhe=0,nocert=0;
+       int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
        int state=0;
        SSL_METHOD *meth=NULL;
        ENGINE *e=NULL;
@@ -448,6 +520,9 @@ int MAIN(int argc, char *argv[])
        if (bio_err == NULL)
                bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
 
+       if (!load_config(bio_err, NULL))
+               goto end;
+
        verify_depth=0;
 #ifdef FIONBIO
        s_nbio=0;
@@ -501,6 +576,13 @@ int MAIN(int argc, char *argv[])
                        if (--argc < 1) goto bad;
                        dhfile = *(++argv);
                        }
+#ifndef OPENSSL_NO_ECDH                
+               else if (strcmp(*argv,"-named_curve") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       named_curve = *(++argv);
+                       }
+#endif
                else if (strcmp(*argv,"-dcert") == 0)
                        {
                        if (--argc < 1) goto bad;
@@ -553,6 +635,8 @@ int MAIN(int argc, char *argv[])
                        }
                else if (strcmp(*argv,"-debug") == 0)
                        { s_debug=1; }
+               else if (strcmp(*argv,"-msg") == 0)
+                       { s_msg=1; }
                else if (strcmp(*argv,"-hack") == 0)
                        { hack=1; }
                else if (strcmp(*argv,"-state") == 0)
@@ -567,6 +651,8 @@ int MAIN(int argc, char *argv[])
                        { no_tmp_rsa=1; }
                else if (strcmp(*argv,"-no_dhe") == 0)
                        { no_dhe=1; }
+               else if (strcmp(*argv,"-no_ecdhe") == 0)
+                       { no_ecdhe=1; }
                else if (strcmp(*argv,"-www") == 0)
                        { www=1; }
                else if (strcmp(*argv,"-WWW") == 0)
@@ -622,6 +708,11 @@ bad:
                goto end;
                }
 
+       SSL_load_error_strings();
+       OpenSSL_add_ssl_algorithms();
+
+        e = setup_engine(bio_err, engine_id, 1);
+
        if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
                && !RAND_status())
                {
@@ -633,7 +724,7 @@ bad:
 
        if (bio_s_out == NULL)
                {
-               if (s_quiet && !s_debug)
+               if (s_quiet && !s_debug && !s_msg)
                        {
                        bio_s_out=BIO_new(BIO_s_null());
                        }
@@ -644,7 +735,7 @@ bad:
                        }
                }
 
-#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA)
+#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
        if (nocert)
 #endif
                {
@@ -654,11 +745,6 @@ bad:
                s_dkey_file=NULL;
                }
 
-       SSL_load_error_strings();
-       OpenSSL_add_ssl_algorithms();
-
-        e = setup_engine(bio_err, engine_id, 1);
-
        ctx=SSL_CTX_new(meth);
        if (ctx == NULL)
                {
@@ -737,6 +823,59 @@ bad:
                DH_free(dh);
                }
 #endif
+
+#ifndef OPENSSL_NO_ECDH
+       if (!no_ecdhe)
+               {
+               EC_KEY *ecdh=NULL;
+
+               ecdh = EC_KEY_new();
+               if (ecdh == NULL)
+                       {
+                       BIO_printf(bio_err,"Could not create ECDH struct.\n");
+                       goto end;
+                       }
+
+               if (named_curve)
+                       {
+                       int nid = OBJ_sn2nid(named_curve);
+
+                       if (nid == 0)
+                               {
+                               BIO_printf(bio_err, "unknown curve name (%s)\n", 
+                                       named_curve);
+                               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);
+                               goto end;
+                               }
+                       }
+
+               if (ecdh->group != NULL)
+                       {
+                       BIO_printf(bio_s_out,"Setting temp ECDH parameters\n");
+                       }
+               else
+                       {
+                       BIO_printf(bio_s_out,"Using default temp ECDH parameters\n");
+                       ecdh->group=EC_GROUP_new_by_nid(NID_sect163r2);
+                       if (ecdh->group == NULL) 
+                               {
+                               BIO_printf(bio_err, "unable to create curve (sect163r2)\n");
+                               goto end;
+                               }
+                       }
+               (void)BIO_flush(bio_s_out);
+
+               SSL_CTX_set_tmp_ecdh(ctx,ecdh);
+               EC_KEY_free(ecdh);
+               }
+#endif
        
        if (!set_cert_stuff(ctx,s_cert_file,s_key_file))
                goto end;
@@ -892,6 +1031,11 @@ static int sv_body(char *hostname, int s, unsigned char *context)
                BIO_set_callback(SSL_get_rbio(con),bio_dump_cb);
                BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
                }
+       if (s_msg)
+               {
+               SSL_set_msg_callback(con, msg_cb);
+               SSL_set_msg_callback_arg(con, bio_s_out);
+               }
 
        width=s+1;
        for (;;)
@@ -1284,6 +1428,11 @@ static int www_body(char *hostname, int s, unsigned char *context)
                BIO_set_callback(SSL_get_rbio(con),bio_dump_cb);
                BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
                }
+       if (s_msg)
+               {
+               SSL_set_msg_callback(con, msg_cb);
+               SSL_set_msg_callback_arg(con, bio_s_out);
+               }
 
        blank=0;
        for (;;)