Certificate Trust List Check issue: well formed untrusted certificate might be considered trusted
# Description
In the certificate validation process, all certificate validation steps described in part 6 v1.05.06 are applied when a peer certificate is verified by the S2OPC server or client.
But there is an issue with the Trust List Check step, which is the last step applied, which compares the peer certificate chain for a match in the trusted certificates list. The comparison is only partial and might lead to consider there is a match with a certificate that have the same subject name and same certificate length but not the same key.
Only the first bytes corresponding to the subject length are compared instead of the bytes of the certificate length.
Note: since all other steps are applied the certificate chain of the certificate shall still be valid (but could be untrusted) and all other steps shall have succeeded.
Note 2: it concerns both implementation with MbedTLS wrapper and CycloneCyrpto wrapper.
## Code version and environment identification
Present since release 1.5.0
Present in master: b3b7f67561cd11b42460516358fe0a8ee38e7d3b
## Steps to reproduce
It is easy to reproduce with a trusted self-signed certificate:
1. Create a self-signed certificate with a new key
2. Create a second one with same configuration (subject shall be the same and total length also) and a new key, and force the same Serial value in it than the one in 1.
3. Add 1. to the trusted certificates of the server PKI
4. Use 2. to connect to the server successfully whereas this attacker certificate is actually not trusted
E.g.: attacker key password is "test":
[client_self_signed_attacker.der](/uploads/9e95c1aa3fc11d9cb201b372e3a336a8/client_self_signed_attacker.der)
[client_self_signed_attacker_key.pem](/uploads/5f119e8bd7941fb1fb751e0b6b22b9a3/client_self_signed_attacker_key.pem)
[client_self_signed_origin.der](/uploads/edf40fd33366df8f6d240ddb1db1c2a3/client_self_signed_origin.der)
Note 1: with a shorter subject content it is possible to have less fields identical (Serial, issuer, ...)
Note 2: it should be possible to match a trusted CA too with the same mechanism but it is harder to reproduce as the certificate length should be the same.
## Relevant logs and/or screenshots
(Paste any relevant logs - use code blocks (```) to format console output, logs, and code, as
it's very hard to read otherwise.)
# Analysis
Comparison code is incorrect (several instances in mbedtls and cyclone wrappers):
Fix for MbedTLS:
```diff
if (crt->subject_raw.len == crtTrusted->subject_raw.len && crt->raw.len == crtTrusted->raw.len &&
0 == memcmp(crt->subject_raw.p, crtTrusted->subject_raw.p, crt->subject_raw.len) &&
- 0 == memcmp(crt->raw.p, crtTrusted->raw.p, crt->subject_raw.len))
+ 0 == memcmp(crt->raw.p, crtTrusted->raw.p, crt->raw.len))
```
The incorrect length was used to compare certificates.
It leaded to compare only the start of the X509 certificate, thus having similar content for this first part should be sufficient (depending on subject length of the trusted certificate to mimic):
```
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
71:78:8e:77:4b:49:17:0e:9f:08:97:28:6f:c8:90:aa:1d:b6:90:67
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = FR, ST = France, O = Systerel, CN = S2OPC Demo Certificate Self-signed Authority for Tests, emailAddress = s2opc-support@systerel.fr, L = Aix-en-Provence
Validity
Not Before: May 18 16:11:47 2026 GMT
Not After : May 17 16:11:47 2027 GMT
```
# Security impact
Any certificate that passes the validation steps (except Trust List Check) and that have the same first bytes than a trusted certificate in the PKI for the length of the subject is considered trusted whereas it might not. Therefore an attacker might be able to forge a valid untrusted certificate that is finally consider trusted.
Also see the created [CVE-2026-9758](https://www.cve.org/CVERecord?id=CVE-2026-9758).
# Possible fixes
Fix the incorrect comparisons in the code.
issue