Skip to content

Commit

Permalink
MacOSCryptoSettings: Disable encryption if keychain entitlement is mi…
Browse files Browse the repository at this point in the history
…ssing (#9679)

* Require codesign and entitlements to enable MacOSCryptoSettings
* SecTask.h is only available on MacOS
  • Loading branch information
oskirby committed Jun 25, 2024
1 parent c34e159 commit d7d4436
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 8 deletions.
8 changes: 7 additions & 1 deletion src/platforms/macos/macoscryptosettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@ class MacOSCryptoSettings final : public CryptoSettings {

void resetKey() override;
QByteArray getKey(const QByteArray& metadata) override;
CryptoSettings::Version getSupportedVersion() override;
CryptoSettings::Version getSupportedVersion() override {
return m_keyVersion;
}

private:
static bool checkCodesign();
static bool checkEntitlement(const QString& name);

bool m_initialized = false;
CryptoSettings::Version m_keyVersion = CryptoSettings::NoEncryption;
QByteArray m_key;
QString m_appId;
};
Expand Down
75 changes: 68 additions & 7 deletions src/platforms/macos/macoscryptosettings.mm
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,23 @@
#include "logger.h"

#import <Foundation/Foundation.h>
#ifdef MZ_MACOS
# import <Security/SecTask.h>
#endif

namespace {
Logger logger("MacOSCryptoSettings");
} // namespace

MacOSCryptoSettings::MacOSCryptoSettings() : CryptoSettings() {
if (checkCodesign() && checkEntitlement("keychain-access-groups")) {
// If we are signed and have entitlements - we can use the encryption key.
m_keyVersion = CryptoSettings::EncryptionChachaPolyV1;
} else {
logger.warning() << "Disabling encryption: Codesign is invalid";
m_keyVersion = CryptoSettings::NoEncryption;
}

NSString* appId = [[NSBundle mainBundle] bundleIdentifier];
if (appId) {
m_appId = QString::fromNSString(appId);
Expand Down Expand Up @@ -106,13 +117,63 @@
return m_key;
}

CryptoSettings::Version MacOSCryptoSettings::getSupportedVersion() {
logger.debug() << "Get supported settings method";
// static
bool MacOSCryptoSettings::checkCodesign() {
#ifdef MZ_MACOS
SecTaskRef task = SecTaskCreateFromSelf(kCFAllocatorSystemDefault);
CFStringRef signer = SecTaskCopySigningIdentifier(task, nullptr);
CFRelease(task);
if (signer != nullptr) {
logger.debug() << "Got signature from:"
<< QString::fromNSString(static_cast<NSString*>(signer));
CFRelease(signer);
return true;
}
return false;
#else
// For iOS we probably need to roll our own solution by calling the
// csopt syscall directly, as the SecTask framework is only available
// for MacOS.
return true;
#endif
}

if (getKey(QByteArray()).isEmpty()) {
logger.debug() << "No encryption";
return CryptoSettings::NoEncryption;
// static
bool MacOSCryptoSettings::checkEntitlement(const QString& name) {
#ifdef MZ_MACOS
SecTaskRef task = SecTaskCreateFromSelf(kCFAllocatorSystemDefault);
if (task == nullptr) {
return false;
}
CFStringRef cfName = CFStringCreateWithCString(
kCFAllocatorSystemDefault, qUtf8Printable(name), kCFStringEncodingUTF8);
auto guard = qScopeGuard([&] {
CFRelease(task);
CFRelease(cfName);
});

CFErrorRef error = nullptr;
CFTypeRef result = SecTaskCopyValueForEntitlement(task, cfName, &error);
if (error != nullptr) {
CFStringRef desc = CFErrorCopyDescription(error);
logger.error() << "Failed to check entitlements:"
<< QString::fromNSString(static_cast<NSString*>(desc));
CFRelease(desc);
CFRelease(error);
}
if (result != nullptr) {
CFRelease(result);
}
logger.debug() << "Encryption supported!";
return CryptoSettings::EncryptionChachaPolyV1;

// Return success if we got anything back from the entitlement.
return (result != nullptr);
#else
// For iOS we probably need to roll our own solution by calling the
// csopt syscall directly, as the SecTask methods are only available
// for MacOS.
//
// Check out https://github.com/Apple-FOSS-Mirror/security_systemkeychain/
// for inspiration, specifically the procinfo() function in src/cs_misc.cpp.
return true;
#endif
}

0 comments on commit d7d4436

Please sign in to comment.