From bd2f257fff623f67fbb6a424f640ed36b231a929 Mon Sep 17 00:00:00 2001 From: Mikkel Krautz Date: Sun, 3 Oct 2010 19:28:59 +0200 Subject: [PATCH] Bundle intermediate CAs for the overlay installer to make Mac OS X 10.5 play along nicely. --- macx/overlay-installer/intermediate.h | 41 ++++++++++++++++ src/mumble/Overlay_macx.mm | 70 +++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 macx/overlay-installer/intermediate.h diff --git a/macx/overlay-installer/intermediate.h b/macx/overlay-installer/intermediate.h new file mode 100644 index 000000000..19b0e2ed8 --- /dev/null +++ b/macx/overlay-installer/intermediate.h @@ -0,0 +1,41 @@ +static const char *intermediate_cas[] = { + /* StartCom Class 2 Primary Intermediate Object CA */ + "-----BEGIN CERTIFICATE-----\n" + "MIIGcDCCBFigAwIBAgIBJDANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW\n" + "MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg\n" + "Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh\n" + "dGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjIwMTQ2WhcNMTcxMDI0MjIwMTQ2WjCB\n" + "jDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsT\n" + "IlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNVBAMTL1N0\n" + "YXJ0Q29tIENsYXNzIDIgUHJpbWFyeSBJbnRlcm1lZGlhdGUgT2JqZWN0IENBMIIB\n" + "IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyiOLIjUemqAbPJ1J0D8MlzgW\n" + "Kbr4fYlbRVjvhHDtfhFN6RQxq0PjTQxRgWzwFQNKJCdU5ftKoM5N4YSjId6ZNavc\n" + "Sa6/McVnhDAQm+8H3HWoD030NVOxbjgD/Ih3HaV3/z9159nnvyxQEckRZfpJB2Kf\n" + "k6aHqW3JnSvRe+XVZSufDVCe/vtxGSEwKCaNrsLc9pboUoYIC3oyzWoUTZ65+c0H\n" + "4paR8c8eK/mC914mBo6N0dQ512/bkSdaeY9YaQpGtW/h/W/FkbQRT3sCpttLVlIj\n" + "nkuY4r9+zvqhToPjxcfDYEf+XD8VGkAqle8Aa8hQ+M1qGdQjAye8OzbVuUOw7wID\n" + "AQABo4IB6TCCAeUwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD\n" + "VR0OBBYEFNBOD0CZbLhLGW87KLjg44gHNKq3MB8GA1UdIwQYMBaAFE4L7xqkQFul\n" + "F2mHMMo0aEPQQa7yMD0GCCsGAQUFBwEBBDEwLzAtBggrBgEFBQcwAoYhaHR0cDov\n" + "L3d3dy5zdGFydHNzbC5jb20vc2ZzY2EuY3J0MFsGA1UdHwRUMFIwJ6AloCOGIWh0\n" + "dHA6Ly93d3cuc3RhcnRzc2wuY29tL3Nmc2NhLmNybDAnoCWgI4YhaHR0cDovL2Ny\n" + "bC5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMIGABgNVHSAEeTB3MHUGCysGAQQBgbU3\n" + "AQIBMGYwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGlj\n" + "eS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVy\n" + "bWVkaWF0ZS5wZGYwEQYJYIZIAYb4QgEBBAQDAgABMFAGCWCGSAGG+EIBDQRDFkFT\n" + "dGFydENvbSBDbGFzcyAyIFByaW1hcnkgSW50ZXJtZWRpYXRlIE9iamVjdCBTaWdu\n" + "aW5nIENlcnRpZmljYXRlczANBgkqhkiG9w0BAQUFAAOCAgEAcnMLA3VaN4OIE9l4\n" + "QT5OEtZy5PByBit3oHiqQpgVEQo7DHRsjXD5H/IyTivpMikaaeRxIv95baRd4hoU\n" + "cMwDj4JIjC3WA9FoNFV31SMljEZa66G8RQECdMSSufgfDYu1XQ+cUKxhD3EtLGGc\n" + "FGjjML7EQv2Iol741rEsycXwIXcryxeiMbU2TPi7X3elbwQMc4JFlJ4By9FhBzuZ\n" + "B1DV2sN2irGVbC3G/1+S2doPDjL1CaElwRa/T0qkq2vvPxUgryAoCppUFKViw5yo\n" + "GYC+z1GaesWWiP1eFKAL0wI7IgSvLzU3y1Vp7vsYaxOVBqZtebFTWRHtXjCsFrrQ\n" + "Bngt0d33QbQRI5mwgzEp7XJ9xu5d6RVWM4TPRUsd+DDZpBHm9mszvi9gVFb2ZG7q\n" + "RRXCSqys4+u/NLBPbXi/m/lU00cODQTlC/euwjk9HQtRrXQ/zqsBJS6UJ+eLGw1q\n" + "Ofj+HVBl/ZQpfoLk7IoWlRQvRL1s7oirEaqPZUIWY/grXq9r6jDKAp3LZdKQpPOn\n" + "nogtqlU4f7/kLjEJhrrc98mrOWmVMK/BuFRAfQ5oDUMnVmCzAzLMjKfGcVW/iMew\n" + "41yfhgKbwpfzm3LBr1Zv+pEBgcgW6onRLSAn3XHM0eNtz+AkxH6rRf6B2mYhLEEG\n" + "LapH8R1AMAo4BbVFOZR5kXcMCwo=\n" + "-----END CERTIFICATE-----\n" + , +}; diff --git a/src/mumble/Overlay_macx.mm b/src/mumble/Overlay_macx.mm index 6e9037eae..583784d8d 100644 --- a/src/mumble/Overlay_macx.mm +++ b/src/mumble/Overlay_macx.mm @@ -40,6 +40,12 @@ extern "C" { #include } +// This is a temporary solution. We don't want the list of our trusted +// intermediate certificates to be tampered with, and the easiest way +// to achieve that is to embed them into the binary (since it gets +// codesigned.) +#include "../../macx/overlay-installer/intermediate.h" + static const NSString *MumbleOverlayLoaderBundle = @"/Library/ScriptingAdditions/MumbleOverlay.osax"; static const NSString *MumbleOverlayLoaderBundleIdentifier = @"net.sourceforge.mumble.OverlayScriptingAddition"; @@ -505,12 +511,51 @@ err: return ret; } +// Get an NSArray of the system anchors + our bundled intermediate certs. +static bool getAnchorCerts(NSArray **anchors) { + bool ret = false; + OSStatus err = noErr; + CFArrayRef systemAnchors = NULL; + + if (anchors == NULL) { + qWarning("getAnchorCerts: Invalid argument."); + goto err; + } + + err = SecTrustCopyAnchorCertificates(&systemAnchors); + if (err != noErr) { + qWarning("Unable to copy system anchor certificates"); + goto err; + } + + *anchors = [[NSMutableArray alloc] initWithArray:(NSArray *)systemAnchors]; + for (int i = 0; i < sizeof(intermediate_cas)/sizeof(intermediate_cas[0]); i++) { + QSslCertificate cert(intermediate_cas[i]); + QByteArray qbaIntermediate = cert.toDer(); + + SecCertificateRef tmp = NULL; + const CSSM_DATA crt = { (CSSM_SIZE) qbaIntermediate.length(), (uint8_t *) qbaIntermediate.constData() }; + err = SecCertificateCreateFromData(&crt, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &tmp); + if (err != noErr) { + qWarning("getAnchorCerts: Couldn't SecCertificateCreateFromData(). Skipping."); + continue; + } + + [(NSMutableArray *) *anchors addObject:(id)tmp]; + } + + ret = true; +err: + return ret; +} + // First, validate the signature of the installer XAR archive. Then, check // that the certificate chain is trusted by the system. bool validateInstaller(const char *path) { bool ret = false; OSStatus err = noErr; NSArray *certs = nil; + NSArray *anchors = nil; SecPolicySearchRef search = NULL; SecPolicyRef policy = NULL; SecTrustRef trust = NULL; @@ -546,6 +591,30 @@ bool validateInstaller(const char *path) { goto err; } + if (QSysInfo::MacintoshVersion < QSysInfo::MV_SNOWLEOPARD) { + qWarning("validateInstaller: Non-Snow Leopard install detected. Including bundled intermediate certificates when " + "verifying installer."); + + // Get system anchors with our bundled intermediate certificates included. + if (! getAnchorCerts(&anchors)) { + qWarning("validateInstaller: Unable to fetch anchors."); + goto err; + } + + // Set the anchors for the trust object + // + // Note: By doing this, we're actually circumventing the user trust settings for the system anchors. + // + // There's only really a way around this for Snow Leopard, where a `SecTrustSetAnchorCertificatesOnly' + // function was introduced. With this, you can trust the anchor certificates set for the trust object + // AND trust the system anchors using the user's *own* trust settings for them. + err = SecTrustSetAnchorCertificates(trust, (CFArrayRef)anchors); + if (err != noErr) { + qWarning("validateInstaller: Unable to set bundled anchor certificates."); + goto err; + } + } + // Do we trust this certificate? err = SecTrustEvaluate(trust, &result); if (err != noErr) { @@ -569,6 +638,7 @@ bool validateInstaller(const char *path) { err: [certs release]; + [anchors release]; if (search) CFRelease(search); if (policy)