forked from quic-go/quic-go
read tls.Config properly in RSA signer
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"errors"
|
"errors"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/lucas-clemente/quic-go/utils"
|
"github.com/lucas-clemente/quic-go/utils"
|
||||||
)
|
)
|
||||||
@@ -19,6 +20,7 @@ import (
|
|||||||
type rsaSigner struct {
|
type rsaSigner struct {
|
||||||
key *rsa.PrivateKey
|
key *rsa.PrivateKey
|
||||||
cert *x509.Certificate
|
cert *x509.Certificate
|
||||||
|
config *tls.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRSASigner loads the key and cert from files
|
// NewRSASigner loads the key and cert from files
|
||||||
@@ -38,7 +40,7 @@ func NewRSASigner(tlsConfig *tls.Config) (Signer, error) {
|
|||||||
return nil, errors.New("Only RSA private keys are supported for now")
|
return nil, errors.New("Only RSA private keys are supported for now")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &rsaSigner{key: rsaKey, cert: x509Cert}, nil
|
return &rsaSigner{key: rsaKey, cert: x509Cert, config: tlsConfig}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignServerProof signs CHLO and server config for use in the server proof
|
// SignServerProof signs CHLO and server config for use in the server proof
|
||||||
@@ -83,3 +85,28 @@ func (kd *rsaSigner) GetCertCompressed(sni string) []byte {
|
|||||||
func (kd *rsaSigner) GetCertUncompressed(sni string) []byte {
|
func (kd *rsaSigner) GetCertUncompressed(sni string) []byte {
|
||||||
return kd.cert.Raw
|
return kd.cert.Raw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (kd *rsaSigner) getCertForSNI(sni string) (*tls.Certificate, error) {
|
||||||
|
if kd.config.GetCertificate != nil {
|
||||||
|
cert, err := kd.config.GetCertificate(&tls.ClientHelloInfo{ServerName: sni})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if cert != nil {
|
||||||
|
return cert, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(kd.config.NameToCertificate) != 0 {
|
||||||
|
if cert, ok := kd.config.NameToCertificate[sni]; ok {
|
||||||
|
return cert, nil
|
||||||
|
}
|
||||||
|
wildcardSNI := "*" + strings.TrimLeftFunc(sni, func(r rune) bool { return r != '.' })
|
||||||
|
if cert, ok := kd.config.NameToCertificate[wildcardSNI]; ok {
|
||||||
|
return cert, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(kd.config.Certificates) != 0 {
|
||||||
|
return &kd.config.Certificates[0], nil
|
||||||
|
}
|
||||||
|
return nil, errors.New("no matching certificate found")
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"compress/zlib"
|
"compress/zlib"
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
|
||||||
"github.com/lucas-clemente/quic-go/testdata"
|
"github.com/lucas-clemente/quic-go/testdata"
|
||||||
@@ -41,4 +42,57 @@ var _ = Describe("ProofRsa", func() {
|
|||||||
err = rsa.VerifyPSS(kd.(*rsaSigner).cert.PublicKey.(*rsa.PublicKey), crypto.SHA256, data, signature, &rsa.PSSOptions{SaltLength: 32})
|
err = rsa.VerifyPSS(kd.(*rsaSigner).cert.PublicKey.(*rsa.PublicKey), crypto.SHA256, data, signature, &rsa.PSSOptions{SaltLength: 32})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Context("retrieving certificate", func() {
|
||||||
|
var (
|
||||||
|
signer *rsaSigner
|
||||||
|
config *tls.Config
|
||||||
|
cert tls.Certificate
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
cert = testdata.GetCertificate()
|
||||||
|
config = &tls.Config{}
|
||||||
|
signer = &rsaSigner{config: config}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("uses first certificate in config.Certificates", func() {
|
||||||
|
config.Certificates = []tls.Certificate{cert}
|
||||||
|
cert, err := signer.getCertForSNI("")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(cert.PrivateKey).ToNot(BeNil())
|
||||||
|
Expect(cert.Certificate[0]).ToNot(BeNil())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("uses NameToCertificate entries", func() {
|
||||||
|
config.NameToCertificate = map[string]*tls.Certificate{
|
||||||
|
"quic.clemente.io": &cert,
|
||||||
|
}
|
||||||
|
cert, err := signer.getCertForSNI("quic.clemente.io")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(cert.PrivateKey).ToNot(BeNil())
|
||||||
|
Expect(cert.Certificate[0]).ToNot(BeNil())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("uses NameToCertificate entries with wildcard", func() {
|
||||||
|
config.NameToCertificate = map[string]*tls.Certificate{
|
||||||
|
"*.clemente.io": &cert,
|
||||||
|
}
|
||||||
|
cert, err := signer.getCertForSNI("quic.clemente.io")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(cert.PrivateKey).ToNot(BeNil())
|
||||||
|
Expect(cert.Certificate[0]).ToNot(BeNil())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("uses GetCertificate", func() {
|
||||||
|
config.GetCertificate = func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||||
|
Expect(clientHello.ServerName).To(Equal("quic.clemente.io"))
|
||||||
|
return &cert, nil
|
||||||
|
}
|
||||||
|
cert, err := signer.getCertForSNI("quic.clemente.io")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(cert.PrivateKey).ToNot(BeNil())
|
||||||
|
Expect(cert.Certificate[0]).ToNot(BeNil())
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user