Skip to content

Commit 937a716

Browse files
aamcommit-bot@chromium.org
authored andcommitted
[io/ssl/mac] Retain certificates used by trust certification evaluation.
This is follow-up to https://dart-review.googlesource.com/c/sdk/+/174340, which moved construction of macos certificate list from boringssl structures from worker thread back to main thread, however it seems to have resulted in certificates in certificate list being prematurely released. This cl explicitly passes/retains certificates lists to worker thread to be released after certificate trust is evaluated. Avoid using deprecated SecTrustEvaluate if running on recent versions of OS. Fixes flutter/flutter#73971 TEST=flutter/examples/image_list on mac osx 10.13.6 simulator 10.3.1 Change-Id: I36829a9b236fab2bbbe952314ce277c436ea0e10 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183620 Commit-Queue: Alexander Aprelev <[email protected]> Reviewed-by: Siva Annamalai <[email protected]>
1 parent d0725fe commit 937a716

File tree

1 file changed

+45
-24
lines changed

1 file changed

+45
-24
lines changed

runtime/bin/security_context_macos.cc

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ typedef ScopedCFType<SecPolicyRef> ScopedSecPolicyRef;
7979
typedef ScopedCFType<SecCertificateRef> ScopedSecCertificateRef;
8080
typedef ScopedCFType<SecTrustRef> ScopedSecTrustRef;
8181

82+
const int kNumTrustEvaluateRequestParams = 5;
83+
8284
static SecCertificateRef CreateSecCertificateFromX509(X509* cert) {
8385
if (cert == NULL) {
8486
return NULL;
@@ -206,11 +208,21 @@ static ssl_verify_result_t CertificateVerificationCallback(SSL* ssl,
206208
return ssl_verify_invalid;
207209
}
208210

209-
// Handler should release trust and root_cert.
211+
// TrustEvaluateHandler should release all handles.
210212
Dart_CObject dart_cobject_trust;
211213
dart_cobject_trust.type = Dart_CObject_kInt64;
212214
dart_cobject_trust.value.as_int64 =
213-
reinterpret_cast<intptr_t>(CFRetain(trust.get()));
215+
reinterpret_cast<intptr_t>(trust.release());
216+
217+
Dart_CObject dart_cobject_cert_chain;
218+
dart_cobject_cert_chain.type = Dart_CObject_kInt64;
219+
dart_cobject_cert_chain.value.as_int64 =
220+
reinterpret_cast<intptr_t>(cert_chain.release());
221+
222+
Dart_CObject dart_cobject_trusted_certs;
223+
dart_cobject_trusted_certs.type = Dart_CObject_kInt64;
224+
dart_cobject_trusted_certs.value.as_int64 =
225+
reinterpret_cast<intptr_t>(trusted_certs.release());
214226

215227
Dart_CObject dart_cobject_root_cert;
216228
dart_cobject_root_cert.type = Dart_CObject_kInt64;
@@ -222,9 +234,10 @@ static ssl_verify_result_t CertificateVerificationCallback(SSL* ssl,
222234

223235
Dart_CObject array;
224236
array.type = Dart_CObject_kArray;
225-
array.value.as_array.length = 3;
226-
Dart_CObject* values[] = {&dart_cobject_trust, &dart_cobject_root_cert,
227-
&reply_send_port};
237+
array.value.as_array.length = kNumTrustEvaluateRequestParams;
238+
Dart_CObject* values[] = {&dart_cobject_trust, &dart_cobject_cert_chain,
239+
&dart_cobject_trusted_certs,
240+
&dart_cobject_root_cert, &reply_send_port};
228241
array.value.as_array.values = values;
229242

230243
Dart_PostCObject(filter->trust_evaluate_reply_port(), &array);
@@ -265,36 +278,44 @@ static void TrustEvaluateHandler(Dart_Port dest_port_id,
265278
}
266279

267280
CObjectArray request(message);
268-
ASSERT(request.Length() == 3);
281+
if (request.Length() != kNumTrustEvaluateRequestParams) {
282+
FATAL2("Malformed trust evaluate message: got %" Pd
283+
" parameters "
284+
"expected %d\n",
285+
request.Length(), kNumTrustEvaluateRequestParams);
286+
}
269287
CObjectIntptr trust_cobject(request[0]);
270288
ScopedSecTrustRef trust(reinterpret_cast<SecTrustRef>(trust_cobject.Value()));
271-
CObjectIntptr root_cert_cobject(request[1]);
289+
CObjectIntptr cert_chain_cobject(request[1]);
290+
ScopedCFMutableArrayRef cert_chain(
291+
reinterpret_cast<CFMutableArrayRef>(cert_chain_cobject.Value()));
292+
CObjectIntptr trusted_certs_cobject(request[2]);
293+
ScopedCFMutableArrayRef trusted_certs(
294+
reinterpret_cast<CFMutableArrayRef>(trusted_certs_cobject.Value()));
295+
CObjectIntptr root_cert_cobject(request[3]);
272296
X509* root_cert = reinterpret_cast<X509*>(root_cert_cobject.Value());
273-
CObjectSendPort reply_port(request[2]);
297+
CObjectSendPort reply_port(request[4]);
274298
Dart_Port reply_port_id = reply_port.Value();
275299

276300
SecTrustResultType trust_result;
277301
if (SSLCertContext::long_ssl_cert_evaluation()) {
278302
usleep(3000 * 1000 /* 3 s*/);
279303
}
280304

305+
OSStatus status = noErr;
281306
// Perform the certificate verification.
282-
#if ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && defined(__MAC_10_14_0) && \
283-
__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_14_0) || \
284-
(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && defined(__IPHONE_12_0) && \
285-
_IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_12_0))
286-
// SecTrustEvaluateWithError available as of OSX 10.14 and iOS 12.
287-
// The result is ignored as we get more information from the following call to
288-
// SecTrustGetTrustResult which also happens to match the information we get
289-
// from calling SecTrustEvaluate.
290-
bool res = SecTrustEvaluateWithError(trust.get(), NULL);
291-
USE(res);
292-
OSStatus status = SecTrustGetTrustResult(trust.get(), &trust_result);
293-
#else
294-
295-
// SecTrustEvaluate is deprecated as of OSX 10.15 and iOS 13.
296-
OSStatus status = SecTrustEvaluate(trust.get(), &trust_result);
297-
#endif
307+
if (__builtin_available(iOS 12.0, macOS 10.14, *)) {
308+
// SecTrustEvaluateWithError available as of OSX 10.14 and iOS 12.
309+
// The result is ignored as we get more information from the following call
310+
// to SecTrustGetTrustResult which also happens to match the information we
311+
// get from calling SecTrustEvaluate.
312+
bool res = SecTrustEvaluateWithError(trust.get(), NULL);
313+
USE(res);
314+
status = SecTrustGetTrustResult(trust.get(), &trust_result);
315+
} else {
316+
// SecTrustEvaluate is deprecated as of OSX 10.15 and iOS 13.
317+
status = SecTrustEvaluate(trust.get(), &trust_result);
318+
}
298319

299320
postReply(reply_port_id,
300321
status == noErr && (trust_result == kSecTrustResultProceed ||

0 commit comments

Comments
 (0)