1 |
|
|
/* $OpenBSD: ciphers.c,v 1.8 2015/10/17 15:00:11 doug Exp $ */ |
2 |
|
|
/* |
3 |
|
|
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 |
|
|
* |
5 |
|
|
* Permission to use, copy, modify, and distribute this software for any |
6 |
|
|
* purpose with or without fee is hereby granted, provided that the above |
7 |
|
|
* copyright notice and this permission notice appear in all copies. |
8 |
|
|
* |
9 |
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
10 |
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
11 |
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
12 |
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
13 |
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
14 |
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
15 |
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 |
|
|
*/ |
17 |
|
|
|
18 |
|
|
#include <stdio.h> |
19 |
|
|
#include <stdlib.h> |
20 |
|
|
|
21 |
|
|
#include <openssl/err.h> |
22 |
|
|
#include <openssl/ssl.h> |
23 |
|
|
|
24 |
|
|
#include "apps.h" |
25 |
|
|
#include "progs.h" |
26 |
|
|
|
27 |
|
|
struct { |
28 |
|
|
int usage; |
29 |
|
|
int verbose; |
30 |
|
|
} ciphers_config; |
31 |
|
|
|
32 |
|
|
struct option ciphers_options[] = { |
33 |
|
|
{ |
34 |
|
|
.name = "h", |
35 |
|
|
.type = OPTION_FLAG, |
36 |
|
|
.opt.flag = &ciphers_config.usage, |
37 |
|
|
}, |
38 |
|
|
{ |
39 |
|
|
.name = "?", |
40 |
|
|
.type = OPTION_FLAG, |
41 |
|
|
.opt.flag = &ciphers_config.usage, |
42 |
|
|
}, |
43 |
|
|
{ |
44 |
|
|
.name = "tls1", |
45 |
|
|
.desc = "This option is deprecated since it is the default", |
46 |
|
|
.type = OPTION_DISCARD, |
47 |
|
|
}, |
48 |
|
|
{ |
49 |
|
|
.name = "v", |
50 |
|
|
.desc = "Provide cipher listing", |
51 |
|
|
.type = OPTION_VALUE, |
52 |
|
|
.opt.value = &ciphers_config.verbose, |
53 |
|
|
.value = 1, |
54 |
|
|
}, |
55 |
|
|
{ |
56 |
|
|
.name = "V", |
57 |
|
|
.desc = "Provide cipher listing with cipher suite values", |
58 |
|
|
.type = OPTION_VALUE, |
59 |
|
|
.opt.value = &ciphers_config.verbose, |
60 |
|
|
.value = 2, |
61 |
|
|
}, |
62 |
|
|
{ NULL }, |
63 |
|
|
}; |
64 |
|
|
|
65 |
|
|
static void |
66 |
|
|
ciphers_usage(void) |
67 |
|
|
{ |
68 |
|
8 |
fprintf(stderr, "usage: ciphers [-hVv] [-tls1] [cipherlist]\n"); |
69 |
|
4 |
options_usage(ciphers_options); |
70 |
|
4 |
} |
71 |
|
|
|
72 |
|
|
int |
73 |
|
|
ciphers_main(int argc, char **argv) |
74 |
|
|
{ |
75 |
|
28 |
char *cipherlist = NULL; |
76 |
|
|
STACK_OF(SSL_CIPHER) *ciphers; |
77 |
|
|
const SSL_CIPHER *cipher; |
78 |
|
|
SSL_CTX *ssl_ctx = NULL; |
79 |
|
|
SSL *ssl = NULL; |
80 |
|
|
uint16_t value; |
81 |
|
|
int i, rv = 0; |
82 |
|
|
char *desc; |
83 |
|
|
|
84 |
✓✗ |
14 |
if (single_execution) { |
85 |
✗✓ |
14 |
if (pledge("stdio rpath flock cpath wpath", NULL) == -1) { |
86 |
|
|
perror("pledge"); |
87 |
|
|
exit(1); |
88 |
|
|
} |
89 |
|
|
} |
90 |
|
|
|
91 |
|
14 |
memset(&ciphers_config, 0, sizeof(ciphers_config)); |
92 |
|
|
|
93 |
✓✓ |
28 |
if (options_parse(argc, argv, ciphers_options, &cipherlist, |
94 |
|
14 |
NULL) != 0) { |
95 |
|
4 |
ciphers_usage(); |
96 |
|
4 |
return (1); |
97 |
|
|
} |
98 |
|
|
|
99 |
✗✓ |
10 |
if (ciphers_config.usage) { |
100 |
|
|
ciphers_usage(); |
101 |
|
|
return (1); |
102 |
|
|
} |
103 |
|
|
|
104 |
✓✗ |
10 |
if ((ssl_ctx = SSL_CTX_new(TLSv1_client_method())) == NULL) |
105 |
|
|
goto err; |
106 |
|
|
|
107 |
✓✓ |
10 |
if (cipherlist != NULL) { |
108 |
✓✗ |
6 |
if (SSL_CTX_set_cipher_list(ssl_ctx, cipherlist) == 0) |
109 |
|
|
goto err; |
110 |
|
|
} |
111 |
|
|
|
112 |
✓✗ |
10 |
if ((ssl = SSL_new(ssl_ctx)) == NULL) |
113 |
|
|
goto err; |
114 |
|
|
|
115 |
✓✗ |
10 |
if ((ciphers = SSL_get_ciphers(ssl)) == NULL) |
116 |
|
|
goto err; |
117 |
|
|
|
118 |
✓✓ |
570 |
for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { |
119 |
|
275 |
cipher = sk_SSL_CIPHER_value(ciphers, i); |
120 |
✓✓ |
275 |
if (ciphers_config.verbose == 0) { |
121 |
|
174 |
fprintf(stdout, "%s%s", (i ? ":" : ""), |
122 |
|
87 |
SSL_CIPHER_get_name(cipher)); |
123 |
|
87 |
continue; |
124 |
|
|
} |
125 |
✓✗ |
188 |
if (ciphers_config.verbose > 1) { |
126 |
|
188 |
value = SSL_CIPHER_get_value(cipher); |
127 |
|
188 |
fprintf(stdout, "%-*s0x%02X,0x%02X - ", 10, "", |
128 |
|
188 |
((value >> 8) & 0xff), (value & 0xff)); |
129 |
|
188 |
} |
130 |
|
188 |
desc = SSL_CIPHER_description(cipher, NULL, 0); |
131 |
✗✓ |
188 |
if (strcmp(desc, "OPENSSL_malloc Error") == 0) { |
132 |
|
|
fprintf(stderr, "out of memory\n"); |
133 |
|
|
goto err; |
134 |
|
|
} |
135 |
|
188 |
fprintf(stdout, "%s", desc); |
136 |
|
188 |
free(desc); |
137 |
|
188 |
} |
138 |
✓✓ |
10 |
if (ciphers_config.verbose == 0) |
139 |
|
6 |
fprintf(stdout, "\n"); |
140 |
|
|
|
141 |
|
|
goto done; |
142 |
|
|
|
143 |
|
|
err: |
144 |
|
|
ERR_print_errors_fp(stderr); |
145 |
|
|
rv = 1; |
146 |
|
|
|
147 |
|
|
done: |
148 |
|
10 |
SSL_CTX_free(ssl_ctx); |
149 |
|
10 |
SSL_free(ssl); |
150 |
|
|
|
151 |
|
10 |
return (rv); |
152 |
|
14 |
} |