public static boolean isTrustedRoot()

in src/main/java/org/jetbrains/nativecerts/mac/SecurityFrameworkUtil.java [237:366]


    public static boolean isTrustedRoot(SecurityFramework.SecCertificateRef certificateRef) {
        boolean selfSignedCertificate = isSelfSignedCertificate(getX509Certificate(certificateRef));

        CFArrayRefByReference trustedSettingsRef = copyTrustSettings(certificateRef);
        CoreFoundation.CFArrayRef trustedSettingsArray = trustedSettingsRef == null ? null : trustedSettingsRef.getArray();

        try {
            String certificateDescription = CoreFoundationExtUtil.getDescription(certificateRef);

            if (trustedSettingsArray == null) {
                // Trust record is null we need to verify the certificate first
                CoreFoundationExt.Error error = validateCertificate(certificateRef);
                if (error == null) {
                    return true;
                } else {
                    LOGGER.fine("Certificate '" + certificateDescription + "' has no trust settings and failed to validate against trusted roots: " + error);
                    return false;
                }
            }

            if (LOGGER.isLoggable(Level.FINE)) {
                try {
                    String description = CoreFoundationExtUtil.getDescription(trustedSettingsArray);
                    LOGGER.fine("Certificate '" + certificateDescription + "' trust settings:\n" + description);
                } catch (Throwable t) {
                    LOGGER.warning(renderExceptionMessage("Unable to describe certificate trusted settings", t));
                }
            }

            if (trustedSettingsArray.getCount() == 0) {
                // https://developer.apple.com/documentation/security/1400261-sectrustsettingscopytrustsetting
                // An empty trust settings array (that is, the trustSettings parameter returns a valid but empty CFArray) means "always trust this certificate" with an overall trust setting for the certificate of kSecTrustSettingsResultTrustRoot
                return true;
            }

            for (int i = 0; i < trustedSettingsArray.getCount(); i++) {
                CoreFoundation.CFDictionaryRef constraints = new CoreFoundation.CFDictionaryRef(trustedSettingsArray.getValueAtIndex(i));
                CoreFoundation.CFIndex constraintsCount = CoreFoundationExt.INSTANCE.CFDictionaryGetCount(constraints);
                int processedConstrains = 0;

                // kSecTrustSettingsResult
                {
                    Pointer value = constraints.getValue(SecurityFramework.kSecTrustSettingsResult);

                    // from https://developer.apple.com/documentation/security/1400261-sectrustsettingscopytrustsetting
                    // If this key is not present, a default value of kSecTrustSettingsResultTrustRoot is assumed. Because only a root certificate can have this value, a usage constraints dictionary for a non-root certificate that is missing this key is not valid.
                    // Note the distinction between the results kSecTrustSettingsResultTrustRoot and kSecTrustSettingsResultTrustAsRoot: The former can only be applied to a root (self-signed) certificates; the latter can only be applied to non-root certificates. Therefore, an empty trust settings array for a non-root certificate is invalid, because the default value of kSecTrustSettingsResultTrustRoot is not valid for a non-root certificate.

                    SecurityFramework.SecTrustSettingsResult result;
                    if (value == null) {
                        result = SecurityFramework.SecTrustSettingsResult.kSecTrustSettingsResultTrustRoot;
                    } else {
                        CoreFoundation.CFNumberRef resultNumber = new CoreFoundation.CFNumberRef(value);
                        result = new SecurityFramework.SecTrustSettingsResult(resultNumber.longValue());
                        processedConstrains++;
                    }

                    // Return only trust roots. Skip even SecurityFramework.SecTrustSettingsResult.kSecTrustSettingsResultTrustAsRoot for now
                    if (!result.equals(SecurityFramework.SecTrustSettingsResult.kSecTrustSettingsResultTrustRoot)) {
                        continue;
                    }

                    // trust roots must be self-signed, see above
                    if (!selfSignedCertificate) {
                        LOGGER.warning("Certificate '" + certificateDescription + "' is not self-signed, skipping");
                        continue;
                    }
                }

                // kSecTrustSettingsAllowedError
                {
                    // Skip kSecTrustSettingsAllowedError processing
                    // Documentation says "A number which, if encountered during certificate verification, is ignored for that certificate."
                    // We would not ignore anything, so skip for now
                    if (constraints.getValue(SecurityFramework.kSecTrustSettingsAllowedError) != null) {
                        processedConstrains++;
                    }
                }

                // kSecTrustSettingsPolicyName
                {
                    // Skip kSecTrustSettingsPolicyName, it does not matter for processing
                    if (constraints.getValue(SecurityFramework.kSecTrustSettingsPolicyName) != null) {
                        processedConstrains++;
                    }
                }

                // kSecTrustSettingsPolicy
                {
                    Pointer value = constraints.getValue(SecurityFramework.kSecTrustSettingsPolicy);
                    if (value != null) {
                        SecurityFramework.SecPolicyRef secPolicyRef = new SecurityFramework.SecPolicyRef(value);

                        CoreFoundation.CFDictionaryRef policyDictionaryRef = SecurityFramework.INSTANCE.SecPolicyCopyProperties(secPolicyRef);
                        try {
                            Pointer policyOid = policyDictionaryRef.getValue(SecurityFramework.kSecPolicyOid);
                            if (policyOid == null) {
                                // Must be present, so it's an invalid policy
                                continue;
                            }

                            CoreFoundation.CFStringRef policyOidStringRef = new CoreFoundation.CFStringRef(policyOid);
                            if (!CoreFoundationExt.INSTANCE.CFEqual(SecurityFramework.kSecPolicyAppleSSL, policyOidStringRef)) {
                                // Accept only kSecPolicyAppleSSL policy
                                continue;
                            }
                        } finally {
                            policyDictionaryRef.release();
                        }

                        processedConstrains++;
                    }
                }

                if (constraintsCount.longValue() == processedConstrains) {
                    // return only certificates with known and checked constraints attached to them
                    // this way we'll probably miss some valid trusted roots, but
                    // there is no way to evaluate other and possibly unknown constraints
                    return true;
                }
            }

            // No matched constraints => not a trusted root
            return false;
        } finally {
            if (trustedSettingsArray != null) {
                trustedSettingsArray.release();
            }
        }
    }