apps/speed.c: fix typo in last commit.
[openssl.git] / apps / s_client.c
index 94e03c9c000f271e9b7e04a864d9c79f9ca93f3f..b72e505fb1c536316a8f7aef3ab4feb82f0a61aa 100644 (file)
@@ -206,6 +206,9 @@ static int c_status_req=0;
 static int c_msg=0;
 static int c_showcerts=0;
 
+static char *keymatexportlabel=NULL;
+static int keymatexportlen=20;
+
 static void sc_usage(void);
 static void print_stuff(BIO *berr,SSL *con,int full);
 #ifndef OPENSSL_NO_TLSEXT
@@ -360,6 +363,8 @@ static void sc_usage(void)
 #endif
        BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
        BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list");
+       BIO_printf(bio_err," -keymatexport label   - Export keying material using label\n");
+       BIO_printf(bio_err," -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
        }
 
 #ifndef OPENSSL_NO_TLSEXT
@@ -398,7 +403,7 @@ typedef struct srp_arg_st
 
 #define SRP_NUMBER_ITERATIONS_FOR_PRIME 64
 
-static int SRP_Verify_N_and_g(BIGNUM *N, BIGNUM *g)
+static int srp_Verify_N_and_g(BIGNUM *N, BIGNUM *g)
        {
        BN_CTX *bn_ctx = BN_CTX_new();
        BIGNUM *p = BN_new();
@@ -426,6 +431,21 @@ static int SRP_Verify_N_and_g(BIGNUM *N, BIGNUM *g)
        return ret;
        }
 
+/* This callback is used here for two purposes:
+   - extended debugging
+   - making some primality tests for unknown groups
+   The callback is only called for a non default group.
+
+   An application does not need the call back at all if
+   only the stanard groups are used.  In real life situations, 
+   client and server already share well known groups, 
+   thus there is no need to verify them. 
+   Furthermore, in case that a server actually proposes a group that
+   is not one of those defined in RFC 5054, it is more appropriate 
+   to add the group to a static list and then compare since 
+   primality tests are rather cpu consuming.
+*/
+
 static int MS_CALLBACK ssl_srp_verify_param_cb(SSL *s, void *arg)
        {
        SRP_ARG *srp_arg = (SRP_ARG *)arg;
@@ -448,11 +468,11 @@ static int MS_CALLBACK ssl_srp_verify_param_cb(SSL *s, void *arg)
                if (srp_arg->debug)
                        BIO_printf(bio_err, "SRP param N and g are not known params, going to check deeper.\n");
 
-/* The srp_moregroups must be used with caution, testing primes costs time. 
+/* The srp_moregroups is a real debugging feature.
    Implementors should rather add the value to the known ones.
    The minimal size has already been tested.
 */
-               if (BN_num_bits(g) <= BN_BITS && SRP_Verify_N_and_g(N,g))
+               if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N,g))
                        return 1;
                }       
        BIO_printf(bio_err, "SRP param N and g rejected.\n");
@@ -481,12 +501,6 @@ static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
        return pass;
        }
 
-static char * MS_CALLBACK missing_srp_username_callback(SSL *s, void *arg)
-       {
-       SRP_ARG *srp_arg = (SRP_ARG *)arg;
-       return BUF_strdup(srp_arg->srplogin);
-       }
-
 #endif
        char *srtp_profiles = NULL;
 
@@ -942,6 +956,17 @@ int MAIN(int argc, char **argv)
                        if (--argc < 1) goto bad;
                        srtp_profiles = *(++argv);
                        }
+               else if (strcmp(*argv,"-keymatexport") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       keymatexportlabel= *(++argv);
+                       }
+               else if (strcmp(*argv,"-keymatexportlen") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       keymatexportlen=atoi(*(++argv));
+                       if (keymatexportlen == 0) goto bad;
+                       }
                 else
                        {
                        BIO_printf(bio_err,"unknown option %s\n",*argv);
@@ -1166,9 +1191,7 @@ bad:
 #ifndef OPENSSL_NO_SRP
         if (srp_arg.srplogin)
                {
-               if (srp_lateuser) 
-                       SSL_CTX_set_srp_missing_srp_username_callback(ctx,missing_srp_username_callback);
-               else if (!SSL_CTX_set_srp_username(ctx, srp_arg.srplogin))
+               if (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg.srplogin))
                        {
                        BIO_printf(bio_err,"Unable to set SRP username\n");
                        goto end;
@@ -1900,6 +1923,7 @@ static void print_stuff(BIO *bio, SSL *s, int full)
 #ifndef OPENSSL_NO_COMP
        const COMP_METHOD *comp, *expansion;
 #endif
+       unsigned char *exportedkeymat;
 
        if (full)
                {
@@ -2045,6 +2069,30 @@ static void print_stuff(BIO *bio, SSL *s, int full)
        }
  
        SSL_SESSION_print(bio,SSL_get_session(s));
+       if (keymatexportlabel != NULL) {
+               BIO_printf(bio, "Keying material exporter:\n");
+               BIO_printf(bio, "    Label: '%s'\n", keymatexportlabel);
+               BIO_printf(bio, "    Length: %i bytes\n", keymatexportlen);
+               exportedkeymat = OPENSSL_malloc(keymatexportlen);
+               if (exportedkeymat != NULL) {
+                       i = SSL_export_keying_material(s, exportedkeymat,
+                                                      keymatexportlen,
+                                                      keymatexportlabel,
+                                                    strlen(keymatexportlabel),
+                                                      NULL, 0, 0);
+                       if (i != keymatexportlen) {
+                               BIO_printf(bio,
+                                          "    Error: return value %i\n", i);
+                       } else {
+                               BIO_printf(bio, "    Keying material: ");
+                               for (i=0; i<keymatexportlen; i++)
+                                       BIO_printf(bio, "%02X",
+                                                  exportedkeymat[i]);
+                               BIO_printf(bio, "\n");
+                       }
+                       OPENSSL_free(exportedkeymat);
+               }
+       }
        BIO_printf(bio,"---\n");
        if (peer != NULL)
                X509_free(peer);