macOS rejects certificate with non-ciritical unknown extension

In our macOS daemon process, we are trying to validate a leaf certificate by anchoring intermediate CA cert and evaluating it using SecTrustEvaluateWithError. The leaf certificate contains couple of non-critical MS extensions (1.3.6.1.4.1.311.21.10 and 1.3.6.1.4.1.311.21.7). The macOS API fails to parse these extensions and does not evaluate the cert chain. Below is the error returned:

 {
    NSLocalizedDescription = "\U201abc\U201d certificate is not standards compliant";
    NSUnderlyingError = "Error Domain=NSOSStatusErrorDomain Code=-67618 \"Certificate 0 \U201abc\U201d has errors: Unable to parse known extension;\" UserInfo={NSLocalizedDescription=Certificate 0 \U201abc\U201d has errors: Unable to parse known extension;}";
}

As per RFC2459, a non-critical extension can be ignored by the system:

A certificate using system MUST reject the certificate if it encounters a critical extension it does not recognize; however, a non-critical extension may be ignored if it is not recognized.

So, why does macOS not ignore these non-critical extension and returns a failure? OS version is 14.4.1.

Answered by DTS Engineer in 795767022

[For those reading along at home, dispacthMain isn’t able to share the certs publicly, and so they sent me a copy via an alternative channel.]

I’m not 100% sure of this conclusion, but I think the actual issue is this:

type: default
time: 2024-07-17 15:40:18.701654 +0100
process: trustd
subsystem: com.apple.securityd
category: SecWarning
message: Invalid SubjectAltName Extension

Consider this dump of the leaf:

% dumpasn1 -p -a /Users/quinn/Test/leaf.cer 
SEQUENCE {
  SEQUENCE {
    [0] {…}
    INTEGER …
    SEQUENCE {…}
    SEQUENCE {…}
    SEQUENCE {
      UTCTime 01/04/2024 16:54:46 GMT
      UTCTime 01/04/2025 16:54:46 GMT
      }
    SEQUENCE {…}
    SEQUENCE {…}
    [3] {
      SEQUENCE {
        SEQUENCE {
          OBJECT IDENTIFIER subjectAltName (2 5 29 17)
          OCTET STRING, encapsulates {
            SEQUENCE {}
            }
          }
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        }
      }
    }
  SEQUENCE {…}
  BIT STRING
    …
  }

Note how the subjectAltName extension is empty. RFC 5280 is pretty darned clear on that point:

If the subjectAltName extension is present, the sequence MUST contain at least one entry.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I don’t think that quote from RFC 2459 applies here because the certificate parser does recognise the extension. Hence the “known” in the “Unable to parse known extension” error.

And that’s born out by the fact that you were able to create a certificate object (SecCertificate) at all. If this were a critical extension then the certificate parser would have failed completely, so you would never have to go to the trust object stage.

Looking in Darwin, I think this message is being triggered by this line of code.

In terms of standards, my read is the section 4.2 of RFC 5280 applies, which says:

A non-critical extension MAY be ignored if it is not recognized, but MUST be processed if it is recognized.

Specifically, I’d say that in this quote the “recognized” applies to the extension OID, not to the contents of the extension.


Regardless, I’m not 100% sure that whatever failure you’re seeing is tied to those specific OIDs. Can you post an example certificate that’s failing the trust evaluation? [1]

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] You can either post a link in the clear (see tip 14 in Quinn’s Top Ten DevForums Tips) or post a hex dump within a code block (triple backquotes).

Accepted Answer

[For those reading along at home, dispacthMain isn’t able to share the certs publicly, and so they sent me a copy via an alternative channel.]

I’m not 100% sure of this conclusion, but I think the actual issue is this:

type: default
time: 2024-07-17 15:40:18.701654 +0100
process: trustd
subsystem: com.apple.securityd
category: SecWarning
message: Invalid SubjectAltName Extension

Consider this dump of the leaf:

% dumpasn1 -p -a /Users/quinn/Test/leaf.cer 
SEQUENCE {
  SEQUENCE {
    [0] {…}
    INTEGER …
    SEQUENCE {…}
    SEQUENCE {…}
    SEQUENCE {
      UTCTime 01/04/2024 16:54:46 GMT
      UTCTime 01/04/2025 16:54:46 GMT
      }
    SEQUENCE {…}
    SEQUENCE {…}
    [3] {
      SEQUENCE {
        SEQUENCE {
          OBJECT IDENTIFIER subjectAltName (2 5 29 17)
          OCTET STRING, encapsulates {
            SEQUENCE {}
            }
          }
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        SEQUENCE {…}
        }
      }
    }
  SEQUENCE {…}
  BIT STRING
    …
  }

Note how the subjectAltName extension is empty. RFC 5280 is pretty darned clear on that point:

If the subjectAltName extension is present, the sequence MUST contain at least one entry.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you for your help Quinn. It would be great if Security APIs could also mention the extension causing the failure, in error message. Unable to parse known extension; is not very clear error, IMO.

It would be great if Security APIs could also mention the extension causing the failure

I can’t disagree with that (-:

To get this suggestion in front of the folks who have the power to make that change, put it in an enhancement request. Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

macOS rejects certificate with non-ciritical unknown extension
 
 
Q