Alpine Linux contains now expired DST Root CA X3 certificate:
$ docker run --rm alpine:3.8 sh -euxc '
grep "### Digital Signature Trust Co." -A 21 /etc/ssl/cert.pem
'
+ grep '### Digital Signature Trust Co.' -A 21 /etc/ssl/cert.pem
### Digital Signature Trust Co.
=== /O=Digital Signature Trust Co./CN=DST Root CA X3
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
44:af:b0:80:d6:a3:27:ba:89:30:39:86:2e:f8:40:6b
Signature Algorithm: sha1WithRSAEncryption
Validity
Not Before: Sep 30 21:12:19 2000 GMT
Not After : Sep 30 14:01:15 2021 GMT
Subject: O=Digital Signature Trust Co., CN=DST Root CA X3
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Subject Key Identifier:
C4:A7:B1:A4:7B:2C:71:FA:DB:E1:4B:90:75:FF:C4:15:60:85:89:10
SHA1 Fingerprint=DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13
SHA256 Fingerprint=06:87:26:03:31:A7:24:03:D9:09:F1:05:E6:9B:CF:0D:32:E1:BD:24:93:FF:C6:D9:20:6D:11:BC:D6:77:07:39
Which makes websites like registry.bower.io not pass the verification:
$ docker run --rm alpine:3.8 sh -euxc '
apk add openssl
openssl s_client -connect registry.bower.io:443 -servername registry.bower.io
'
...
+ openssl s_client -connect registry.bower.io:443 -servername registry.bower.io
...
---
Certificate chain
0 s:/CN=bower.io
i:/C=US/O=Let's Encrypt/CN=E6
1 s:/C=US/O=Let's Encrypt/CN=E6
i:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
2 s:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
...
Verify return code: 10 (certificate has expired)
---
DONE
The natural solution is to remove the certificate:
$ docker run --rm alpine:3.8 sh -euxc '
apk add openssl ca-certificates
sed -i "/^mozilla\/DST_Root_CA_X3\.crt$/s/^/#/" /etc/ca-certificates.conf
update-ca-certificates
openssl s_client -connect registry.bower.io:443 -servername registry.bower.io
'
...
+ sed -i '/^mozilla\/DST_Root_CA_X3\.crt$/s/^/#/' /etc/ca-certificates.conf
+ update-ca-certificates
WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping
+ openssl s_client -connect registry.bower.io:443 -servername registry.bower.io
...
---
Certificate chain
0 s:/CN=bower.io
i:/C=US/O=Let's Encrypt/CN=E6
1 s:/C=US/O=Let's Encrypt/CN=E6
i:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
2 s:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
...
Verify return code: 10 (certificate has expired)
---
DONE
But it doesn't help, because /etc/ssl/cert.pem
, which comes with libressl2.7-libcrypto
:
$ docker run --rm alpine:3.8 sh -euxc '
apk info -W /etc/ssl/cert.pem
'
+ apk info -W /etc/ssl/cert.pem
/etc/ssl/cert.pem is owned by libressl2.7-libcrypto-2.7.5-r0
is not changed by update-ca-certificates
. And that is one of the locations of the system trust store, as such the file must be moved, renamed or something:
$ docker run --rm alpine:3.8 sh -euxc '
apk add openssl ca-certificates
sed -i "/^mozilla\/DST_Root_CA_X3\.crt$/s/^/#/" /etc/ca-certificates.conf
update-ca-certificates
mv /etc/ssl/cert.pem /etc/ssl/cert.pem.bak
openssl s_client -connect registry.bower.io:443 -servername registry.bower.io
'
...
+ sed -i '/^mozilla\/DST_Root_CA_X3\.crt$/s/^/#/' /etc/ca-certificates.conf
+ update-ca-certificates
WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping
+ mv /etc/ssl/cert.pem /etc/ssl/cert.pem.bak
+ openssl s_client -connect registry.bower.io:443 -servername registry.bower.io
...
---
Certificate chain
0 s:/CN=bower.io
i:/C=US/O=Let's Encrypt/CN=E6
1 s:/C=US/O=Let's Encrypt/CN=E6
i:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
2 s:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
...
Verify return code: 0 (ok)
---
That is not needed in case of curl
:
$ docker run --rm alpine:3.8 sh -euxc '
apk add curl
curl -sS https://registry.bower.io
'
...
+ curl -sS https://registry.bower.io
curl: (60) SSL certificate problem: certificate has expired
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
$ docker run --rm alpine:3.8 sh -euxc '
apk add curl
sed -i "/^mozilla\/DST_Root_CA_X3\.crt$/s/^/#/" /etc/ca-certificates.conf
update-ca-certificates
curl -sS https://registry.bower.io
'
...
+ sed -i '/^mozilla\/DST_Root_CA_X3\.crt$/s/^/#/' /etc/ca-certificates.conf
+ update-ca-certificates
WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping
+ curl -sS https://registry.bower.io
Found. Redirecting to http://bower.io/search/
Probably because it uses libressl
:
$ docker run --rm alpine:3.8 sh -euxc '
apk add curl
apk info -R curl
apk info -R libcurl
apk info -P libressl2.7-libssl
apk info -P libressl2.7-libcrypto
ldd /usr/bin/curl
apk info -W /lib/libssl.so.45
apk info -W /lib/libcrypto.so.43
'
...
+ apk info -R curl
curl-7.61.1-r3 depends on:
ca-certificates
so:libcurl.so.4
+ apk info -R libcurl
libcurl-7.61.1-r3 depends on:
ca-certificates
so:libcrypto.so.43
so:libssl.so.45
+ apk info -P libressl2.7-libssl
libressl2.7-libssl-2.7.5-r0 provides:
so:libssl.so.45=45.0.1
+ apk info -P libressl2.7-libcrypto
libressl2.7-libcrypto-2.7.5-r0 provides:
so:libcrypto.so.43=43.0.1
+ ldd /usr/bin/curl
libssl.so.45 => /lib/libssl.so.45 (0x77ac57566000)
libcrypto.so.43 => /lib/libcrypto.so.43 (0x77ac571bb000)
+ apk info -W /lib/libssl.so.45
/lib/libssl.so.45 is owned by libressl2.7-libssl-2.7.5-r0
+ apk info -W /lib/libcrypto.so.43
/lib/libcrypto.so.43 is owned by libressl2.7-libcrypto-2.7.5-r0
But needed by nodejs
:
$ docker run --rm alpine:3.8 sh -euxc '
apk add nodejs
cat <<\EOF >a.js
const https = require("https");
https.get({host: "registry.bower.io"}, res => {
console.log(res.statusCode);
}).on("error", e => {
console.log(e);
});
EOF
node a.js
'
...
+ node a.js
{ Error: certificate has expired
at TLSSocket.<anonymous> (_tls_wrap.js:1116:38)
at emitNone (events.js:106:13)
at TLSSocket.emit (events.js:208:7)
at TLSSocket._finishInit (_tls_wrap.js:643:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:473:38) code: 'CERT_HAS_EXPIRED' }
$ docker run --rm alpine:3.8 sh -euxc '
apk add nodejs
cat <<\EOF >a.js
const https = require("https");
https.get({host: "registry.bower.io"}, res => {
console.log(res.statusCode);
}).on("error", e => {
console.log(e);
});
EOF
sed -i "/^mozilla\/DST_Root_CA_X3\.crt$/s/^/#/" /etc/ca-certificates.conf
update-ca-certificates
node a.js
'
...
+ sed -i '/^mozilla\/DST_Root_CA_X3\.crt$/s/^/#/' /etc/ca-certificates.conf
+ update-ca-certificates
WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping
+ node a.js
{ Error: certificate has expired
at TLSSocket.<anonymous> (_tls_wrap.js:1116:38)
at emitNone (events.js:106:13)
at TLSSocket.emit (events.js:208:7)
at TLSSocket._finishInit (_tls_wrap.js:643:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:473:38) code: 'CERT_HAS_EXPIRED' }
$ docker run --rm alpine:3.8 sh -euxc '
apk add nodejs
cat <<\EOF >a.js
const https = require("https");
https.get({host: "registry.bower.io"}, res => {
console.log(res.statusCode);
}).on("error", e => {
console.log(e);
});
EOF
sed -i "/^mozilla\/DST_Root_CA_X3\.crt$/s/^/#/" /etc/ca-certificates.conf
update-ca-certificates
mv /etc/ssl/cert.pem /etc/ssl/cert.pem.bak
node a.js
'
...
+ sed -i '/^mozilla\/DST_Root_CA_X3\.crt$/s/^/#/' /etc/ca-certificates.conf
+ update-ca-certificates
WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping
+ mv /etc/ssl/cert.pem /etc/ssl/cert.pem.bak
+ node a.js
302
Which uses openssl
:
$ docker run --rm alpine:3.8 sh -euxc '
apk add nodejs
apk info -R nodejs
apk info -P libcrypto1.0
apk info -P libssl1.0
ldd /usr/bin/node
apk info -W /lib/libcrypto.so.1.0.0
apk info -W /lib/libssl.so.1.0.0
'
...
+ apk info -R nodejs
nodejs-8.14.0-r0 depends on:
ca-certificates
so:libcrypto.so.1.0.0
so:libssl.so.1.0.0
+ apk info -P libcrypto1.0
libcrypto1.0-1.0.2u-r0 provides:
so:libcrypto.so.1.0.0=1.0.0
+ apk info -P libssl1.0
libssl1.0-1.0.2u-r0 provides:
so:libssl.so.1.0.0=1.0.0
+ ldd /usr/bin/node
libcrypto.so.1.0.0 => /lib/libcrypto.so.1.0.0 (0x77c7c7ba3000)
libssl.so.1.0.0 => /lib/libssl.so.1.0.0 (0x77c7c793a000)
+ apk info -W /lib/libcrypto.so.1.0.0
/lib/libcrypto.so.1.0.0 is owned by libcrypto1.0-1.0.2u-r0
+ apk info -W /lib/libssl.so.1.0.0
/lib/libssl.so.1.0.0 is owned by libssl1.0-1.0.2u-r0