Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(297)

Unified Diff: runtime/bin/security_context_macos.cc

Issue 2903743002: Porting SecureSocket to use BoringSSL on OSX (Closed)
Patch Set: Addressed nits, confirmed change works on Windows Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/security_context_linux.cc ('k') | runtime/bin/security_context_win.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/security_context_macos.cc
diff --git a/runtime/bin/security_context_macos.cc b/runtime/bin/security_context_macos.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3ae88f7458bf8bc8fcad900deaf5efebd19585c8
--- /dev/null
+++ b/runtime/bin/security_context_macos.cc
@@ -0,0 +1,191 @@
+// Copyright (c) 2017 the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED)
+
+#include "platform/globals.h"
+#if defined(HOST_OS_MACOS)
+
+#include "bin/security_context.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/SecureTransport.h>
+#include <Security/Security.h>
+
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+
+#include "bin/secure_socket_filter.h"
+
+namespace dart {
+namespace bin {
+
+const intptr_t SSLCertContext::kApproximateSize = sizeof(SSLCertContext);
+
+const char* commandline_root_certs_file = NULL;
+const char* commandline_root_certs_cache = NULL;
+
+template <typename T>
+class ScopedCFType {
+ public:
+ explicit ScopedCFType(T obj) : obj_(obj) {}
+
+ ~ScopedCFType() { CFRelease(obj_); }
+
+ T get() { return obj_; }
+ T* ptr() { return &obj_; }
+ const T get() const { return obj_; }
+
+ void set(T obj) { obj_ = obj; }
+
+ private:
+ T obj_;
+
+ DISALLOW_ALLOCATION();
+ DISALLOW_COPY_AND_ASSIGN(ScopedCFType);
+};
+
+typedef ScopedCFType<CFMutableArrayRef> ScopedCFMutableArrayRef;
+typedef ScopedCFType<CFDataRef> ScopedCFDataRef;
+typedef ScopedCFType<SecPolicyRef> ScopedSecPolicyRef;
+typedef ScopedCFType<SecCertificateRef> ScopedSecCertificateRef;
+typedef ScopedCFType<SecTrustRef> ScopedSecTrustRef;
+
+static SecCertificateRef CreateSecCertificateFromX509(X509* cert) {
+ if (cert == NULL) {
+ return NULL;
+ }
+ unsigned char* deb_cert = NULL;
+ int length = i2d_X509(cert, &deb_cert);
+ if (length < 0) {
+ return 0;
+ }
+ ASSERT(deb_cert != NULL);
+ ScopedCFDataRef cert_buf(
+ CFDataCreateWithBytesNoCopy(NULL, deb_cert, length, kCFAllocatorNull));
+ SecCertificateRef auth_cert =
+ SecCertificateCreateWithData(NULL, cert_buf.get());
+ if (auth_cert == NULL) {
+ return NULL;
+ }
+ return auth_cert;
+}
+
+
+static int CertificateVerificationCallback(X509_STORE_CTX* ctx, void* arg) {
+ SSLCertContext* context = static_cast<SSLCertContext*>(arg);
+
+ // Convert BoringSSL formatted certificates to SecCertificate certificates.
+ ScopedCFMutableArrayRef cert_chain(NULL);
+ X509* root_cert = NULL;
+ if (ctx->untrusted != NULL) {
+ STACK_OF(X509)* user_provided_certs = ctx->untrusted;
+ int num_certs = sk_X509_num(user_provided_certs);
+ int current_cert = 0;
+ cert_chain.set(CFArrayCreateMutable(NULL, num_certs, NULL));
+ X509* ca;
+ while ((ca = sk_X509_shift(user_provided_certs)) != NULL) {
+ SecCertificateRef cert = CreateSecCertificateFromX509(ca);
+ if (cert == NULL) {
+ return ctx->verify_cb(0, ctx);
+ }
+ CFArrayAppendValue(cert_chain.get(), cert);
+ ++current_cert;
+
+ if (current_cert == num_certs) {
+ root_cert = ca;
+ }
+ }
+ }
+
+ // Convert all trusted certificates provided by the user via
+ // setTrustedCertificatesBytes or the command line into SecCertificates.
+ ScopedCFMutableArrayRef trusted_certs(CFArrayCreateMutable(NULL, 0, NULL));
+ X509_STORE* store = ctx->ctx;
+ ASSERT(store != NULL);
+
+ if (store->objs != NULL) {
+ for (uintptr_t i = 0; i < sk_X509_OBJECT_num(store->objs); ++i) {
+ X509* ca = sk_X509_OBJECT_value(store->objs, i)->data.x509;
+ SecCertificateRef cert = CreateSecCertificateFromX509(ca);
+ if (cert == NULL) {
+ return ctx->verify_cb(0, ctx);
+ }
+ CFArrayAppendValue(trusted_certs.get(), cert);
+ }
+ }
+
+ // Generate a generic X509 verification policy.
+ ScopedSecPolicyRef policy(SecPolicyCreateBasicX509());
+
+ // Create the trust object with the certificates provided by the user.
+ ScopedSecTrustRef trust(NULL);
+ OSStatus status = SecTrustCreateWithCertificates(cert_chain.get(),
+ policy.get(), trust.ptr());
+ if (status != noErr) {
+ return ctx->verify_cb(0, ctx);
+ }
+
+ // If the user provided any additional CA certificates, add them to the trust
+ // object.
+ if (CFArrayGetCount(trusted_certs.get()) > 0) {
+ status = SecTrustSetAnchorCertificates(trust.get(), trusted_certs.get());
+ if (status != noErr) {
+ return ctx->verify_cb(0, ctx);
+ }
+ }
+
+ // Specify whether or not to use the built-in CA certificates for
+ // verification.
+ status =
+ SecTrustSetAnchorCertificatesOnly(trust.get(), !context->trust_builtin());
+ if (status != noErr) {
+ return ctx->verify_cb(0, ctx);
+ }
+
+ // Perform the certificate verification.
+ SecTrustResultType trust_result;
+ status = SecTrustEvaluate(trust.get(), &trust_result);
+ if (status != noErr) {
+ return ctx->verify_cb(0, ctx);
+ }
+
+ if ((trust_result == kSecTrustResultProceed) ||
+ (trust_result == kSecTrustResultUnspecified)) {
+ // Successfully verified certificate!
+ return ctx->verify_cb(1, ctx);
+ }
+
+ // Set current_cert to the root of the certificate chain. This will be passed
+ // to the callback provided by the user for additional verification steps.
+ ctx->current_cert = root_cert;
+ return ctx->verify_cb(0, ctx);
+}
+
+
+void SSLCertContext::RegisterCallbacks(SSL* ssl) {
+ SSL_CTX* ctx = SSL_get_SSL_CTX(ssl);
+ SSL_CTX_set_cert_verify_callback(ctx, CertificateVerificationCallback, this);
+}
+
+
+void SSLCertContext::TrustBuiltinRoots() {
+ // First, try to use locations specified on the command line.
+ if (commandline_root_certs_file != NULL) {
+ LoadRootCertFile(commandline_root_certs_file);
+ return;
+ }
+ if (commandline_root_certs_cache != NULL) {
+ LoadRootCertCache(commandline_root_certs_cache);
+ return;
+ }
+ set_trust_builtin(true);
+}
+
+} // namespace bin
+} // namespace dart
+
+#endif // defined(HOST_OS_MACOS)
+#endif // !defined(DART_IO_DISABLED) &&
+ // !defined(DART_IO_SECURE_SOCKET_DISABLED)
« no previous file with comments | « runtime/bin/security_context_linux.cc ('k') | runtime/bin/security_context_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698