Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto/x509: "certificate signed by unknown authority" with seemingly valid certificate chain #28276

Closed
imirkin opened this issue Oct 18, 2018 · 7 comments

Comments

@imirkin
Copy link

@imirkin imirkin commented Oct 18, 2018

Version: go version go1.11.1 linux/amd64

Trying to fetch any data from https://www.aft.gouv.fr/ results in an error, but chrome and openssl s_client are both happy. Checked that there's a Certigna CA root in my /etc/ssl/certs (which is the ultimate root presented by this site). One odd observation is that the serial number in chrome has an extra leading 00 byte compared to what "openssl x509 -text" prints for that certificate. I can see the execution do "openat" syscalls on all the /etc/ssl/certs files (the "correct" cert is e113c810.0 aka "Certigna" -- openssl only opens that one file).

~ $ mkdir go-1.11.1
~ $ cd go-1.11.1/
~/go-1.11.1 $ mv ../go1.11.1.linux-amd64.tar.gz .
~/go-1.11.1 $ tar zxf go1.11.1.linux-amd64.tar.gz 
~/go-1.11.1 $ GOPATH=`pwd` ./go/bin/go version
go version go1.11.1 linux/amd64
~/go-1.11.1 $ GOPATH=`pwd` ./go/bin/go run tt.go 
Get https://www.aft.gouv.fr/: x509: certificate signed by unknown authority
$ cat tt.go
package main

import (
        "fmt"
        "net/http"
)

func main() {
        _, err := http.Get("https://www.aft.gouv.fr/")
        if err != nil {
                fmt.Println(err)
        } else {
                fmt.Println("success")
        }
}
@imirkin
Copy link
Author

@imirkin imirkin commented Oct 18, 2018

Hm, interesting. There's something more going on here...

$ wget -O- https://www.aft.gouv.fr/
--2018-10-18 19:40:32--  https://www.aft.gouv.fr/
Resolving www.aft.gouv.fr... 193.17.19.48
Connecting to www.aft.gouv.fr|193.17.19.48|:443... connected.
ERROR: The certificate of 'www.aft.gouv.fr' is not trusted.
ERROR: The certificate of 'www.aft.gouv.fr' hasn't got a known issuer.

Which reads from /etc/ssl/certs/ca-certificates.crt (and I ran update-ca-certificates just in case)

But with openssl:

$ openssl s_client -connect www.aft.gouv.fr:443
CONNECTED(00000003)
depth=2 C = FR, O = Dhimyotis, CN = Certigna
verify return:1
depth=1 C = FR, O = DHIMYOTIS, OU = 0002 48146308100036, 2.5.4.97 = NTRFR-48146308100036, CN = Certigna Services CA
verify return:1
depth=0 C = FR, L = PARIS, O = MINISTERE DE L ECONOMIE ET DES FINANCES, OU = 0002 11002001300097, 2.5.4.97 = NTRFR-11002001300097, CN = igpde.finances.gouv.fr, serialNumber = S7010005
verify return:1
---
Certificate chain
 0 s:/C=FR/L=PARIS/O=MINISTERE DE L ECONOMIE ET DES FINANCES/OU=0002 11002001300097/2.5.4.97=NTRFR-11002001300097/CN=igpde.finances.gouv.fr/serialNumber=S7010005
   i:/C=FR/O=DHIMYOTIS/OU=0002 48146308100036/2.5.4.97=NTRFR-48146308100036/CN=Certigna Services CA
 1 s:/C=FR/O=DHIMYOTIS/OU=0002 48146308100036/2.5.4.97=NTRFR-48146308100036/CN=Certigna Services CA
   i:/C=FR/O=Dhimyotis/CN=Certigna
 2 s:/C=FR/O=Dhimyotis/CN=Certigna
   i:/C=FR/O=Dhimyotis/CN=Certigna
---
...
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
...
    Start Time: 1539906145
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)

and this reads /etc/ssl/certs/e113c810.0 directly.

@imirkin
Copy link
Author

@imirkin imirkin commented Oct 19, 2018

... and the plot thickens. Chrome (68 and 69) likes it, Firefox does not.

Looking at it in Firefox, it actually seems like they send 3 certificates:

Cert 1: Signed by Certigna (which is in the system roots)
Cert 2: Signed by Cert 3
Cert 3: Self-signed

It looks like Chrome is cool with this, Firefox, wget, and golang is not. I don't know what the "correct" thing here is.

@adamdecaf
Copy link
Contributor

@adamdecaf adamdecaf commented Oct 19, 2018

Yea.. This is definitely strange... I'm on Windows, so some of these are commands are linux, but Windows commands work too.

Firefox rejects this site, but chrome loads it for me also.

$ cert-manage list -file aft.gouv.fr # file was from firefox output (PEM bundle)
Certificate
  SHA256 Fingerprint: c73f446a2905d9c681b8932c9d66fb409b05a9cf3221372f2132809bff347011
  SerialNumber: 94383833859489847656733716548355707322
  Subject: www.aft.gouv.fr
  Issuer: Certigna Services CA
  NotBefore: 2018-04-17 08:58:12 +0000 UTC | NotAfter: 2020-04-16 08:58:12 +0000 UTC
  DNSNames:
    www.aft.gouv.fr
    aft.gouv.fr
  CRLDistributionPoints:
    http://crl.certigna.fr/servicesca.crl
    http://crl.dhimyotis.com/servicesca.crl
Certificate
  SHA256 Fingerprint: 1a59bce22526e00f2f45f468f189bf6295a09613f5ddaa3a065f557c681b8c72
  SerialNumber: 1492319261661083504146538991001357251153460
  Subject: AC2-FINANCES-SERVEURS-2
  Issuer: AC2-FINANCES-RACINE
  NotBefore: 2017-12-13 00:00:00 +0000 UTC | NotAfter: 2024-03-21 00:00:00 +0000 UTC
  IsCA: true
  CRLDistributionPoints:
    http://igc1.finances.gouv.fr/ac2-finances-racine.crl
    http://igc2.finances.gouv.fr/ac2-finances-racine.crl
Certificate
  SHA256 Fingerprint: d41b4453e05a6baf74fbc0df8b48922093ce3872c85309a75de79983d23d3222
  SerialNumber: 1492425241900974833885176625963136504336648
  Subject: AC2-FINANCES-RACINE  ### <---- This is the self signed cert. 
  Issuer: AC2-FINANCES-RACINE
  NotBefore: 2014-03-21 00:00:00 +0000 UTC | NotAfter: 2024-03-21 00:00:00 +0000 UTC
  IsCA: true
  CRLDistributionPoints:
    http://igc1.finances.gouv.fr/ac2-finances-racine.crl
    http://igc2.finances.gouv.fr/ac2-finances-racine.crl

None of the Windows cert stores (where Chrome looks) have this root.

$ certutil.exe -store My | grep -C10 AC2-FINANCES-RACINE
$ certutil.exe -store Root | grep -C10 AC2-FINANCES-RACINE
$ certutil.exe -store Trust | grep -C10 AC2-FINANCES-RACINE
$ certutil.exe -store CA | grep -C10 AC2-FINANCES-RACINE
$ certutil.exe -store AuthRoot | grep -C10 AC2-FINANCES-RACINE
@mikioh
Copy link
Contributor

@mikioh mikioh commented Oct 19, 2018

it actually seems like they send 3 certificates:

Sounds interesting. On Censys, we see only 2 certs (without self-signed one); https://censys.io/certificates?q=www.aft.gouv.fr+and+tags%3A+trusted

@mikioh
Copy link
Contributor

@mikioh mikioh commented Oct 19, 2018

Sorry, forgot to replace the tag "trusted" with "%2A"; yup, they have three certs; https://censys.io/certificates?q=www.aft.gouv.fr+and+tags%3A+%252A

@imirkin
Copy link
Author

@imirkin imirkin commented Oct 19, 2018

$ cert-manage list -file aft.gouv.fr # file was from firefox output (PEM bundle)
Certificate
  SHA256 Fingerprint: c73f446a2905d9c681b8932c9d66fb409b05a9cf3221372f2132809bff347011
  SerialNumber: 94383833859489847656733716548355707322
  Subject: www.aft.gouv.fr
  Issuer: Certigna Services CA
  NotBefore: 2018-04-17 08:58:12 +0000 UTC | NotAfter: 2020-04-16 08:58:12 +0000 UTC
  DNSNames:
    www.aft.gouv.fr
    aft.gouv.fr
  CRLDistributionPoints:
    http://crl.certigna.fr/servicesca.crl
    http://crl.dhimyotis.com/servicesca.crl

Note that the issuer of this cert is Certigna, not the next cert on the list. And Certigna is in the list of roots. However upon looking a little more carefully, there's actually supposed to be an intermediate there -- the root is "Certigna" while this is "Certigna Services CA". And it's missing from the supplied chain, where I'd normally expect to see it.

But then ... why does openssl work? Unclear. The supplied cert does have

            Authority Information Access: 
                CA Issuers - URI:http://autorite.certigna.fr/servicesca.der
                CA Issuers - URI:http://autorite.dhimyotis.com/servicesca.der
                OCSP - URI:http://servicesca.ocsp.certigna.fr
                OCSP - URI:http://servicesca.ocsp.dhimyotis.com

However I don't see openssl try to connect to those URIs. And I don't have it locally (or in strace). But openssl s_client -showcerts certainly prints it out...

I'm definitely inclined to say "server misconfigured" at this point, but I'm still unclear on how openssl s_client works things out.

@imirkin
Copy link
Author

@imirkin imirkin commented Oct 19, 2018

Aha, with a tcpdump, looks like go is getting different certs than openssl. And sure enough, with

openssl s_client -servername www.aft.gouv.fr -connect www.aft.gouv.fr:443

it fails, because it gets those bogus certs. Without the -servername, it's all good. Moral of the story ... SSL is complicated and difficult to debug. Sorry for the totally off-topic bug!

@imirkin imirkin closed this Oct 19, 2018
@golang golang locked and limited conversation to collaborators Oct 19, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.