--- /dev/null
+/*
+ * Copyright (c) 2006,2011,2014 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * SecTrustSettings.h - Public interface for manipulation of certificate
+ * Trust Settings.
+ */
+
+#ifndef _SECURITY_SEC_TRUST_SETTINGS_H_
+#define _SECURITY_SEC_TRUST_SETTINGS_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/cssmtype.h>
+#include <Security/SecKeychain.h>
+#include <Security/SecPolicy.h>
+#include <Security/SecCertificate.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+CF_ASSUME_NONNULL_BEGIN
+
+/*
+ * Any certificate (cert) which resides in a keychain can have associated with
+ * it a set of Trust Settings. Trust Settings specify conditions in which a
+ * given cert can be trusted or explicitly distrusted. A "trusted" cert is
+ * either a root (self-signed) cert that, when a cert chain verifies back to that
+ * root, the entire cert chain is trusted; or a non-root cert that does not need
+ * to verify to a trusted root cert (which is normally the case when verifying a
+ * cert chain). An "explicitly distrusted" cert is one which will, when encountered
+ * during the evaluation of a cert chain, cause immediate and unconditional failure
+ * of the verify operation.
+ *
+ * Trust Settings are configurable by the user; they can apply on three levels
+ * (called domains):
+ *
+ * -- Per-user.
+ * -- Locally administered, system-wide. Administrator privileges are required
+ * to make changes to this domain.
+ * -- System. These Trust Settings are immutable and comprise the set of trusted
+ * root certificates supplied in Mac OS X.
+ *
+ * Per-user Trust Settings override locally administered Trust Settings, which
+ * in turn override the System Trust Settings.
+ *
+ * Each cert's Trust Settings are expressed as a CFArray which includes any
+ * number (including zero) of CFDictionaries, each of which comprises one set of
+ * Usage Constraints. Each Usage Constraints dictionary contains zero or one of
+ * each the following components:
+ *
+ * key = kSecTrustSettingsPolicy value = SecPolicyRef
+ * key = kSecTrustSettingsApplication value = SecTrustedApplicationRef
+ * key = kSecTrustSettingsPolicyString value = CFString, policy-specific
+ * key = kSecTrustSettingsKeyUsage value = CFNumber, an SInt32 key usage
+ *
+ * A given Usage Constraints dictionary applies to a given cert if *all* of the
+ * usage constraint components specified in the dictionary match the usage of
+ * the cert being evaluated; when this occurs, the value of the
+ * kSecTrustSettingsResult entry in the dictionary, shown below, is the effective
+ * trust setting for the cert.
+ *
+ * key = kSecTrustSettingsResult value = CFNumber, an SInt32 SecTrustSettingsResult
+ *
+ * The overall Trust Settings of a given cert are the sum of all such Usage
+ * Constraints CFDictionaries: Trust Settings for a given usage apply if *any*
+ * of the CFDictionaries in the cert's Trust Settings array satisfies
+ * the specified usage. Thus, when a cert has multiple Usage Constraints
+ * dictionaries in its Trust Settings array, the overall Trust Settings
+ * for the cert are
+ *
+ * (Usage Constraint 0 component 0 AND Usage Constraint 0 component 1 ...)
+ * -- OR --
+ * (Usage Constraint 1 component 0 AND Usage Constraint 1 component 1 ...)
+ * -- OR --
+ * ...
+ *
+ * Notes on the various Usage Constraints components:
+ *
+ * kSecTrustSettingsPolicy Specifies a cert verification policy, e.g., SSL,
+ * SMIME, etc.
+ * kSecTrustSettingsApplication Specifies the application performing the cert
+ * verification.
+ * kSecTrustSettingsPolicyString Policy-specific. For the SMIME policy, this is
+ * an email address.
+ * For the SSL policy, this is a host name.
+ * kSecTrustSettingsKeyUsage A bitfield indicating key operations (sign,
+ * encrypt, etc.) for which this Usage Constraint
+ * apply. Values are defined below as the
+ * SecTrustSettingsKeyUsage enum.
+ * kSecTrustSettingsResult The resulting trust value. If not present this has a
+ * default of kSecTrustSettingsResultTrustRoot, meaning
+ * "trust this root cert". Other legal values are:
+ * kSecTrustSettingsResultTrustAsRoot : trust non-root
+ * cert as if it were a trusted root.
+ * kSecTrustSettingsResultDeny : explicitly distrust this
+ * cert.
+ * kSecTrustSettingsResultUnspecified : neither trust nor
+ * distrust; can be used to specify an "Allowed error"
+ * (see below) without assigning trust to a specific
+ * cert.
+ *
+ * Another optional component in a Usage Constraints dictionary is a CSSM_RETURN
+ * which, if encountered during certificate verification, is ignored for that
+ * cert. These "allowed error" values are constrained by Usage Constraints as
+ * described above; a Usage Constraint dictionary with no constraints but with
+ * an Allowed Error value causes that error to always be allowed when the cert
+ * is being evaluated.
+ *
+ * The "allowed error" entry in a Usage Constraints dictionary is formatted
+ * as follows:
+ *
+ * key = kSecTrustSettingsAllowedError value = CFNumber, an SInt32 CSSM_RETURN
+ *
+ * Note that if kSecTrustSettingsResult value of kSecTrustSettingsResultUnspecified
+ * is *not* present for a Usage Constraints dictionary with no Usage
+ * Constraints, the default of kSecTrustSettingsResultTrustRoot is assumed. To
+ * specify a kSecTrustSettingsAllowedError without explicitly trusting (or
+ * distrusting) the associated cert, specify kSecTrustSettingsResultUnspecified
+ * for the kSecTrustSettingsResult component.
+ *
+ * Note that an empty Trust Settings array means "always trust this cert,
+ * with a resulting kSecTrustSettingsResult of kSecTrustSettingsResultTrustRoot".
+ * An empty Trust Settings array is definitely not the same as *no* Trust
+ * Settings, which means "this cert must be verified to a known trusted cert".
+ *
+ * Note the distinction between kSecTrustSettingsResultTrustRoot and
+ * kSecTrustSettingsResultTrustAsRoot; the former can only be applied to
+ * root (self-signed) certs; the latter can only be applied to non-root
+ * certs. This also means that an empty TrustSettings array for a non-root
+ * cert is invalid, since the default value for kSecTrustSettingsResult is
+ * kSecTrustSettingsResultTrustRoot, which is invalid for a non-root cert.
+ *
+ * Authentication
+ * --------------
+ *
+ * When making changes to the per-user Trust Settings, the user will be
+ * prompted with an alert panel asking for authentication via user name a
+ * password (or other credentials normally used for login). This means
+ * that it is not possible to modify per-user Trust Settings when not
+ * running in a GUI environment (i.e. the user is not logged in via
+ * Loginwindow).
+ *
+ * When making changes to the system-wide Trust Settings, the user will be
+ * prompted with an alert panel asking for an administrator's name and
+ * password, unless the calling process is running as root in which case
+ * no futher authentication is needed.
+ */
+
+/*
+ * The keys in one Usage Constraints dictionary.
+ */
+#define kSecTrustSettingsPolicy CFSTR("kSecTrustSettingsPolicy")
+#define kSecTrustSettingsApplication CFSTR("kSecTrustSettingsApplication")
+#define kSecTrustSettingsPolicyString CFSTR("kSecTrustSettingsPolicyString")
+#define kSecTrustSettingsKeyUsage CFSTR("kSecTrustSettingsKeyUsage")
+#define kSecTrustSettingsAllowedError CFSTR("kSecTrustSettingsAllowedError")
+#define kSecTrustSettingsResult CFSTR("kSecTrustSettingsResult")
+
+/*
+ * Key usage bits, the value for Usage Constraints key kSecTrustSettingsKeyUsage.
+ */
+typedef CF_OPTIONS(uint32, SecTrustSettingsKeyUsage) {
+ /* sign/verify data */
+ kSecTrustSettingsKeyUseSignature = 0x00000001,
+ /* bulk encryption */
+ kSecTrustSettingsKeyUseEnDecryptData = 0x00000002,
+ /* key wrap/unwrap */
+ kSecTrustSettingsKeyUseEnDecryptKey = 0x00000004,
+ /* sign/verify cert */
+ kSecTrustSettingsKeyUseSignCert = 0x00000008,
+ /* sign/verify CRL and OCSP */
+ kSecTrustSettingsKeyUseSignRevocation = 0x00000010,
+ /* key exchange, e.g., Diffie-Hellman */
+ kSecTrustSettingsKeyUseKeyExchange = 0x00000020,
+ /* any usage (the default if this value is not specified) */
+ kSecTrustSettingsKeyUseAny = 0xffffffff
+};
+
+/*
+ * The effective Trust Setting result.
+ */
+typedef CF_ENUM(uint32, SecTrustSettingsResult) {
+ kSecTrustSettingsResultInvalid = 0, /* Never valid in a Trust Settings array or
+ * in an API call. */
+ kSecTrustSettingsResultTrustRoot, /* Root cert is explicitly trusted */
+ kSecTrustSettingsResultTrustAsRoot, /* Non-root cert is explicitly trusted */
+ kSecTrustSettingsResultDeny, /* Cert is explicitly distrusted */
+ kSecTrustSettingsResultUnspecified /* Neither trusted nor distrusted; evaluation
+ * proceeds as usual */
+};
+
+/*
+ * Specify user, local administrator, or system domain Trust Settings.
+ * Note that kSecTrustSettingsDomainSystem settings are read-only, even by
+ * root.
+ */
+typedef CF_ENUM(uint32, SecTrustSettingsDomain) {
+ kSecTrustSettingsDomainUser = 0,
+ kSecTrustSettingsDomainAdmin,
+ kSecTrustSettingsDomainSystem
+};
+
+/*
+ * SecCertificateRef value indicating the default Root Certificate Trust Settings
+ * for a given domain. When evaluating Trust Settings for a root cert in
+ * a given domain, *and* no matching explicit Trust Settings exists for the
+ * root cert in questions, *and* default Root Cert Trust Settings exist
+ * in that domain which matches the evaluation condition, then the
+ * SecTrustSettingsResult for that default Trust Setting (if not
+ * kSecTrustSettingsResultUnspecified) will apply.
+ *
+ * This can be used e.g. by a system administrator to explicilty distrust all
+ * of the root certs in the (immutable) system domain for a specific policy.
+ *
+ * This const is passed as the 'SecCertificateRef certRef' argument to
+ * SecTrustSettingsCopyTrustSettings(), SecTrustSettingsSetTrustSettings(),
+ * and SecTrustSettingsRemoveTrustSettings(), and
+ * SecTrustSettingsCopyModificationDate().
+ */
+#define kSecTrustSettingsDefaultRootCertSetting ((SecCertificateRef)-1)
+
+/*
+ * Obtain Trust Settings for specified cert.
+ * Caller must CFRelease() the returned CFArray.
+ * Returns errSecItemNotFound if no Trust settings exist for the cert.
+ */
+OSStatus SecTrustSettingsCopyTrustSettings(
+ SecCertificateRef certRef,
+ SecTrustSettingsDomain domain,
+ CFArrayRef * __nonnull CF_RETURNS_RETAINED trustSettings); /* RETURNED */
+
+/*
+ * Specify Trust Settings for specified cert. If specified cert
+ * already has Trust Settings in the specified domain, they will
+ * be replaced.
+ * The trustSettingsDictOrArray parameter is either a CFDictionary,
+ * a CFArray of them, or NULL. NULL indicates "always trust this
+ * root cert regardless of usage".
+ */
+OSStatus SecTrustSettingsSetTrustSettings(
+ SecCertificateRef certRef,
+ SecTrustSettingsDomain domain,
+ CFTypeRef __nullable trustSettingsDictOrArray);
+
+/*
+ * Delete Trust Settings for specified cert.
+ * Returns errSecItemNotFound if no Trust settings exist for the cert.
+ */
+OSStatus SecTrustSettingsRemoveTrustSettings(
+ SecCertificateRef certRef,
+ SecTrustSettingsDomain domain);
+
+/*
+ * Obtain an array of all certs which have Trust Settings in the
+ * specified domain. Elements in the returned certArray are
+ * SecCertificateRefs.
+ * Caller must CFRelease() the returned array.
+ * Returns errSecNoTrustSettings if no trust settings exist
+ * for the specified domain.
+ */
+OSStatus SecTrustSettingsCopyCertificates(
+ SecTrustSettingsDomain domain,
+ CFArrayRef * __nullable CF_RETURNS_RETAINED certArray);
+
+/*
+ * Obtain the time at which a specified cert's Trust Settings
+ * were last modified. Caller must CFRelease the result.
+ * Returns errSecItemNotFound if no Trust Settings exist for specified
+ * cert and domain.
+ */
+OSStatus SecTrustSettingsCopyModificationDate(
+ SecCertificateRef certRef,
+ SecTrustSettingsDomain domain,
+ CFDateRef * __nonnull CF_RETURNS_RETAINED modificationDate); /* RETURNED */
+
+/*
+ * Obtain an external, portable representation of the specified
+ * domain's TrustSettings. Caller must CFRelease the returned data.
+ * Returns errSecNoTrustSettings if no trust settings exist
+ * for the specified domain.
+ */
+OSStatus SecTrustSettingsCreateExternalRepresentation(
+ SecTrustSettingsDomain domain,
+ CFDataRef * __nonnull CF_RETURNS_RETAINED trustSettings);
+
+/*
+ * Import trust settings, obtained via SecTrustSettingsCreateExternalRepresentation,
+ * into the specified domain.
+ */
+OSStatus SecTrustSettingsImportExternalRepresentation(
+ SecTrustSettingsDomain domain,
+ CFDataRef trustSettings);
+
+CF_ASSUME_NONNULL_END
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SECURITY_SEC_TRUST_SETTINGS_H_ */
+