Line data Source code
1 : #include "burp.h"
2 : #include "alloc.h"
3 : #include "conf.h"
4 : #include "log.h"
5 : #include "server/ca.h"
6 :
7 : static const char *pass=NULL;
8 :
9 0 : int ssl_do_accept(SSL *ssl)
10 : {
11 : while(1)
12 : {
13 : int r;
14 0 : ERR_clear_error();
15 0 : switch((r=SSL_accept(ssl)))
16 : {
17 : case 1:
18 : return 0;
19 : case 0:
20 : goto error;
21 : default:
22 0 : switch(SSL_get_error(ssl, r))
23 : {
24 : case SSL_ERROR_WANT_READ:
25 : continue;
26 : default:
27 : goto error;
28 : }
29 : break;
30 : }
31 : }
32 : error:
33 0 : logp_ssl_err("SSL_accept\n");
34 0 : return -1;
35 : }
36 :
37 0 : int ssl_load_dh_params(SSL_CTX *ctx, struct conf **confs)
38 : {
39 0 : DH *ret=0;
40 0 : BIO *bio=NULL;
41 0 : const char *ssl_dhfile=get_string(confs[OPT_SSL_DHFILE]);
42 :
43 0 : if(!(bio=BIO_new_file(ssl_dhfile, "r")))
44 : {
45 0 : logp_ssl_err("Couldn't open ssl_dhfile: %s\n", ssl_dhfile);
46 0 : return -1;
47 : }
48 :
49 0 : ret=PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
50 0 : BIO_free(bio);
51 0 : if(SSL_CTX_set_tmp_dh(ctx, ret)<0)
52 : {
53 0 : logp_ssl_err("Couldn't set DH parameters");
54 0 : return -1;
55 : }
56 : return 0;
57 : }
58 :
59 0 : static int password_cb(char *buf, int num, int rwflag, void *userdata)
60 : {
61 0 : if(num<(int)strlen(pass)+1) return 0;
62 0 : strcpy(buf, pass);
63 0 : return strlen(pass);
64 : }
65 :
66 1 : void ssl_load_globals(void)
67 : {
68 : // Global system initialization.
69 1 : SSL_library_init();
70 1 : SSL_load_error_strings();
71 1 : }
72 :
73 0 : static int check_path(const char *path, const char *what)
74 : {
75 : struct stat statp;
76 0 : if(!path) return -1;
77 0 : if(stat(path, &statp))
78 : {
79 : logp("Could not find %s %s: %s\n",
80 0 : what, path, strerror(errno));
81 0 : return -1;
82 : }
83 : return 0;
84 : }
85 :
86 0 : static int ssl_load_keys_and_certs(SSL_CTX *ctx, struct conf **confs)
87 : {
88 0 : char *ssl_key=NULL;
89 0 : const char *ssl_cert=get_string(confs[OPT_SSL_CERT]);
90 0 : const char *ssl_cert_ca=get_string(confs[OPT_SSL_CERT_CA]);
91 :
92 : // Load our keys and certificates if the path exists.
93 0 : if(!check_path(ssl_cert, "ssl_cert")
94 0 : && !SSL_CTX_use_certificate_chain_file(ctx, ssl_cert))
95 : {
96 0 : logp_ssl_err("Can't read ssl_cert: %s\n", ssl_cert);
97 0 : return -1;
98 : }
99 :
100 0 : pass=get_string(confs[OPT_SSL_KEY_PASSWORD]);
101 0 : SSL_CTX_set_default_passwd_cb(ctx, password_cb);
102 :
103 0 : ssl_key=get_string(confs[OPT_SSL_KEY]);
104 0 : if(!ssl_key) ssl_key=get_string(confs[OPT_SSL_CERT]);
105 :
106 : // Load the key file, if the path exists.
107 0 : if(!check_path(ssl_key, "ssl_key")
108 0 : && !SSL_CTX_use_PrivateKey_file(ctx, ssl_key, SSL_FILETYPE_PEM))
109 : {
110 0 : logp_ssl_err("Can't read ssl_key file: %s\n", ssl_key);
111 0 : return -1;
112 : }
113 :
114 : // Load the CAs we trust, if the path exists.
115 0 : if(!check_path(ssl_cert_ca, "ssl_cert_ca")
116 0 : && !SSL_CTX_load_verify_locations(ctx, ssl_cert_ca, 0))
117 : {
118 0 : logp_ssl_err("Can't read ssl_cert_ca file: %s\n", ssl_cert_ca);
119 0 : return -1;
120 : }
121 :
122 : return 0;
123 : }
124 :
125 0 : SSL_CTX *ssl_initialise_ctx(struct conf **confs)
126 : {
127 0 : SSL_CTX *ctx=NULL;
128 0 : SSL_METHOD *meth=NULL;
129 0 : const char *ssl_ciphers=get_string(confs[OPT_SSL_CIPHERS]);
130 :
131 : // Create our context.
132 0 : meth=(SSL_METHOD *)SSLv23_method();
133 0 : ctx=(SSL_CTX *)SSL_CTX_new(meth);
134 :
135 0 : if(ssl_load_keys_and_certs(ctx, confs)) return NULL;
136 :
137 0 : if(ssl_ciphers)
138 0 : SSL_CTX_set_cipher_list(ctx, ssl_ciphers);
139 :
140 : // Unclear what is negotiated, so keep quiet until I figure that out.
141 0 : if(!get_int(confs[OPT_SSL_COMPRESSION]))
142 : {
143 : #ifdef SSL_OP_NO_COMPRESSION
144 0 : SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
145 : #else
146 : logp("This version of openssl has no SSL_OP_NO_COMPRESSION option, so turning off config option '%s' will not work. You should probably upgrade openssl.\n", confs[OPT_SSL_COMPRESSION]->field);
147 : #endif
148 : }
149 : // Default is zlib5, which needs no option set.
150 :
151 0 : SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
152 :
153 0 : return ctx;
154 : }
155 :
156 1 : void ssl_destroy_ctx(SSL_CTX *ctx)
157 : {
158 1 : SSL_CTX_free(ctx);
159 1 : }
160 :
161 : #ifndef HAVE_WIN32
162 0 : static void sanitise(char *buf)
163 : {
164 0 : char *cp=NULL;
165 0 : for(cp=buf; *cp; cp++)
166 : {
167 0 : if(!isalnum(*cp)
168 0 : && !isblank(*cp)
169 0 : && *cp!='_'
170 0 : && *cp!='-'
171 0 : && *cp!='.'
172 0 : && *cp!=':'
173 0 : && *cp!='@')
174 0 : *cp='_';
175 : }
176 0 : }
177 :
178 : // This function taken from openvpn-2.2.1 and tidied up a bit.
179 0 : static int setenv_x509(X509_NAME *x509, const char *type)
180 : {
181 : int i, n;
182 : int fn_nid;
183 : ASN1_OBJECT *fn;
184 : ASN1_STRING *val;
185 : X509_NAME_ENTRY *ent;
186 : const char *objbuf;
187 : uint8_t *buf;
188 : char *name_expand;
189 : size_t name_expand_size;
190 :
191 0 : n=X509_NAME_entry_count (x509);
192 0 : for(i=0; i<n; ++i)
193 : {
194 0 : if(!(ent=X509_NAME_get_entry (x509, i))
195 0 : || !(fn=X509_NAME_ENTRY_get_object(ent))
196 0 : || !(val=X509_NAME_ENTRY_get_data(ent))
197 0 : || (fn_nid=OBJ_obj2nid(fn))==NID_undef
198 0 : || !(objbuf=OBJ_nid2sn(fn_nid)))
199 : continue;
200 0 : buf=(uint8_t *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
201 0 : if(ASN1_STRING_to_UTF8(&buf, val)<=0) continue;
202 0 : name_expand_size=64+strlen(objbuf);
203 0 : if(!(name_expand=(char *)malloc_w(name_expand_size, __func__)))
204 : return -1;
205 : snprintf(name_expand, name_expand_size,
206 0 : "X509_%s_%s", type, objbuf);
207 0 : sanitise(name_expand);
208 0 : sanitise((char*)buf);
209 0 : setenv(name_expand, (char*)buf, 1);
210 0 : free_w(&name_expand);
211 0 : OPENSSL_free(buf);
212 : }
213 : return 0;
214 : }
215 :
216 0 : static int setenv_x509_date(ASN1_TIME *tm, const char *env)
217 : {
218 0 : BIO *bio_out=NULL;
219 0 : BUF_MEM *bptr=NULL;
220 0 : char tmpbuf[256]="";
221 0 : if(!(bio_out=BIO_new(BIO_s_mem())))
222 : {
223 0 : log_out_of_memory(__func__);
224 0 : return -1;
225 : }
226 0 : ASN1_TIME_print(bio_out, tm);
227 0 : BIO_get_mem_ptr(bio_out, &bptr);
228 0 : BIO_gets(bio_out, tmpbuf, sizeof(tmpbuf)-1);
229 0 : BIO_free_all(bio_out);
230 0 : sanitise(tmpbuf);
231 0 : setenv(env, (char*)tmpbuf, 1);
232 0 : return 0;
233 : }
234 :
235 0 : static int setenv_x509_serialnumber(ASN1_INTEGER *i, const char *env)
236 : {
237 0 : BIO *bio_out=NULL;
238 0 : BUF_MEM *bptr=NULL;
239 0 : char tmpbuf[256]="";
240 0 : if(!(bio_out=BIO_new(BIO_s_mem())))
241 : {
242 0 : log_out_of_memory(__func__);
243 0 : return -1;
244 : }
245 0 : i2a_ASN1_INTEGER(bio_out, i);
246 0 : BIO_get_mem_ptr(bio_out, &bptr);
247 0 : BIO_gets(bio_out, tmpbuf, sizeof(tmpbuf)-1);
248 0 : BIO_free_all(bio_out);
249 0 : sanitise(tmpbuf);
250 0 : setenv(env, (char*)tmpbuf, 1);
251 0 : return 0;
252 : }
253 : #endif
254 :
255 0 : int ssl_check_cert(SSL *ssl, struct conf **confs, struct conf **cconfs)
256 : {
257 : X509 *peer;
258 0 : char tmpbuf[256]="";
259 0 : const char *ssl_peer_cn=get_string(cconfs[OPT_SSL_PEER_CN]);
260 :
261 0 : if(!ssl_peer_cn)
262 : {
263 0 : logp("ssl_peer_cn not set.\n");
264 0 : return -1;
265 : }
266 :
267 : SSL_CIPHER_description(SSL_get_current_cipher(ssl),
268 0 : tmpbuf, sizeof(tmpbuf));
269 0 : logp("SSL is using cipher: %s\n", tmpbuf);
270 0 : if(!(peer=SSL_get_peer_certificate(ssl)))
271 : {
272 0 : logp("Could not get peer certificate.\n");
273 0 : return -1;
274 : }
275 0 : if(SSL_get_verify_result(ssl)!=X509_V_OK)
276 : {
277 0 : logp_ssl_err("Certificate doesn't verify.\n");
278 0 : return -1;
279 : }
280 :
281 : X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
282 0 : NID_commonName, tmpbuf, sizeof(tmpbuf));
283 0 : if(strcasecmp(tmpbuf, ssl_peer_cn))
284 : {
285 0 : logp("cert common name doesn't match configured ssl_peer_cn\n");
286 0 : logp("'%s'!='%s'\n", tmpbuf, ssl_peer_cn);
287 0 : return -1;
288 : }
289 :
290 : #ifndef HAVE_WIN32
291 : // Check the peer certificate against the CRL list only if set
292 : // in the configuration file. Thus if not set it is not
293 : // breaking the 'ssl_extra_checks_script' configuration.
294 0 : if(confs && ca_x509_verify_crl(confs, peer, ssl_peer_cn))
295 : return -1;
296 :
297 0 : if(setenv_x509(X509_get_subject_name(peer), "PEER")
298 0 : || setenv_x509(X509_get_issuer_name(peer), "ISSUER"))
299 : return -1;
300 :
301 0 : if(setenv_x509_date(X509_get_notBefore(peer), "X509_PEER_NOT_BEFORE")
302 0 : || setenv_x509_date(X509_get_notAfter(peer), "X509_PEER_NOT_AFTER"))
303 : return -1;
304 :
305 0 : if(setenv_x509_serialnumber(X509_get_serialNumber(peer),
306 0 : "X509_PEER_SERIALNUMBER"))
307 : return -1;
308 : #endif
309 : //if((comp=SSL_get_current_compression(ssl)))
310 : // logp("SSL is using compression: %s\n", comp->name);
311 :
312 0 : return 0;
313 : }
|