-
Notifications
You must be signed in to change notification settings - Fork 384
/
sslscan.h
374 lines (333 loc) · 13.5 KB
/
sslscan.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
/***************************************************************************
* sslscan - A SSL cipher scanning tool *
* Copyright 2007-2009 by Ian Ventura-Whiting (Fizz) *
* Copyright 2010 by Michael Boman ([email protected]) *
* Copyleft 2010 by Jacob Appelbaum <[email protected]> *
* Copyleft 2013 by rbsec <[email protected]> *
* Copyleft 2014 by Julian Kornberger <[email protected]> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
* In addition, as a special exception, the copyright holders give *
* permission to link the code of portions of this program with the *
* OpenSSL library under certain conditions as described in each *
* individual source file, and distribute linked combinations *
* including the two. *
* You must obey the GNU General Public License in all respects *
* for all of the code used other than OpenSSL. If you modify *
* file(s) with this exception, you may extend this exception to your *
* version of the file(s), but you are not obligated to do so. If you *
* do not wish to do so, delete this exception statement from your *
* version. If you delete this exception statement from all source *
* files in the program, then also delete it here. *
***************************************************************************/
#ifndef HAVE_SSLSCAN_H_
#define HAVE_SSLSCAN_H_
#include "missing_ciphersuites.h"
// Defines...
#define false 0
#define true 1
#define mode_help 0
#define mode_version 1
#define mode_single 2
#define mode_multiple 3
#define BUFFERSIZE 1024
// For options.sslVersion field.
#define ssl_all 0
#define ssl_v2 1
#define ssl_v3 2
#define tls_all 3
#define tls_v10 4
#define tls_v11 5
#define tls_v12 6
#define tls_v13 7
// For functions that take a tls_version argument.
#define TLSv1_0 0
#define TLSv1_1 1
#define TLSv1_2 2
#define TLSv1_3 3
/* We must maintain our own list of TLSv1.3-specific ciphersuites here, because SSL_CTX_get_ciphers() will *always* return TLSv1.2 ciphersuites, even when SSL_CTX_set_min_proto_version() and SSL_CTX_set_max_proto_version() are used. This is confirmed by an OpenSSL developer here: https://github.com/openssl/openssl/issues/7196#issuecomment-420575202 */
#define TLSV13_CIPHERSUITES "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256"
/* Cipherlist for TLSv1.2 and below that corresponds to all available ciphersuites. */
#define CIPHERSUITE_LIST_ALL "ALL:COMPLEMENTOFALL"
// Macros for various outputs
#define printf(format, ...) if (!xml_to_stdout) fprintf(stdout, format, ##__VA_ARGS__)
#define printf_xml(format, ...) if (options->xmlOutput) fprintf(options->xmlOutput, format, ##__VA_ARGS__)
#define printf_verbose(format, ...) if (options->verbose) printf(format, ##__VA_ARGS__)
#define printf_error(format, ...) \
if (!xml_to_stdout) fprintf(stderr, "%sERROR: " format "%s\n", COL_RED, ##__VA_ARGS__, RESET); \
printf_xml(" <error><![CDATA[" format "]]></error>\n", ##__VA_ARGS__)
/* Calls close() on a file descriptor, then sets it to zero to prevent accidental re-use. */
#define CLOSE(fd) { if ((fd) != -1) { close((fd)); (fd) = -1; } }
/* Calls free() on a pointer, then explicitly sets it to NULL to avoid use-after-free. */
#define FREE(ptr) { free((ptr)); (ptr) = NULL; }
/* Frees an SSL pointer, and explicitly sets it to NULL to avoid use-after-free. */
#define FREE_SSL(ssl) { if ((ssl) != NULL) { SSL_free((ssl)); (ssl) = NULL; } }
/* Frees a SSL_CTX pointer, and explicitly sets it to NULL to avoid use-after-free. */
#define FREE_CTX(ctx) { if ((ctx) != NULL) { SSL_CTX_free((ctx)); (ctx) = NULL; } }
// Colour Console Output...
// Always better to do "const char RESET[] = " because it saves relocation records.
// Default colours were hard to read on Windows, so use lighter ones
#ifdef _WIN32
char *RESET = "[0m"; // DEFAULT
char *COL_RED = "[91m";
char *COL_YELLOW = "[93m";
char *COL_BLUE = "[1;36m";
char *COL_GREEN = "[92m";
char *COL_PURPLE = "[95m";
char *COL_GREY = "[1;30m";
char *COL_RED_BG = "[41m";
#else
char *RESET = "[0m"; // DEFAULT
char *COL_RED = "[31m";
char *COL_YELLOW = "[33m";
char *COL_BLUE = "[1;34m";
char *COL_GREEN = "[32m";
char *COL_PURPLE = "[35m";
char *COL_GREY = "[1;30m";
char *COL_RED_BG = "[41m";
#endif
#ifdef _WIN32
#define SLEEPMS(ms) Sleep(ms);
#else
#define SLEEPMS(ms) do { \
struct timeval wait = { 0, ms*1000 }; \
select(0, NULL, NULL, NULL, &wait); \
} while(0)
#endif
const char *program_banner = " _\n"
" ___ ___| |___ ___ __ _ _ __\n"
" / __/ __| / __|/ __/ _` | '_ \\\n"
" \\__ \\__ \\ \\__ \\ (_| (_| | | | |\n"
" |___/___/_|___/\\___\\__,_|_| |_|\n\n";
struct sslCipher
{
// Cipher Properties...
const char *name;
const char *version;
int bits;
char description[512];
const SSL_METHOD *sslMethod;
struct sslCipher *next;
};
struct sslCheckOptions
{
// Program Options...
char host[512];
char sniname[512];
int sni_set;
char addrstr[INET6_ADDRSTRLEN];
int port;
int showCertificate;
int showCertificates;
int checkCertificate;
int showTrustedCAs;
int showClientCiphers;
int showCipherIds;
int showTimes;
int ciphersuites;
int reneg;
int fallback;
int compression;
int heartbleed;
int groups;
int signature_algorithms;
int starttls_ftp;
int starttls_imap;
int starttls_irc;
int starttls_ldap;
int starttls_pop3;
int starttls_smtp;
int starttls_mysql;
int starttls_xmpp;
int starttls_psql;
int xmpp_server;
int sslVersion;
int targets;
int sslbugs;
int rdp;
int verbose;
int cipher_details;
int ipv4;
int ipv6;
int ocspStatus;
int ianaNames;
char cipherstring[65536];
// File Handles...
FILE *xmlOutput;
// TCP Connection Variables...
short h_addrtype;
struct sockaddr_in serverAddress;
struct sockaddr_in6 serverAddress6;
struct timeval timeout;
int connect_timeout;
unsigned int sleep;
// SSL Variables...
SSL_CTX *ctx;
struct sslCipher *ciphers;
char *clientCertsFile;
char *privateKeyFile;
char *privateKeyPassword;
// TLS versions supported by the server.
unsigned int tls10_supported;
unsigned int tls11_supported;
unsigned int tls12_supported;
unsigned int tls13_supported;
};
// store renegotiation test data
struct renegotiationOutput
{
int supported;
int secure;
};
/* For OCSP processing. Taken from crypto/ocsp/ocsp_local.h in OpenSSL, which does not seem to be normally exposed externally. */
struct ocsp_response_st {
ASN1_ENUMERATED *responseStatus;
OCSP_RESPBYTES *responseBytes;
};
struct ocsp_resp_bytes_st {
ASN1_OBJECT *responseType;
ASN1_OCTET_STRING *response;
};
struct ocsp_responder_id_st {
int type;
union {
X509_NAME *byName;
ASN1_OCTET_STRING *byKey;
} value;
};
typedef struct ocsp_responder_id_st OCSP_RESPID;
struct ocsp_response_data_st {
ASN1_INTEGER *version;
OCSP_RESPID responderId;
ASN1_GENERALIZEDTIME *producedAt;
STACK_OF(OCSP_SINGLERESP) *responses;
STACK_OF(X509_EXTENSION) *responseExtensions;
};
typedef struct ocsp_response_data_st OCSP_RESPDATA;
struct ocsp_basic_response_st {
OCSP_RESPDATA tbsResponseData;
X509_ALGOR signatureAlgorithm;
ASN1_BIT_STRING *signature;
STACK_OF(X509) *certs;
};
struct ocsp_single_response_st {
OCSP_CERTID *certId;
OCSP_CERTSTATUS *certStatus;
ASN1_GENERALIZEDTIME *thisUpdate;
ASN1_GENERALIZEDTIME *nextUpdate;
STACK_OF(X509_EXTENSION) *singleExtensions;
};
struct ocsp_cert_status_st {
int type;
union {
ASN1_NULL *good;
OCSP_REVOKEDINFO *revoked;
ASN1_NULL *unknown;
} value;
};
struct ocsp_revoked_info_st {
ASN1_GENERALIZEDTIME *revocationTime;
ASN1_ENUMERATED *revocationReason;
};
struct ocsp_cert_id_st {
X509_ALGOR hashAlgorithm;
ASN1_OCTET_STRING issuerNameHash;
ASN1_OCTET_STRING issuerKeyHash;
ASN1_INTEGER serialNumber;
};
#define BS_DEFAULT_NEW_SIZE 256 /* The starting size of the buffer when bs_new() is used. */
struct _bs {
unsigned char *buf;
size_t size; /* The size of the allocated buffer. */
size_t len; /* The number of bytes currently in the buffer. */
};
typedef struct _bs bs; /* Stands for 'byte string'. */
/* We redefine these so that we can run correctly even if the vendor gives us
* a version of OpenSSL that does not match its header files. (Apple: I am
* looking at you.)
*/
#ifndef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
# define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L
#endif
#ifndef SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
# define SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x0010
#endif
// Utilities
void bs_new(bs **);
void bs_new_size(bs **, size_t);
void bs_free(bs **);
void bs_append_bytes(bs *, unsigned char *, size_t);
void bs_append_uint32_t(bs *, uint32_t);
void bs_append_ushort(bs *, unsigned short);
void bs_append_bs(bs *, bs *);
size_t bs_get_len(bs *);
size_t bs_get_size(bs *);
unsigned char *bs_get_bytes(bs *);
unsigned char bs_get_byte(bs *, size_t);
void bs_set_byte(bs *, size_t, unsigned char);
void bs_set_ushort(bs *b, size_t offset, unsigned short length);
int bs_read_socket(bs *b, int s, size_t num_bytes);
unsigned int checkIfTLSVersionIsSupported(struct sslCheckOptions *options, unsigned int tls_version);
SSL_CTX *CTX_new(const SSL_METHOD *method);
int fileExists(char *);
void findMissingCiphers();
char *getPrintableTLSName(unsigned int tls_version);
bs *getServerHello(int s);
bs *makeCiphersuiteListAll(unsigned int tls_version);
bs *makeCiphersuiteListTLS13All();
bs *makeCiphersuiteListMissing(unsigned int tls_version);
bs *makeClientHello(struct sslCheckOptions *options, unsigned int version, bs *ciphersuite_list, bs *tls_extensions);
bs *makeTLSExtensions(struct sslCheckOptions *options, unsigned int include_signature_algorithms);
void markFoundCiphersuite(unsigned short server_cipher_id, unsigned int tls_version);
int ocsp_certid_print(BIO *bp, OCSP_CERTID *a, int indent);
static int ocsp_resp_cb(SSL *s, void *arg);
void readLine(FILE *, char *, int);
int readOrLogAndClose(int, void *, size_t, const struct sslCheckOptions *);
char *resolveCipherID(unsigned short cipher_id, int *cipher_bits);
static int password_callback(char *, int, int, void *);
const char *printableSslMethod(const SSL_METHOD *);
ssize_t sendString(int, const char[]);
int ssl_print_tmp_key(struct sslCheckOptions *, SSL *s);
void tlsExtensionAddDefaultKeyShare(bs *tls_extensions);
void tlsExtensionAddTLSv1_3(bs *tls_extensions);
void tlsExtensionUpdateLength(bs *tls_extensions);
int tcpConnect(struct sslCheckOptions *);
// Tests
void tls_reneg_init(struct sslCheckOptions *);
int outputRenegotiation(struct sslCheckOptions *, struct renegotiationOutput *);
struct renegotiationOutput *newRenegotiationOutput(void);
int freeRenegotiationOutput(struct renegotiationOutput *);
int testCompression(struct sslCheckOptions *, const SSL_METHOD *);
int testRenegotiation(struct sslCheckOptions *, const SSL_METHOD *);
#ifdef SSL_MODE_SEND_FALLBACK_SCSV
int testfallback(struct sslCheckOptions *, const SSL_METHOD *);
#endif
int testHeartbleed(struct sslCheckOptions *, const SSL_METHOD *);
int testSupportedGroups(struct sslCheckOptions *options);
int testSignatureAlgorithms(struct sslCheckOptions *options);
int testCipher(struct sslCheckOptions *, const SSL_METHOD *);
int testMissingCiphers(struct sslCheckOptions *options, unsigned int version);
int testProtocolCiphers(struct sslCheckOptions *, const SSL_METHOD *);
int testConnection(struct sslCheckOptions *);
int testHost(struct sslCheckOptions *);
int loadCerts(struct sslCheckOptions *);
int checkCertificateProtocols(struct sslCheckOptions *, const SSL_METHOD *);
int checkCertificate(struct sslCheckOptions *, const SSL_METHOD *);
int showCertificate(struct sslCheckOptions *);
int runSSLv2Test(struct sslCheckOptions *options);
int runSSLv3Test(struct sslCheckOptions *options);
#endif
/* vim :set ts=4 sw=4 sts=4 et : */