Package: bro / 2.5.5-1

0005-Disable-OCSP-features-that-can-t-yet-be-ported-to-Op.patch Patch series | download
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
From: Hilko Bengen <bengen@debian.org>
Date: Wed, 29 Nov 2017 16:36:06 +0100
Subject: Disable OCSP features that can't (yet) be ported to OpenSSL 1.1

---
 scripts/test-all-policy.bro                        |   2 +-
 src/file_analysis/analyzer/x509/functions.bif      | 289 ---------------------
 .../scripts/base/protocols/ssl/ocsp-stapling.test  |  16 --
 .../scripts/policy/protocols/ssl/validate-ocsp.bro |   2 +-
 4 files changed, 2 insertions(+), 307 deletions(-)
 delete mode 100644 testing/btest/scripts/base/protocols/ssl/ocsp-stapling.test

diff --git a/scripts/test-all-policy.bro b/scripts/test-all-policy.bro
index a022060..f3984e6 100644
--- a/scripts/test-all-policy.bro
+++ b/scripts/test-all-policy.bro
@@ -97,7 +97,7 @@
 @load protocols/ssl/log-hostcerts-only.bro
 #@load protocols/ssl/notary.bro
 @load protocols/ssl/validate-certs.bro
-@load protocols/ssl/validate-ocsp.bro
+#@load protocols/ssl/validate-ocsp.bro
 @load protocols/ssl/weak-keys.bro
 @load tuning/__load__.bro
 @load tuning/defaults/__load__.bro
diff --git a/src/file_analysis/analyzer/x509/functions.bif b/src/file_analysis/analyzer/x509/functions.bif
index f867d4f..11e4d46 100644
--- a/src/file_analysis/analyzer/x509/functions.bif
+++ b/src/file_analysis/analyzer/x509/functions.bif
@@ -106,39 +106,6 @@ STACK_OF(X509)* x509_get_untrusted_stack(VectorVal* certs_vec)
 	return untrusted_certs;
 	}
 
-// We need this function to be able to identify the signer certificate of an
-// OCSP request out of a list of possible certificates.
-X509* x509_get_ocsp_signer(STACK_OF(X509) *certs, OCSP_RESPID *rid)
-	{
-	// We support two lookup types - either by response id or by key.
-	if ( rid->type == V_OCSP_RESPID_NAME )
-		return X509_find_by_subject(certs, rid->value.byName);
-
-	// There only should be name and type - but let's be sure...
-	if ( rid->type != V_OCSP_RESPID_KEY )
-		return 0;
-
-	// Just like OpenSSL, we just support SHA-1 lookups and bail out otherwhise.
-	if ( rid->value.byKey->length != SHA_DIGEST_LENGTH )
-		return 0;
-
-	unsigned char* key_hash = rid->value.byKey->data;
-	for ( int i = 0; i < sk_X509_num(certs); ++i )
-		{
-		unsigned char digest[SHA_DIGEST_LENGTH];
-		X509* cert = sk_X509_value(certs, i);
-		if ( ! X509_pubkey_digest(cert, EVP_sha1(), digest, NULL) )
-			// digest failed for this certificate, try with next
-			continue;
-
-		if ( memcmp(digest, key_hash, SHA_DIGEST_LENGTH) == 0 )
-			// keys match, return certificate
-			return cert;
-		}
-
-	return 0;
-	}
-
 %%}
 
 ## Parses a certificate into an X509::Certificate structure.
@@ -191,262 +158,6 @@ function x509_get_certificate_string%(cert: opaque of x509, pem: bool &default=F
 	return ext_val;
 	%}
 
-## Verifies an OCSP reply.
-##
-## certs: Specifies the certificate chain to use. Server certificate first.
-##
-## ocsp_reply: the ocsp reply to validate.
-##
-## root_certs: A list of root certificates to validate the certificate chain.
-##
-## verify_time: Time for the validity check of the certificates.
-##
-## Returns: A record of type X509::Result containing the result code of the
-##          verify operation.
-##
-## .. bro:see:: x509_certificate x509_extension x509_ext_basic_constraints
-##              x509_ext_subject_alternative_name x509_parse
-##              x509_get_certificate_string x509_verify
-function x509_ocsp_verify%(certs: x509_opaque_vector, ocsp_reply: string, root_certs: table_string_of_string, verify_time: time &default=network_time()%): X509::Result
-	%{
-        stack_st_X509* ocsp_certs;
-
-	RecordVal* rval = 0;
-	X509_STORE* ctx = x509_get_root_store(root_certs->AsTableVal());
-	if ( ! ctx )
-		return x509_result_record(-1, "Problem initializing root store");
-
-
-	VectorVal *certs_vec = certs->AsVectorVal();
-	if ( certs_vec->Size() < 1 )
-		{
-		reporter->Error("No certificates given in vector");
-		return x509_result_record(-1, "no certificates");
-		}
-
-	// host certificate
-	unsigned int index = 0; // to prevent overloading to 0pointer
-	Val *sv = certs_vec->Lookup(index);
-	if ( ! sv )
-		{
-		builtin_error("undefined value in certificate vector");
-		return x509_result_record(-1, "undefined value in certificate vector");
-		}
-
-	file_analysis::X509Val* cert_handle = (file_analysis::X509Val*) sv;
-
-	X509* cert = cert_handle->GetCertificate();
-	if ( ! cert )
-		{
-		builtin_error(fmt("No certificate in opaque"));
-		return x509_result_record(-1, "No certificate in opaque");
-		}
-
-	const unsigned char* start = ocsp_reply->Bytes();
-
-	STACK_OF(X509)* untrusted_certs = x509_get_untrusted_stack(certs_vec);
-	if ( ! untrusted_certs )
-		return x509_result_record(-1, "Problem initializing list of untrusted certificates");
-
-	// from here, always goto cleanup. Initialize all other required variables...
-	time_t vtime = (time_t) verify_time;
-	OCSP_BASICRESP *basic = 0;
-	OCSP_SINGLERESP *single = 0;
-	X509_STORE_CTX *csc = 0;
-	OCSP_CERTID *certid = 0;
-	int status = -1;
-	int out = -1;
-	int result = -1;
-	X509* issuer_certificate = 0;
-	X509* signer = 0;
-	OCSP_RESPONSE *resp = d2i_OCSP_RESPONSE(NULL, &start, ocsp_reply->Len());
-	if ( ! resp )
-		{
-		rval = x509_result_record(-1, "Could not parse OCSP response");
-		goto x509_ocsp_cleanup;
-		}
-
-	status = OCSP_response_status(resp);
-	if ( status != OCSP_RESPONSE_STATUS_SUCCESSFUL )
-		{
-		rval = x509_result_record(-2, OCSP_response_status_str(status));
-		goto x509_ocsp_cleanup;
-		}
-
-	basic = OCSP_response_get1_basic(resp);
-	if ( ! basic )
-		{
-		rval = x509_result_record(-1, "Could not parse OCSP response");
-		goto x509_ocsp_cleanup;
-		}
-
-
-	// the following code took me _forever_ to get right.
-	// The OCSP_basic_verify command takes a list of certificates. However (which is not immediately
-	// visible or understandable), those are only used to find the signer certificate. They are _not_
-	// used for chain building during the actual verification (this would be stupid). But - if we sneakily
-	// inject the certificates in the certificate list of the OCSP reply, they actually are used during
-	// the lookup.
-	// Yay.
-
-	ocsp_certs = sk_X509_dup(OCSP_resp_get0_certs(basic));
-	if ( !ocsp_certs )
-		{
-		ocsp_certs = sk_X509_new_null();
-		if ( !ocsp_certs )
-			{
-			rval = x509_result_record(-1, "Could not allocate basic x509 stack");
-			goto x509_ocsp_cleanup;
-			}
-		}
-
-	issuer_certificate = 0;
-	for ( int i = 0; i < sk_X509_num(untrusted_certs); i++)
-		{
-		sk_X509_push(ocsp_certs, X509_dup(sk_X509_value(untrusted_certs, i)));
-
-		if ( X509_NAME_cmp(X509_get_issuer_name(cert), X509_get_subject_name(sk_X509_value(untrusted_certs, i))) == 0 )
-			issuer_certificate = sk_X509_value(untrusted_certs, i);
-		}
-
-	// Because we actually want to be able to give nice error messages that show why we were
-	// not able to verify the OCSP response - do our own verification logic first.
-	signer = x509_get_ocsp_signer(basic->certs, basic->tbsResponseData->responderId);
-
-	/*
-	Do this perhaps - OpenSSL also cannot do it, so I do not really feel bad about it.
-	Needs a different lookup because the root store is no stack of X509 certs
-
-	if ( !s igner )
-		// if we did not find it in the certificates that were sent, search in the root store
-		signer = x509_get_ocsp_signer(ocsp_certs, basic->tbsResponseData->responderId);
-	*/
-
-	if ( ! signer )
-		{
-		rval = x509_result_record(-1, "Could not find OCSP responder certificate");
-		goto x509_ocsp_cleanup;
-		}
-
-	csc = X509_STORE_CTX_new();
-	X509_STORE_CTX_init(csc, ctx, signer, ocsp_certs);
-	X509_STORE_CTX_set_time(csc, 0, (time_t) verify_time);
-	X509_STORE_CTX_set_purpose(csc, X509_PURPOSE_OCSP_HELPER);
-
-	result = X509_verify_cert(csc);
-	if ( result != 1 )
-		{
-		const char *reason = X509_verify_cert_error_string(X509_STORE_CTX_get_error(csc));
-		rval = x509_result_record(result, X509_verify_cert_error_string(X509_STORE_CTX_get_error(csc)));
-		goto x509_ocsp_cleanup;
-		}
-
-	// We pass OCSP_NOVERIFY to let OCSP_basic_verify skip the chain verification.
-	// With that, it only verifies the signature of the basic response and we are responsible
-	// for the chain ourselves. We have to do that since we cannot get OCSP_basic_verify to use our timestamp.
-	out = OCSP_basic_verify(basic, NULL, ctx, OCSP_NOVERIFY);
-	if ( out < 1 )
-		{
-		rval = x509_result_record(out, ERR_error_string(ERR_get_error(),NULL));
-		goto x509_ocsp_cleanup;
-		}
-
-	// ok, now we verified the OCSP response. This means that we have a valid chain tying it
-	// to a root that we trust and that the signature also hopefully is valid. This does not yet
-	// mean that the ocsp response actually matches the certificate the server send us or that
-	// the OCSP response even says that the certificate is valid.
-
-	// let's start this out by checking that the response is actually for the certificate we want
-	// to validate and not for something completely unrelated that the server is trying to trick us
-	// into accepting.
-
-	if ( issuer_certificate )
-		certid = OCSP_cert_to_id(NULL, cert, issuer_certificate);
-	else
-		{
-		// issuer not in list sent by server, check store
-		X509_OBJECT *obj = X509_OBJECT_new();
-		int lookup = X509_STORE_get_by_subject(csc, X509_LU_X509, X509_get_subject_name(cert), obj);
-		if ( lookup <= 0)
-			{
-			rval = x509_result_record(lookup, "Could not find issuer of host certificate");
-			X509_OBJECT_free(obj);
-			goto x509_ocsp_cleanup;
-			}
-
-		certid = OCSP_cert_to_id(NULL, cert,X509_OBJECT_get0_X509( obj));
-		X509_OBJECT_free(obj);
-		}
-
-
-	if ( ! certid )
-		{
-		rval = x509_result_record(-1, "Certificate ID construction failed");
-		goto x509_ocsp_cleanup;
-		}
-
-	// for now, assume we have one reply...
-	single = OCSP_resp_get0(basic, 0);
-	if ( ! single )
-		{
-		rval = x509_result_record(-1, "Could not lookup OCSP response information");
-		goto x509_ocsp_cleanup;
-		}
-
-	if ( OCSP_id_cmp(certid, (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(single)) != 0 )
-		return x509_result_record(-1, "OCSP reply is not for host certificate");
-
-	// next - check freshness of proof...
-	ASN1_GENERALIZEDTIME *thisUpdate;
-	ASN1_GENERALIZEDTIME *nextUpdate;
-	int type;
-	type = OCSP_single_get0_status(single, NULL, NULL, &thisUpdate, &nextUpdate);
-	if ( ! ASN1_GENERALIZEDTIME_check(thisUpdate) || ! ASN1_GENERALIZEDTIME_check(nextUpdate) )
-		{
-		rval = x509_result_record(-1, "OCSP reply contains invalid dates");
-		goto x509_ocsp_cleanup;
-		}
-
-	// now - nearly done. Check freshness and status code.
-	// There is a function to check the freshness of the ocsp reply in the ocsp code of OpenSSL. But - it only
-	// supports comparing it against the current time, not against arbitrary times. Hence it is kind of unusable
-	// for us...
-	// Well, we will do it manually.
-
-
-	if ( X509_cmp_time(thisUpdate, &vtime) > 0 )
-		rval = x509_result_record(-1, "OCSP reply specifies time in future");
-	else if ( X509_cmp_time(nextUpdate, &vtime) < 0 )
-		rval = x509_result_record(-1, "OCSP reply expired");
-	else if ( type != V_OCSP_CERTSTATUS_GOOD )
-		rval = x509_result_record(-1, OCSP_cert_status_str(type));
-
-	// if we have no error so far, we are done.
-	if ( !rval )
-		rval = x509_result_record(1, OCSP_cert_status_str(type));
-
-x509_ocsp_cleanup:
-
-	if ( untrusted_certs )
-		sk_X509_free(untrusted_certs);
-
-	if ( resp )
-		OCSP_RESPONSE_free(resp);
-
-	if ( basic )
-		OCSP_BASICRESP_free(basic);
-
-	if ( csc )
-		{
-		X509_STORE_CTX_cleanup(csc);
-		X509_STORE_CTX_free(csc);
-		}
-
-	if ( certid )
-		OCSP_CERTID_free(certid);
-
-	return rval;
-	%}
 
 ## Verifies a certificate.
 ##
diff --git a/testing/btest/scripts/base/protocols/ssl/ocsp-stapling.test b/testing/btest/scripts/base/protocols/ssl/ocsp-stapling.test
deleted file mode 100644
index 6424f26..0000000
--- a/testing/btest/scripts/base/protocols/ssl/ocsp-stapling.test
+++ /dev/null
@@ -1,16 +0,0 @@
-# @TEST-EXEC: bro -C -r $TRACES/tls/ocsp-stapling.trace %INPUT
-# @TEST-EXEC: btest-diff .stdout
-
-redef SSL::root_certs += {
-	["OU=Class 3 Public Primary Certification Authority,O=VeriSign\, Inc.,C=US"] = "\x30\x82\x02\x3C\x30\x82\x01\xA5\x02\x10\x70\xBA\xE4\x1D\x10\xD9\x29\x34\xB6\x38\xCA\x7B\x03\xCC\xBA\xBF\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x02\x05\x00\x30\x5F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x17\x30\x15\x06\x03\x55\x04\x0A\x13\x0E\x56\x65\x72\x69\x53\x69\x67\x6E\x2C\x20\x49\x6E\x63\x2E\x31\x37\x30\x35\x06\x03\x55\x04\x0B\x13\x2E\x43\x6C\x61\x73\x73\x20\x33\x20\x50\x75\x62\x6C\x69\x63\x20\x50\x72\x69\x6D\x61\x72\x79\x20\x43\x65\x72\x74\x69\x66\x69\x63\x61\x74\x69\x6F\x6E\x20\x41\x75\x74\x68\x6F\x72\x69\x74\x79\x30\x1E\x17\x0D\x39\x36\x30\x31\x32\x39\x30\x30\x30\x30\x30\x30\x5A\x17\x0D\x32\x38\x30\x38\x30\x31\x32\x33\x35\x39\x35\x39\x5A\x30\x5F\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x17\x30\x15\x06\x03\x55\x04\x0A\x13\x0E\x56\x65\x72\x69\x53\x69\x67\x6E\x2C\x20\x49\x6E\x63\x2E\x31\x37\x30\x35\x06\x03\x55\x04\x0B\x13\x2E\x43\x6C\x61\x73\x73\x20\x33\x20\x50\x75\x62\x6C\x69\x63\x20\x50\x72\x69\x6D\x61\x72\x79\x20\x43\x65\x72\x74\x69\x66\x69\x63\x61\x74\x69\x6F\x6E\x20\x41\x75\x74\x68\x6F\x72\x69\x74\x79\x30\x81\x9F\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x81\x8D\x00\x30\x81\x89\x02\x81\x81\x00\xC9\x5C\x59\x9E\xF2\x1B\x8A\x01\x14\xB4\x10\xDF\x04\x40\xDB\xE3\x57\xAF\x6A\x45\x40\x8F\x84\x0C\x0B\xD1\x33\xD9\xD9\x11\xCF\xEE\x02\x58\x1F\x25\xF7\x2A\xA8\x44\x05\xAA\xEC\x03\x1F\x78\x7F\x9E\x93\xB9\x9A\x00\xAA\x23\x7D\xD6\xAC\x85\xA2\x63\x45\xC7\x72\x27\xCC\xF4\x4C\xC6\x75\x71\xD2\x39\xEF\x4F\x42\xF0\x75\xDF\x0A\x90\xC6\x8E\x20\x6F\x98\x0F\xF8\xAC\x23\x5F\x70\x29\x36\xA4\xC9\x86\xE7\xB1\x9A\x20\xCB\x53\xA5\x85\xE7\x3D\xBE\x7D\x9A\xFE\x24\x45\x33\xDC\x76\x15\xED\x0F\xA2\x71\x64\x4C\x65\x2E\x81\x68\x45\xA7\x02\x03\x01\x00\x01\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x02\x05\x00\x03\x81\x81\x00\xBB\x4C\x12\x2B\xCF\x2C\x26\x00\x4F\x14\x13\xDD\xA6\xFB\xFC\x0A\x11\x84\x8C\xF3\x28\x1C\x67\x92\x2F\x7C\xB6\xC5\xFA\xDF\xF0\xE8\x95\xBC\x1D\x8F\x6C\x2C\xA8\x51\xCC\x73\xD8\xA4\xC0\x53\xF0\x4E\xD6\x26\xC0\x76\x01\x57\x81\x92\x5E\x21\xF1\xD1\xB1\xFF\xE7\xD0\x21\x58\xCD\x69\x17\xE3\x44\x1C\x9C\x19\x44\x39\x89\x5C\xDC\x9C\x00\x0F\x56\x8D\x02\x99\xED\xA2\x90\x45\x4C\xE4\xBB\x10\xA4\x3D\xF0\x32\x03\x0E\xF1\xCE\xF8\xE8\xC9\x51\x8C\xE6\x62\x9F\xE6\x9F\xC0\x7D\xB7\x72\x9C\xC9\x36\x3A\x6B\x9F\x4E\xA8\xFF\x64\x0D\x64",
-};
-
-event ssl_stapled_ocsp(c: connection, is_orig: bool, response: string)
-	{
-	local chain: vector of opaque of x509 = vector();
-	for ( i in c$ssl$cert_chain )
-		chain[i] = c$ssl$cert_chain[i]$x509$handle;
-
-	print is_orig, |response|;
-	print x509_ocsp_verify(chain, response, SSL::root_certs);
-	}
diff --git a/testing/btest/scripts/policy/protocols/ssl/validate-ocsp.bro b/testing/btest/scripts/policy/protocols/ssl/validate-ocsp.bro
index 4e53a46..ea7aea6 100644
--- a/testing/btest/scripts/policy/protocols/ssl/validate-ocsp.bro
+++ b/testing/btest/scripts/policy/protocols/ssl/validate-ocsp.bro
@@ -7,4 +7,4 @@
 # @TEST-EXEC: mv ssl.log ssl-digicert.log
 # @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-x509-names | $SCRIPTS/diff-remove-timestamps" btest-diff ssl-digicert.log
 
-@load protocols/ssl/validate-ocsp
+#@load protocols/ssl/validate-ocsp