-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Windows Dart 2.14.0-93-dev and later.
The majority of this issue was discussed in the pub
repo at dart-lang/pub#2990 and it appears to be an issue with dart
.
A recent change to the runtime made all certificate stores on Windows accessible to dart
. I am in an environment with an internal CA that issues certificates to the proxy servers. When the root certificates for a site are not known to the proxy, it uses the internal certificates for the communication between the workstation and the proxy. The internal certificates are regularly pushed to the workstations to prevent invalid certificate errors.
The issue is that the expired certificates remain in the store and dart
is attempting to use them. The runtime appears to be using the first certificate it encounters. If it is invalid for any reason, it throws an exception and moves on. This happens even when it does find a valid certificate.
import 'dart:io';
void main(List<String> arguments) {
var client = HttpClient();
client.badCertificateCallback = (cert, host, port) {
print('Bad certificate connecting to $host:$port:');
_printCertificate(cert);
print('');
return true;
};
client
.getUrl(Uri.parse('https://pub.dartlang.org/api/packages/pedantic'))
.then((request) => request.close())
.then((response) {
print('Response certificate:');
_printCertificate(response.certificate);
response.drain();
client.close();
});
}
void _printCertificate(X509Certificate? cert) {
if (cert != null) {
print('${cert.issuer}');
print('${cert.subject}');
print('${cert.startValidity}');
print('${cert.endValidity}');
} else {
print('Certificate is null');
}
}
Running this code produces this result. (I had to mask some of the names with XXX due to policy.)
Bad certificate connecting to pub.dartlang.org:443:
/C=XXX/O=XXX/OU=XXX/OU=WCF PKI/CN=XXX WCF Intermediate CA 1
/C=XXX/O=XXX/OU=XXX/OU=WCF PKI/CN=XXX WCF Signing CA 4
2020-01-06 17:59:49.000Z
2020-07-06 17:59:49.000Z
Bad certificate connecting to pub.dartlang.org:443:
/C=XXX/O=XXX/OU=XXX/OU=WCF PKI/CN=XXX WCF Signing CA 4
/CN=pub.dartlang.org
2021-05-04 01:59:01.000Z
2021-07-10 14:07:57.000Z
Response certificate:
/C=XXX/O=XXX/OU=XXX/OU=WCF PKI/CN=XXX WCF Signing CA 4
/CN=pub.dartlang.org
2021-05-04 01:59:01.000Z
2021-07-10 14:07:57.000Z
The first certificate displayed is expired but the second one is not. I have tried this URL in the browser and the valid certificate here is the one being used.
This issue can be replicated using the --root-certs-file
option for dart
. I used a hand crafted certificate bundle that removed all expired certificates and this code worked. I tried using it with pub
and was getting local issuer certificate errors because I did not have the time to hand craft a certificate bundle that included 100+ items from my environment.