Skip to content

Breaking change doc (3.0): The "BEGIN TRUSTED CERTIFICATE" syntax is no longer supported for root certificates on Linux #17775

@bartonjs

Description

@bartonjs

The "BEGIN TRUSTED CERTIFICATE" syntax is no longer supported for root certificates on Linux

Root certificates on Linux (and other Unix-like systems, not including macOS) can be presented in two forms: the standard "BEGIN CERTIFICATE" PEM header, and the OpenSSL-specific "BEGIN TRUSTED CERTIFICATE" PEM header. The latter syntax allows for additional configuration that has shown to cause compatibility issues with .NET Core's X509Chain class, and is not loaded by the chain engine on newer versions of .NET Core.

Version introduced

.NET Core 3.0

Old behavior

Both the "BEGIN CERTIFICATE" and "BEGIN TRUSTED CERTIFICATE" syntaxes were used to populate the root trust list. If the "BEGIN TRUSTED CERTIFICATE" syntax was used, and additional options were specified in the file, X509Chain may surprisingly report that the chain trust was explicitly disallowed (X509ChainStatusFlags.ExplicitDistrust), unless the certificate was also specified with the "BEGIN CERTIFICATE" syntax via an earlier-loaded file.

New behavior

"BEGIN TRUSTED CERTIFICATE" contents are no longer read. If the certificate is not also specified via a standard "BEGIN CERTIFICATE" syntax then X509Chain will report that the root is not trusted (X509ChainStatusFlags.UntrustedRoot).

Reason for change

Incompatibilities with the X509Chain class and the X509_AUX options in "BEGIN TRUSTED CERTIFICATE" certificates leading to surprising interactions around file load ordering.

Recommended action

Many Linux distros write root certificates into two locations: a one certificate per file directory, and a one file concatenation. On some distros the one certificate per file directory uses the "BEGIN TRUSTED CERTIFICATE" syntax while the one file concatenation uses the standard "BEGIN CERTIFICATE" form. Ensure that any custom root certificates are added as "BEGIN CERTIFICATE" in at least one of these locations, and that both locations can be read by your application.

The typical directory is /etc/ssl/certs/ and the typical concatenated file is /etc/ssl/cert.pem, but the platform specific root may differ from /etc/ssl/, as reported by the command openssl version -d. For example, on Ubuntu 18.04 the directory is /usr/lib/ssl/certs/ and /usr/lib/ssl/cert.pem; though /usr/lib/ssl/certs/ is a symlink to /etc/ssl/certs/ and /usr/lib/ssl/cert.pem does not exist.

$ openssl version -d
OPENSSLDIR: "/usr/lib/ssl"
$ ls -al /usr/lib/ssl
total 12
drwxr-xr-x  3 root root 4096 Dec 12 17:10 .
drwxr-xr-x 73 root root 4096 Feb 20 15:18 ..
lrwxrwxrwx  1 root root   14 Mar 27  2018 certs -> /etc/ssl/certs
drwxr-xr-x  2 root root 4096 Dec 12 17:10 misc
lrwxrwxrwx  1 root root   20 Nov 12 16:58 openssl.cnf -> /etc/ssl/openssl.cnf
lrwxrwxrwx  1 root root   16 Mar 27  2018 private -> /etc/ssl/private

Most applications are unaffected by this change, but applications which cannot see both root certificate sources because of permissions problems may experience unexpected UntrustedRoot errors after an upgrade.

Category

CoreFx

Affected APIs

System.Security.Cryptography.X509Certificates.X509Chain


Issue metadata

  • Issue type: breaking-change

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions