Configure: Better detection of '-static' in @{$config{LDFLAGS}}
[openssl.git] / apps / ciphers.c
1 /*
2  * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include "apps.h"
14 #include "progs.h"
15 #include <openssl/err.h>
16 #include <openssl/ssl.h>
17
18 typedef enum OPTION_choice {
19     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
20     OPT_STDNAME,
21     OPT_CONVERT,
22     OPT_SSL3,
23     OPT_TLS1,
24     OPT_TLS1_1,
25     OPT_TLS1_2,
26     OPT_TLS1_3,
27     OPT_PSK,
28     OPT_SRP,
29     OPT_CIPHERSUITES,
30     OPT_V, OPT_UPPER_V, OPT_S
31 } OPTION_CHOICE;
32
33 const OPTIONS ciphers_options[] = {
34     {OPT_HELP_STR, 1, '-', "Usage: %s [options] [cipher]\n"},
35
36     OPT_SECTION("General"),
37     {"help", OPT_HELP, '-', "Display this summary"},
38
39     OPT_SECTION("Output"),
40     {"v", OPT_V, '-', "Verbose listing of the SSL/TLS ciphers"},
41     {"V", OPT_UPPER_V, '-', "Even more verbose"},
42     {"stdname", OPT_STDNAME, '-', "Show standard cipher names"},
43     {"convert", OPT_CONVERT, 's', "Convert standard name into OpenSSL name"},
44
45     OPT_SECTION("Cipher specification"),
46     {"s", OPT_S, '-', "Only supported ciphers"},
47 #ifndef OPENSSL_NO_SSL3
48     {"ssl3", OPT_SSL3, '-', "Ciphers compatible with SSL3"},
49 #endif
50 #ifndef OPENSSL_NO_TLS1
51     {"tls1", OPT_TLS1, '-', "Ciphers compatible with TLS1"},
52 #endif
53 #ifndef OPENSSL_NO_TLS1_1
54     {"tls1_1", OPT_TLS1_1, '-', "Ciphers compatible with TLS1.1"},
55 #endif
56 #ifndef OPENSSL_NO_TLS1_2
57     {"tls1_2", OPT_TLS1_2, '-', "Ciphers compatible with TLS1.2"},
58 #endif
59 #ifndef OPENSSL_NO_TLS1_3
60     {"tls1_3", OPT_TLS1_3, '-', "Ciphers compatible with TLS1.3"},
61 #endif
62 #ifndef OPENSSL_NO_PSK
63     {"psk", OPT_PSK, '-', "Include ciphersuites requiring PSK"},
64 #endif
65 #ifndef OPENSSL_NO_SRP
66     {"srp", OPT_SRP, '-', "Include ciphersuites requiring SRP"},
67 #endif
68     {"ciphersuites", OPT_CIPHERSUITES, 's',
69      "Configure the TLSv1.3 ciphersuites to use"},
70
71     OPT_PARAMETERS(),
72     {"cipher", 0, 0, "Cipher string to decode (optional)"},
73     {NULL}
74 };
75
76 #ifndef OPENSSL_NO_PSK
77 static unsigned int dummy_psk(SSL *ssl, const char *hint, char *identity,
78                               unsigned int max_identity_len,
79                               unsigned char *psk,
80                               unsigned int max_psk_len)
81 {
82     return 0;
83 }
84 #endif
85 #ifndef OPENSSL_NO_SRP
86 static char *dummy_srp(SSL *ssl, void *arg)
87 {
88     return "";
89 }
90 #endif
91
92 int ciphers_main(int argc, char **argv)
93 {
94     SSL_CTX *ctx = NULL;
95     SSL *ssl = NULL;
96     STACK_OF(SSL_CIPHER) *sk = NULL;
97     const SSL_METHOD *meth = TLS_server_method();
98     int ret = 1, i, verbose = 0, Verbose = 0, use_supported = 0;
99     int stdname = 0;
100 #ifndef OPENSSL_NO_PSK
101     int psk = 0;
102 #endif
103 #ifndef OPENSSL_NO_SRP
104     int srp = 0;
105 #endif
106     const char *p;
107     char *ciphers = NULL, *prog, *convert = NULL, *ciphersuites = NULL;
108     char buf[512];
109     OPTION_CHOICE o;
110     int min_version = 0, max_version = 0;
111
112     prog = opt_init(argc, argv, ciphers_options);
113     while ((o = opt_next()) != OPT_EOF) {
114         switch (o) {
115         case OPT_EOF:
116         case OPT_ERR:
117  opthelp:
118             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
119             goto end;
120         case OPT_HELP:
121             opt_help(ciphers_options);
122             ret = 0;
123             goto end;
124         case OPT_V:
125             verbose = 1;
126             break;
127         case OPT_UPPER_V:
128             verbose = Verbose = 1;
129             break;
130         case OPT_S:
131             use_supported = 1;
132             break;
133         case OPT_STDNAME:
134             stdname = verbose = 1;
135             break;
136         case OPT_CONVERT:
137             convert = opt_arg();
138             break;
139         case OPT_SSL3:
140             min_version = SSL3_VERSION;
141             max_version = SSL3_VERSION;
142             break;
143         case OPT_TLS1:
144             min_version = TLS1_VERSION;
145             max_version = TLS1_VERSION;
146             break;
147         case OPT_TLS1_1:
148             min_version = TLS1_1_VERSION;
149             max_version = TLS1_1_VERSION;
150             break;
151         case OPT_TLS1_2:
152             min_version = TLS1_2_VERSION;
153             max_version = TLS1_2_VERSION;
154             break;
155         case OPT_TLS1_3:
156             min_version = TLS1_3_VERSION;
157             max_version = TLS1_3_VERSION;
158             break;
159         case OPT_PSK:
160 #ifndef OPENSSL_NO_PSK
161             psk = 1;
162 #endif
163             break;
164         case OPT_SRP:
165 #ifndef OPENSSL_NO_SRP
166             srp = 1;
167 #endif
168             break;
169         case OPT_CIPHERSUITES:
170             ciphersuites = opt_arg();
171             break;
172         }
173     }
174     argv = opt_rest();
175     argc = opt_num_rest();
176
177     if (argc == 1)
178         ciphers = *argv;
179     else if (argc != 0)
180         goto opthelp;
181
182     if (convert != NULL) {
183         BIO_printf(bio_out, "OpenSSL cipher name: %s\n",
184                    OPENSSL_cipher_name(convert));
185         goto end;
186     }
187
188     ctx = SSL_CTX_new(meth);
189     if (ctx == NULL)
190         goto err;
191     if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
192         goto err;
193     if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
194         goto err;
195
196 #ifndef OPENSSL_NO_PSK
197     if (psk)
198         SSL_CTX_set_psk_client_callback(ctx, dummy_psk);
199 #endif
200 #ifndef OPENSSL_NO_SRP
201     if (srp)
202         SSL_CTX_set_srp_client_pwd_callback(ctx, dummy_srp);
203 #endif
204
205     if (ciphersuites != NULL && !SSL_CTX_set_ciphersuites(ctx, ciphersuites)) {
206         BIO_printf(bio_err, "Error setting TLSv1.3 ciphersuites\n");
207         goto err;
208     }
209
210     if (ciphers != NULL) {
211         if (!SSL_CTX_set_cipher_list(ctx, ciphers)) {
212             BIO_printf(bio_err, "Error in cipher list\n");
213             goto err;
214         }
215     }
216     ssl = SSL_new(ctx);
217     if (ssl == NULL)
218         goto err;
219
220     if (use_supported)
221         sk = SSL_get1_supported_ciphers(ssl);
222     else
223         sk = SSL_get_ciphers(ssl);
224
225     if (!verbose) {
226         for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
227             const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i);
228             p = SSL_CIPHER_get_name(c);
229             if (p == NULL)
230                 break;
231             if (i != 0)
232                 BIO_printf(bio_out, ":");
233             BIO_printf(bio_out, "%s", p);
234         }
235         BIO_printf(bio_out, "\n");
236     } else {
237
238         for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
239             const SSL_CIPHER *c;
240
241             c = sk_SSL_CIPHER_value(sk, i);
242
243             if (Verbose) {
244                 unsigned long id = SSL_CIPHER_get_id(c);
245                 int id0 = (int)(id >> 24);
246                 int id1 = (int)((id >> 16) & 0xffL);
247                 int id2 = (int)((id >> 8) & 0xffL);
248                 int id3 = (int)(id & 0xffL);
249
250                 if ((id & 0xff000000L) == 0x03000000L)
251                     BIO_printf(bio_out, "          0x%02X,0x%02X - ", id2, id3); /* SSL3
252                                                                                   * cipher */
253                 else
254                     BIO_printf(bio_out, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */
255             }
256             if (stdname) {
257                 const char *nm = SSL_CIPHER_standard_name(c);
258                 if (nm == NULL)
259                     nm = "UNKNOWN";
260                 BIO_printf(bio_out, "%-45s - ", nm);
261             }
262             BIO_puts(bio_out, SSL_CIPHER_description(c, buf, sizeof(buf)));
263         }
264     }
265
266     ret = 0;
267     goto end;
268  err:
269     ERR_print_errors(bio_err);
270  end:
271     if (use_supported)
272         sk_SSL_CIPHER_free(sk);
273     SSL_CTX_free(ctx);
274     SSL_free(ssl);
275     return ret;
276 }