Add a -max_early_data option to s_server
[openssl.git] / apps / s_server.c
index 7eee91083a789f129b12f94910e6ecde6eb461c2..cc910bc9a9df45626d0a96103ab91bf4cd1e9c4e 100644 (file)
@@ -451,16 +451,16 @@ static int ssl_servername_cb(SSL *s, int *ad, void *arg)
 /* Structure passed to cert status callback */
 
 typedef struct tlsextstatusctx_st {
 /* Structure passed to cert status callback */
 
 typedef struct tlsextstatusctx_st {
+    int timeout;
     /* File to load OCSP Response from (or NULL if no file) */
     char *respin;
     /* Default responder to use */
     char *host, *path, *port;
     int use_ssl;
     /* File to load OCSP Response from (or NULL if no file) */
     char *respin;
     /* Default responder to use */
     char *host, *path, *port;
     int use_ssl;
-    int timeout;
     int verbose;
 } tlsextstatusctx;
 
     int verbose;
 } tlsextstatusctx;
 
-static tlsextstatusctx tlscstatp = { NULL, NULL, NULL, NULL, 0, -1, 0 };
+static tlsextstatusctx tlscstatp = { -1 };
 
 #ifndef OPENSSL_NO_OCSP
 
 
 #ifndef OPENSSL_NO_OCSP
 
@@ -553,7 +553,11 @@ static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx,
  err:
     ret = SSL_TLSEXT_ERR_ALERT_FATAL;
  done:
  err:
     ret = SSL_TLSEXT_ERR_ALERT_FATAL;
  done:
-    if (aia) {
+    /*
+     * If we parsed aia we need to free; otherwise they were copied and we
+     * don't
+     */
+    if (aia != NULL) {
         OPENSSL_free(host);
         OPENSSL_free(path);
         OPENSSL_free(port);
         OPENSSL_free(host);
         OPENSSL_free(path);
         OPENSSL_free(port);
@@ -589,7 +593,7 @@ static int cert_status_cb(SSL *s, void *arg)
         }
         resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
         BIO_free(derbio);
         }
         resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
         BIO_free(derbio);
-        if (!resp) {
+        if (resp == NULL) {
             BIO_puts(bio_err, "cert_status: Error reading OCSP response\n");
             goto err;
         }
             BIO_puts(bio_err, "cert_status: Error reading OCSP response\n");
             goto err;
         }
@@ -695,7 +699,7 @@ static char *srtp_profiles = NULL;
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE,
     OPT_4, OPT_6, OPT_ACCEPT, OPT_PORT, OPT_UNIX, OPT_UNLINK, OPT_NACCEPT,
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE,
     OPT_4, OPT_6, OPT_ACCEPT, OPT_PORT, OPT_UNIX, OPT_UNLINK, OPT_NACCEPT,
-    OPT_VERIFY, OPT_UPPER_V_VERIFY, OPT_CONTEXT, OPT_CERT, OPT_CRL,
+    OPT_VERIFY, OPT_NAMEOPT, OPT_UPPER_V_VERIFY, OPT_CONTEXT, OPT_CERT, OPT_CRL,
     OPT_CRL_DOWNLOAD, OPT_SERVERINFO, OPT_CERTFORM, OPT_KEY, OPT_KEYFORM,
     OPT_PASS, OPT_CERT_CHAIN, OPT_DHPARAM, OPT_DCERTFORM, OPT_DCERT,
     OPT_DKEYFORM, OPT_DPASS, OPT_DKEY, OPT_DCERT_CHAIN, OPT_NOCERT,
     OPT_CRL_DOWNLOAD, OPT_SERVERINFO, OPT_CERTFORM, OPT_KEY, OPT_KEYFORM,
     OPT_PASS, OPT_CERT_CHAIN, OPT_DHPARAM, OPT_DCERTFORM, OPT_DCERT,
     OPT_DKEYFORM, OPT_DPASS, OPT_DKEY, OPT_DCERT_CHAIN, OPT_NOCERT,
@@ -715,6 +719,7 @@ typedef enum OPTION_choice {
     OPT_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
     OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
     OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
     OPT_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
     OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
     OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
+    OPT_KEYLOG_FILE, OPT_MAX_EARLY,
     OPT_S_ENUM,
     OPT_V_ENUM,
     OPT_X_ENUM
     OPT_S_ENUM,
     OPT_V_ENUM,
     OPT_X_ENUM
@@ -739,6 +744,7 @@ const OPTIONS s_server_options[] = {
     {"Verify", OPT_UPPER_V_VERIFY, 'n',
      "Turn on peer certificate verification, must have a cert"},
     {"cert", OPT_CERT, '<', "Certificate file to use; default is " TEST_CERT},
     {"Verify", OPT_UPPER_V_VERIFY, 'n',
      "Turn on peer certificate verification, must have a cert"},
     {"cert", OPT_CERT, '<', "Certificate file to use; default is " TEST_CERT},
+    {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
     {"naccept", OPT_NACCEPT, 'p', "Terminate after #num connections"},
     {"serverinfo", OPT_SERVERINFO, 's',
      "PEM serverinfo file for certificate"},
     {"naccept", OPT_NACCEPT, 'p', "Terminate after #num connections"},
     {"serverinfo", OPT_SERVERINFO, 's',
      "PEM serverinfo file for certificate"},
@@ -909,6 +915,9 @@ const OPTIONS s_server_options[] = {
 #ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
 #endif
 #ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
 #endif
+    {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"},
+    {"max_early_data", OPT_MAX_EARLY, 'p',
+     "The maximum number of bytes of early data"},
     {NULL, OPT_EOF, 0, NULL}
 };
 
     {NULL, OPT_EOF, 0, NULL}
 };
 
@@ -984,6 +993,8 @@ int s_server_main(int argc, char *argv[])
     int no_resume_ephemeral = 0;
     unsigned int split_send_fragment = 0, max_pipelines = 0;
     const char *s_serverinfo_file = NULL;
     int no_resume_ephemeral = 0;
     unsigned int split_send_fragment = 0, max_pipelines = 0;
     const char *s_serverinfo_file = NULL;
+    const char *keylog_file = NULL;
+    uint32_t max_early_data = 0;
 
     /* Init of few remaining global variables */
     local_argc = argc;
 
     /* Init of few remaining global variables */
     local_argc = argc;
@@ -1120,6 +1131,10 @@ int s_server_main(int argc, char *argv[])
         case OPT_CERT:
             s_cert_file = opt_arg();
             break;
         case OPT_CERT:
             s_cert_file = opt_arg();
             break;
+        case OPT_NAMEOPT:
+            if (!set_nameopt(opt_arg()))
+                goto end;
+            break;
         case OPT_CRL:
             crl_file = opt_arg();
             break;
         case OPT_CRL:
             crl_file = opt_arg();
             break;
@@ -1485,7 +1500,12 @@ int s_server_main(int argc, char *argv[])
         case OPT_READ_BUF:
             read_buf_len = atoi(opt_arg());
             break;
         case OPT_READ_BUF:
             read_buf_len = atoi(opt_arg());
             break;
-
+        case OPT_KEYLOG_FILE:
+            keylog_file = opt_arg();
+            break;
+        case OPT_MAX_EARLY:
+            max_early_data = atoi(opt_arg());
+            break;
         }
     }
     argc = opt_num_rest();
         }
     }
     argc = opt_num_rest();
@@ -1973,6 +1993,11 @@ int s_server_main(int argc, char *argv[])
         }
     }
 #endif
         }
     }
 #endif
+    if (set_keylog_file(ctx, keylog_file))
+        goto end;
+
+    if (max_early_data > 0)
+        SSL_CTX_set_max_early_data(ctx, max_early_data);
 
     BIO_printf(bio_s_out, "ACCEPT\n");
     (void)BIO_flush(bio_s_out);
 
     BIO_printf(bio_s_out, "ACCEPT\n");
     (void)BIO_flush(bio_s_out);
@@ -1993,6 +2018,7 @@ int s_server_main(int argc, char *argv[])
     ret = 0;
  end:
     SSL_CTX_free(ctx);
     ret = 0;
  end:
     SSL_CTX_free(ctx);
+    set_keylog_file(NULL, NULL);
     X509_free(s_cert);
     sk_X509_CRL_pop_free(crls, X509_CRL_free);
     X509_free(s_dcert);
     X509_free(s_cert);
     sk_X509_CRL_pop_free(crls, X509_CRL_free);
     X509_free(s_dcert);
@@ -2307,6 +2333,20 @@ static int sv_body(int s, int stype, unsigned char *context)
                      * cert\n");
                      */
                 }
                      * cert\n");
                      */
                 }
+                if ((buf[0] == 'K' || buf[0] == 'k')
+                        && ((buf[1] == '\n') || (buf[1] == '\r'))) {
+                    SSL_key_update(con, buf[0] == 'K' ?
+                                        SSL_KEY_UPDATE_REQUESTED
+                                        : SSL_KEY_UPDATE_NOT_REQUESTED);
+                    i = SSL_do_handshake(con);
+                    printf("SSL_do_handshake -> %d\n", i);
+                    i = 0;
+                    continue;
+                    /*
+                     * strcpy(buf,"server side RE-NEGOTIATE asking for client
+                     * cert\n");
+                     */
+                }
                 if (buf[0] == 'P') {
                     static const char *str = "Lets print some clear text\n";
                     BIO_write(SSL_get_wbio(con), str, strlen(str));
                 if (buf[0] == 'P') {
                     static const char *str = "Lets print some clear text\n";
                     BIO_write(SSL_get_wbio(con), str, strlen(str));