free NULL cleanup
[openssl.git] / apps / s_server.c
index 573bc873bf8ab99c208a2965827eef9abd90c727..f97a97d8f0f9dee861df8a8c4739db9fca697d01 100644 (file)
@@ -266,7 +266,6 @@ static int s_brief = 0;
 static char *keymatexportlabel = NULL;
 static int keymatexportlen = 20;
 
-static int hack = 0;
 #ifndef OPENSSL_NO_ENGINE
 static char *engine_id = NULL;
 #endif
@@ -304,7 +303,7 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity,
     }
     if (s_debug)
         BIO_printf(bio_s_out, "identity_len=%d identity=%s\n",
-                   identity ? (int)strlen(identity) : 0, identity);
+                   (int)strlen(identity), identity);
 
     /* here we could lookup the given identity e.g. from a database */
     if (strcmp(identity, psk_identity) != 0) {
@@ -423,7 +422,6 @@ static void s_server_init(void)
     s_msg = 0;
     s_quiet = 0;
     s_brief = 0;
-    hack = 0;
 # ifndef OPENSSL_NO_ENGINE
     engine_id = NULL;
 # endif
@@ -488,7 +486,7 @@ static void sv_usage(void)
                " -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
+#ifndef OPENSSL_NO_EC
     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"
@@ -508,6 +506,8 @@ static void sv_usage(void)
     BIO_printf(bio_err, " -CAfile arg   - PEM format file of CA's\n");
     BIO_printf(bio_err,
                " -trusted_first - Use locally trusted CA's first when building trust chain\n");
+    BIO_printf(bio_err,
+               " -no_alt_chains - only ever use the first certificate chain found\n");
     BIO_printf(bio_err,
                " -nocert       - Don't use any certificates (Anon-DH)\n");
     BIO_printf(bio_err,
@@ -545,14 +545,12 @@ static void sv_usage(void)
 #ifndef OPENSSL_NO_DH
     BIO_printf(bio_err, " -no_dhe       - Disable ephemeral DH\n");
 #endif
-#ifndef OPENSSL_NO_ECDH
+#ifndef OPENSSL_NO_EC
     BIO_printf(bio_err, " -no_ecdhe     - Disable ephemeral ECDH\n");
 #endif
     BIO_printf(bio_err,
                "-no_resume_ephemeral - Disable caching and tickets if ephemeral (EC)DH is used\n");
     BIO_printf(bio_err, " -bugs         - Turn on SSL bug compatibility\n");
-    BIO_printf(bio_err,
-               " -hack         - workaround for early Netscape code\n");
     BIO_printf(bio_err,
                " -www          - Respond to a 'GET /' with a status page\n");
     BIO_printf(bio_err,
@@ -651,6 +649,8 @@ static int ebcdic_new(BIO *bi)
     EBCDIC_OUTBUFF *wbuf;
 
     wbuf = (EBCDIC_OUTBUFF *) OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
+    if (!wbuf)
+        return 0;
     wbuf->alloced = 1024;
     wbuf->buff[0] = '\0';
 
@@ -705,9 +705,11 @@ static int ebcdic_write(BIO *b, const char *in, int inl)
         num = num + num;        /* double the size */
         if (num < inl)
             num = inl;
-        OPENSSL_free(wbuf);
         wbuf =
             (EBCDIC_OUTBUFF *) OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
+        if(!wbuf)
+            return 0;
+        OPENSSL_free(b->ptr);
 
         wbuf->alloced = num;
         wbuf->buff[0] = '\0';
@@ -1331,8 +1333,6 @@ int MAIN(int argc, char *argv[])
             sdebug = 1;
         } else if (strcmp(*argv, "-security_debug_verbose") == 0) {
             sdebug = 2;
-        } else if (strcmp(*argv, "-hack") == 0) {
-            hack = 1;
         } else if (strcmp(*argv, "-state") == 0) {
             state = 1;
         } else if (strcmp(*argv, "-crlf") == 0) {
@@ -1677,7 +1677,7 @@ int MAIN(int argc, char *argv[])
                 bio_s_out = BIO_new_fp(stdout, BIO_NOCLOSE);
         }
     }
-#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
+#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
     if (nocert)
 #endif
     {
@@ -1710,8 +1710,6 @@ int MAIN(int argc, char *argv[])
         BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
     }
     SSL_CTX_set_quiet_shutdown(ctx, 1);
-    if (hack)
-        SSL_CTX_set_options(ctx, SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
     if (exc)
         ssl_ctx_set_excert(ctx, exc);
 
@@ -1725,8 +1723,14 @@ int MAIN(int argc, char *argv[])
         SSL_CTX_sess_set_cache_size(ctx, 128);
 
 #ifndef OPENSSL_NO_SRTP
-    if (srtp_profiles != NULL)
-        SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
+    if (srtp_profiles != NULL) {
+        /* Returns 0 on success!! */
+        if(SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles)) {
+            BIO_printf(bio_err, "Error setting SRTP profile\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
 #endif
 
     if ((!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) ||
@@ -1735,8 +1739,11 @@ int MAIN(int argc, char *argv[])
         ERR_print_errors(bio_err);
         /* goto end; */
     }
-    if (vpm)
-        SSL_CTX_set1_param(ctx, vpm);
+    if (vpm && !SSL_CTX_set1_param(ctx, vpm)) {
+        BIO_printf(bio_err, "Error setting X509 params\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
 
     ssl_ctx_add_crls(ctx, crls, 0);
     if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, no_ecdhe, no_jpake))
@@ -1775,8 +1782,6 @@ int MAIN(int argc, char *argv[])
             BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
         }
         SSL_CTX_set_quiet_shutdown(ctx2, 1);
-        if (hack)
-            SSL_CTX_set_options(ctx2, SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
         if (exc)
             ssl_ctx_set_excert(ctx2, exc);
 
@@ -1794,8 +1799,11 @@ int MAIN(int argc, char *argv[])
             (!SSL_CTX_set_default_verify_paths(ctx2))) {
             ERR_print_errors(bio_err);
         }
-        if (vpm)
-            SSL_CTX_set1_param(ctx2, vpm);
+        if (vpm && !SSL_CTX_set1_param(ctx2, vpm))  {
+            BIO_printf(bio_err, "Error setting X509 params\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
 
         ssl_ctx_add_crls(ctx2, crls, 0);
         if (!args_ssl_call(ctx2, bio_err, cctx, ssl_args, no_ecdhe, no_jpake))
@@ -1917,8 +1925,13 @@ int MAIN(int argc, char *argv[])
 #endif
 
     SSL_CTX_set_verify(ctx, s_server_verify, verify_callback);
-    SSL_CTX_set_session_id_context(ctx, (void *)&s_server_session_id_context,
-                                   sizeof s_server_session_id_context);
+    if(!SSL_CTX_set_session_id_context(ctx,
+        (void *)&s_server_session_id_context,
+        sizeof s_server_session_id_context)) {
+        BIO_printf(bio_err, "error setting session id context\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
 
     /* Set DTLS cookie generation and verification callbacks */
     SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
@@ -1927,9 +1940,13 @@ int MAIN(int argc, char *argv[])
 #ifndef OPENSSL_NO_TLSEXT
     if (ctx2) {
         SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback);
-        SSL_CTX_set_session_id_context(ctx2,
+        if(!SSL_CTX_set_session_id_context(ctx2,
                                        (void *)&s_server_session_id_context,
-                                       sizeof s_server_session_id_context);
+                                       sizeof s_server_session_id_context)) {
+            BIO_printf(bio_err, "error setting session id context\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
 
         tlsextcbp.biodebug = bio_s_out;
         SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
@@ -1994,10 +2011,8 @@ int MAIN(int argc, char *argv[])
         sk_X509_CRL_pop_free(crls, X509_CRL_free);
     if (s_dcert)
         X509_free(s_dcert);
-    if (s_key)
-        EVP_PKEY_free(s_key);
-    if (s_dkey)
-        EVP_PKEY_free(s_dkey);
+    EVP_PKEY_free(s_key);
+    EVP_PKEY_free(s_dkey);
     if (s_chain)
         sk_X509_pop_free(s_chain, X509_free);
     if (s_dchain)
@@ -2020,10 +2035,8 @@ int MAIN(int argc, char *argv[])
         SSL_CTX_free(ctx2);
     if (s_cert2)
         X509_free(s_cert2);
-    if (s_key2)
-        EVP_PKEY_free(s_key2);
-    if (serverinfo_in != NULL)
-        BIO_free(serverinfo_in);
+    EVP_PKEY_free(s_key2);
+    BIO_free(serverinfo_in);
 # ifndef OPENSSL_NO_NEXTPROTONEG
     if (next_proto.data)
         OPENSSL_free(next_proto.data);
@@ -2040,14 +2053,10 @@ int MAIN(int argc, char *argv[])
     if (jpake_secret && psk_key)
         OPENSSL_free(psk_key);
 #endif
-    if (bio_s_out != NULL) {
-        BIO_free(bio_s_out);
-        bio_s_out = NULL;
-    }
-    if (bio_s_msg != NULL) {
-        BIO_free(bio_s_msg);
-        bio_s_msg = NULL;
-    }
+    BIO_free(bio_s_out);
+    bio_s_out = NULL;
+    BIO_free(bio_s_msg);
+    bio_s_msg = NULL;
     apps_shutdown();
     OPENSSL_EXIT(ret);
 }
@@ -2134,10 +2143,18 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context)
             kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
         }
 #endif                          /* OPENSSL_NO_KRB5 */
-        if (context)
-            SSL_set_session_id_context(con, context, strlen((char *)context));
+        if (context && !SSL_set_session_id_context(con, context,
+                                                   strlen((char *)context))) {
+            BIO_printf(bio_err, "Error setting session id context\n");
+            ret = -1;
+            goto err;
+        }
+    }
+    if(!SSL_clear(con)) {
+        BIO_printf(bio_err, "Error clearing SSL connection\n");
+        ret = -1;
+        goto err;
     }
-    SSL_clear(con);
 
     if (stype == SOCK_DGRAM) {
 
@@ -2636,8 +2653,7 @@ static DH *load_dh_param(const char *dhfile)
         goto err;
     ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
  err:
-    if (bio != NULL)
-        BIO_free(bio);
+    BIO_free(bio);
     return (ret);
 }
 #endif
@@ -2691,8 +2707,10 @@ static int www_body(char *hostname, int s, int stype, unsigned char *context)
         kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
     }
 #endif                          /* OPENSSL_NO_KRB5 */
-    if (context)
-        SSL_set_session_id_context(con, context, strlen((char *)context));
+    if (context && !SSL_set_session_id_context(con, context,
+                                               strlen((char *)context))) {
+        goto err;
+    }
 
     sbio = BIO_new_socket(s, BIO_NOCLOSE);
     if (s_nbio_test) {
@@ -2727,43 +2745,6 @@ static int www_body(char *hostname, int s, int stype, unsigned char *context)
     }
 
     for (;;) {
-        if (hack) {
-            i = SSL_accept(con);
-#ifndef OPENSSL_NO_SRP
-            while (i <= 0
-                   && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
-                BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
-                           srp_callback_parm.login);
-                srp_callback_parm.user =
-                    SRP_VBASE_get_by_user(srp_callback_parm.vb,
-                                          srp_callback_parm.login);
-                if (srp_callback_parm.user)
-                    BIO_printf(bio_s_out, "LOOKUP done %s\n",
-                               srp_callback_parm.user->info);
-                else
-                    BIO_printf(bio_s_out, "LOOKUP not successful\n");
-                i = SSL_accept(con);
-            }
-#endif
-            switch (SSL_get_error(con, i)) {
-            case SSL_ERROR_NONE:
-                break;
-            case SSL_ERROR_WANT_WRITE:
-            case SSL_ERROR_WANT_READ:
-            case SSL_ERROR_WANT_X509_LOOKUP:
-                continue;
-            case SSL_ERROR_SYSCALL:
-            case SSL_ERROR_SSL:
-            case SSL_ERROR_ZERO_RETURN:
-                ret = 1;
-                goto err;
-                /* break; */
-            }
-
-            SSL_renegotiate(con);
-            SSL_write(con, NULL, 0);
-        }
-
         i = BIO_gets(io, buf, bufsize - 1);
         if (i < 0) {            /* error */
             if (!BIO_should_retry(io)) {
@@ -2786,7 +2767,7 @@ static int www_body(char *hostname, int s, int stype, unsigned char *context)
 
         /* else we have data */
         if (((www == 1) && (strncmp("GET ", buf, 4) == 0)) ||
-            ((www == 2) && (strncmp("GET /stats ", buf, 10) == 0))) {
+            ((www == 2) && (strncmp("GET /stats ", buf, 11) == 0))) {
             char *p;
             X509 *peer;
             STACK_OF(SSL_CIPHER) *sk;
@@ -3031,9 +3012,7 @@ static int www_body(char *hostname, int s, int stype, unsigned char *context)
 
     if (buf != NULL)
         OPENSSL_free(buf);
-    if (io != NULL)
-        BIO_free_all(io);
-/*      if (ssl_bio != NULL) BIO_free(ssl_bio);*/
+    BIO_free_all(io);
     return (ret);
 }
 
@@ -3074,8 +3053,11 @@ static int rev_body(char *hostname, int s, int stype, unsigned char *context)
         kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
     }
 #endif                          /* OPENSSL_NO_KRB5 */
-    if (context)
-        SSL_set_session_id_context(con, context, strlen((char *)context));
+    if (context && !SSL_set_session_id_context(con, context,
+                                               strlen((char *)context))) {
+        ERR_print_errors(bio_err);
+        goto err;
+    }
 
     sbio = BIO_new_socket(s, BIO_NOCLOSE);
     SSL_set_bio(con, sbio, sbio);
@@ -3166,8 +3148,7 @@ static int rev_body(char *hostname, int s, int stype, unsigned char *context)
 
     if (buf != NULL)
         OPENSSL_free(buf);
-    if (io != NULL)
-        BIO_free_all(io);
+    BIO_free_all(io);
     return (ret);
 }
 
@@ -3187,8 +3168,7 @@ static RSA *tmp_rsa_cb(SSL *s, int is_export, int keylength)
         }
         if (!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) ||
             !RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) {
-            if (rsa_tmp)
-                RSA_free(rsa_tmp);
+            RSA_free(rsa_tmp);
             rsa_tmp = NULL;
         }
         if (!s_quiet) {
@@ -3207,7 +3187,8 @@ static int generate_session_id(const SSL *ssl, unsigned char *id,
 {
     unsigned int count = 0;
     do {
-        RAND_pseudo_bytes(id, *id_len);
+        if (RAND_bytes(id, *id_len) <= 0)
+            return 0;
         /*
          * Prefix the session_id with the required prefix. NB: If our prefix
          * is too long, clip it - but there will be worse effects anyway, eg.
@@ -3249,6 +3230,10 @@ static int add_session(SSL *ssl, SSL_SESSION *session)
     unsigned char *p;
 
     sess = OPENSSL_malloc(sizeof(simple_ssl_session));
+    if(!sess) {
+        BIO_printf(bio_err, "Out of memory adding session to external cache\n");
+        return 0;
+    }
 
     SSL_SESSION_get_id(session, &sess->idlen);
     sess->derlen = i2d_SSL_SESSION(session, NULL);
@@ -3256,8 +3241,21 @@ static int add_session(SSL *ssl, SSL_SESSION *session)
     sess->id = BUF_memdup(SSL_SESSION_get_id(session, NULL), sess->idlen);
 
     sess->der = OPENSSL_malloc(sess->derlen);
+    if(!sess->id || !sess->der) {
+        BIO_printf(bio_err, "Out of memory adding session to external cache\n");
+
+        if(sess->id)
+            OPENSSL_free(sess->id);
+        if(sess->der)
+            OPENSSL_free(sess->der);
+        OPENSSL_free(sess);
+        return 0;
+    }
     p = sess->der;
-    i2d_SSL_SESSION(session, &p);
+    if(i2d_SSL_SESSION(session, &p) < 0) {
+        BIO_printf(bio_err, "Error encoding session\n");
+        return 0;
+    }
 
     sess->next = first;
     first = sess;