Repository: go
Issue: crypto/x509: unable to parse certificate with rsassa-pss algorithm
Labels: NeedsInvestigation

We came across this issue after being issued a self signed CA certificate that we needed to use to verify some signatures. The certificate uses the rsassa-pss algorithm. This is now supported in openssl, however it appears to be unsupported in the x509 package. We are unable to load the certificate public key and use it to verify signatures. RSA-PSS seems to be supported in the RSA and TLS packages however.

### What version of Go are you using (`go version`)?

<pre>
go version go1.17 darwin/amd64
</pre>

### Does this issue reproduce with the latest release?

Yes

### What operating system and processor architecture are you using (`go env`)?

<details><summary><code>go env</code> Output</summary><br><pre>
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOOS="darwin"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.17/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.17/libexec/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.17"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/d_/l9p5rr350bs7q7f9p60t79g00000gn/T/go-build2138978773=/tmp/go-build -gno-record-gcc-switches -fno-common"
</pre></details>

### What did you do?
Using openssl 1.1 generate an rsa-pss certificate using the following command

```
openssl  req -x509 -newkey rsa-pss -keyout rsassaPss.key\
 -out rsassaPss.crt -subj /CN=localhost -nodes -batch\
 -pkeyopt rsa_keygen_bits:2048 -sha256
```

Try to use this certificate in Go - the public key will be nil. Certificate below is just a test.

```go
package main

import (
	"crypto/x509"
	"encoding/pem"
	"fmt"
)

func main() {
	const certPEM = `
-----BEGIN CERTIFICATE-----
MIIDaTCCAiCgAwIBAgIUAK7miZIeTHuJkwv6VxQKobZyBv8wPgYJKoZIhvcNAQEK
MDGgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogQC
AgDeMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0yMTA5MTAwNjUwMzlaFw0yMTEw
MTAwNjUwMzlaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASAwCwYJKoZIhvcNAQEK
A4IBDwAwggEKAoIBAQDIQYtNuv4W1wUyzQsEaeJvUx0sAUmT9QtfsGehAc85r3qn
EDiDvOYGwMuT1INrNCZXWIriToAP9rnPGtFhkKb8IkrQbPnwEFCBK1+0k/bON5eJ
FoeaNR7BfjMtVWbHGSBWmQxCoTQ6Zm2GJ2b7tCPlI4nzLu0bnY1+rwvIGfGUOmhD
lCJdTGHrP+ba21kdQPff7NKhrikH50mxo9PMfqe8l1ctf+D7Y5CYRg9eGE8HopkP
6RXSNETyy+LiG1xNSeyLn0rjhxgqKLAqKMQJICZY4fP0rRt9ddnJ5ii89dZWIXGC
2ltrXyJoALJT30vaZqMPOCFHRGUFmTgDWu/6CW/PAgMBAAGjUzBRMB0GA1UdDgQW
BBTmQZJ2A6B3bN4NSH8paBHwUeY62zAfBgNVHSMEGDAWgBTmQZJ2A6B3bN4NSH8p
aBHwUeY62zAPBgNVHRMBAf8EBTADAQH/MD4GCSqGSIb3DQEBCjAxoA0wCwYJYIZI
AWUDBAIBoRowGAYJKoZIhvcNAQEIMAsGCWCGSAFlAwQCAaIEAgIA3gOCAQEAgHFF
Wrq0ukDb2RYdT6qYrlB2iy6gRbkyxyuqQ1RyN4hAKA2v87YTfgVr9WYdKyw397O1
aSPHvICS6cfIc/RaboiJ2ELB5ADa91G87xecmud5I7rhO+Ou6uB06gX+ilZldY2r
S7upRLsNYtfkZgpYmIrhrcTECn5aWHntAAdK4nfhdbz+UcZ6M/JlfV2+lOB5Xciy
79BBe9H/BlrsYedmxwG6D/P9ciJ6fEw45N7rKnnoeydbo5+Jg+MMumzITDkLUdr2
3y71AiHyLcSx/vjlN4VLKoA7JkpCC48bvS8NeRuC1ap4E6n+Bw5Ej4C1hVTsmoYC
iCu1A5nM8YQM8QSKVg==
-----END CERTIFICATE-----
`

	certblock, _ := pem.Decode([]byte(certPEM))
	if certblock == nil {
		panic("failed to parse PEM certificate")
	}

	cert, err := x509.ParseCertificate(certblock.Bytes)
	if err != nil {
		panic("failed to parse DER encoded public key: " + err.Error())
	}
	certpub := cert.PublicKey
	fmt.Println("public key", certpub)
}
```

### What did you expect to see?

The public key is parsed and loaded

### What did you see instead?

The public key is nil

### Further information

The certificate we are trying to use has the following attributes which I can't generate exactly the same with openssl. But the example still causes the same issues with Go

```
/usr/local/opt/openssl@1.1/bin/openssl x509 -in x.cer -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ...
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: ...
        Validity
            Not Before: ...
            Not After : ...
        Subject: ...
        Subject Public Key Info:
            Public Key Algorithm: rsassaPss
                RSA-PSS Public-Key: (2048 bit)
                Modulus:
...
                Exponent: ...
                PSS parameter restrictions:
                  Hash Algorithm: sha256
                  Mask Algorithm: mgf1 with sha256
                  Minimum Salt Length: 0x20
                  Trailer Field: 0x01
    Signature Algorithm: sha256WithRSAEncryption
...
```