Skip to content

Commit

Permalink
Upstream merge 2024-11-11 (aws#1985)
Browse files Browse the repository at this point in the history
By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 license and the ISC license.
  • Loading branch information
andrewhop authored Nov 25, 2024
2 parents f14cc9a + 4b14a26 commit 412018d
Show file tree
Hide file tree
Showing 22 changed files with 677 additions and 947 deletions.
10 changes: 10 additions & 0 deletions ssl/ssl_cert.cc
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,16 @@ UniquePtr<DC> DC::Parse(CRYPTO_BUFFER *in, uint8_t *out_alert) {
return nullptr;
}

// RFC 9345 forbids algorithms that use the rsaEncryption OID. As the
// RSASSA-PSS OID is unusably complicated, this effectively means we will not
// support RSA delegated credentials.
if (SSL_get_signature_algorithm_key_type(dc->dc_cert_verify_algorithm) ==
EVP_PKEY_RSA) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SIGNATURE_ALGORITHM);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
return nullptr;
}

return dc;
}

Expand Down
22 changes: 0 additions & 22 deletions ssl/test/runner/cert.pem

This file was deleted.

10 changes: 5 additions & 5 deletions ssl/test/runner/channel_id_key.pem
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIPwxu50c7LEhVNRYJFRWBUnoaz7JSos96T5hBp4rjyptoAoGCCqGSM49
AwEHoUQDQgAEzFSVTE5guxJRQ0VbZ8dicPs5e/DT7xpW7Yc9hq0VOchv7cbXuI/T
CwadDjGWX/oaz0ftFqrVmfkwZu+C58ioWg==
-----END EC PRIVATE KEY-----
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg/DG7nRzssSFU1Fgk
VFYFSehrPslKiz3pPmEGniuPKm2hRANCAATMVJVMTmC7ElFDRVtnx2Jw+zl78NPv
Glbthz2GrRU5yG/txte4j9MLBp0OMZZf+hrPR+0WqtWZ+TBm74LnyKha
-----END PRIVATE KEY-----
4 changes: 2 additions & 2 deletions ssl/test/runner/cipher_suites.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ type keyAgreement interface {
// In the case that the key agreement protocol doesn't use a
// ServerKeyExchange message, generateServerKeyExchange can return nil,
// nil.
generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg, uint16) (*serverKeyExchangeMsg, error)
processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
generateServerKeyExchange(*Config, *CertificateChain, *clientHelloMsg, *serverHelloMsg, uint16) (*serverKeyExchangeMsg, error)
processClientKeyExchange(*Config, *CertificateChain, *clientKeyExchangeMsg, uint16) ([]byte, error)

// On the client side, the next two methods are called in order.

Expand Down
143 changes: 121 additions & 22 deletions ssl/test/runner/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ import (
"crypto/ecdsa"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"io"
"math/big"
"os"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -434,18 +437,18 @@ type Config struct {
// If Time is nil, TLS uses time.Now.
Time func() time.Time

// Certificates contains one or more certificate chains
// Chains contains one or more certificate chains
// to present to the other side of the connection.
// Server configurations must include at least one certificate.
Certificates []Certificate
Chains []CertificateChain

// NameToCertificate maps from a certificate name to an element of
// Certificates. Note that a certificate name can be of the form
// NameToChain maps from a certificate name to an element of
// Chains. Note that a certificate name can be of the form
// '*.example.com' and so doesn't have to be a domain name as such.
// See Config.BuildNameToCertificate
// The nil value causes the first element of Certificates to be used
// The nil value causes the first element of Chains to be used
// for all connections.
NameToCertificate map[string]*Certificate
NameToChain map[string]*CertificateChain

// RootCAs defines the set of root certificate authorities
// that clients use when verifying server certificates.
Expand Down Expand Up @@ -1842,7 +1845,7 @@ type ProtocolBugs struct {

// RenegotiationCertificate, if not nil, is the certificate to use on
// renegotiation handshakes.
RenegotiationCertificate *Certificate
RenegotiationCertificate *CertificateChain

// ExpectNoCertificateAuthoritiesExtension, if true, causes the client to
// reject CertificateRequest with the CertificateAuthorities extension.
Expand Down Expand Up @@ -2126,20 +2129,20 @@ func (c *Config) supportedVersions(isDTLS, requireTLS13 bool) []uint16 {
}

// getCertificateForName returns the best certificate for the given name,
// defaulting to the first element of c.Certificates if there are no good
// defaulting to the first element of c.Chains if there are no good
// options.
func (c *Config) getCertificateForName(name string) *Certificate {
if len(c.Certificates) == 1 || c.NameToCertificate == nil {
func (c *Config) getCertificateForName(name string) *CertificateChain {
if len(c.Chains) == 1 || c.NameToChain == nil {
// There's only one choice, so no point doing any work.
return &c.Certificates[0]
return &c.Chains[0]
}

name = strings.ToLower(name)
for len(name) > 0 && name[len(name)-1] == '.' {
name = name[:len(name)-1]
}

if cert, ok := c.NameToCertificate[name]; ok {
if cert, ok := c.NameToChain[name]; ok {
return cert
}

Expand All @@ -2149,13 +2152,13 @@ func (c *Config) getCertificateForName(name string) *Certificate {
for i := range labels {
labels[i] = "*"
candidate := strings.Join(labels, ".")
if cert, ok := c.NameToCertificate[candidate]; ok {
if cert, ok := c.NameToChain[candidate]; ok {
return cert
}
}

// If nothing matches, return the first certificate.
return &c.Certificates[0]
return &c.Chains[0]
}

func (c *Config) signSignatureAlgorithms() []signatureAlgorithm {
Expand All @@ -2172,28 +2175,28 @@ func (c *Config) verifySignatureAlgorithms() []signatureAlgorithm {
return supportedSignatureAlgorithms
}

// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate
// BuildNameToCertificate parses c.Chains and builds c.NameToCertificate
// from the CommonName and SubjectAlternateName fields of each of the leaf
// certificates.
func (c *Config) BuildNameToCertificate() {
c.NameToCertificate = make(map[string]*Certificate)
for i := range c.Certificates {
cert := &c.Certificates[i]
c.NameToChain = make(map[string]*CertificateChain)
for i := range c.Chains {
cert := &c.Chains[i]
x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
if err != nil {
continue
}
if len(x509Cert.Subject.CommonName) > 0 {
c.NameToCertificate[x509Cert.Subject.CommonName] = cert
c.NameToChain[x509Cert.Subject.CommonName] = cert
}
for _, san := range x509Cert.DNSNames {
c.NameToCertificate[san] = cert
c.NameToChain[san] = cert
}
}
}

// A Certificate is a chain of one or more certificates, leaf first.
type Certificate struct {
// A CertificateChain is a chain of one or more certificates, leaf first.
type CertificateChain struct {
Certificate [][]byte
PrivateKey crypto.PrivateKey // supported types: *rsa.PrivateKey, *ecdsa.PrivateKey
// OCSPStaple contains an optional OCSP response which will be served
Expand All @@ -2208,6 +2211,15 @@ type Certificate struct {
// processing for TLS clients doing client authentication. If nil, the
// leaf certificate will be parsed as needed.
Leaf *x509.Certificate
// ChainPath is the path to the temporary on disk copy of the certificate
// chain.
ChainPath string
// KeyPath is the path to the temporary on disk copy of the key.
KeyPath string
// RootPath is the path to the temporary on disk copy of the root of the
// certificate chain. If the chain only contains one certificate ChainPath
// and RootPath will be the same.
RootPath string
}

// A TLS record.
Expand Down Expand Up @@ -2419,3 +2431,90 @@ func isAllZero(v []byte) bool {
}
return true
}

var baseCertTemplate = &x509.Certificate{
SerialNumber: big.NewInt(57005),
Subject: pkix.Name{
CommonName: "test cert",
Country: []string{"US"},
Province: []string{"Some-State"},
Organization: []string{"Internet Widgits Pty Ltd"},
},
NotBefore: time.Now().Add(-time.Hour),
NotAfter: time.Now().Add(time.Hour),
DNSNames: []string{"test"},
IsCA: true,
BasicConstraintsValid: true,
}

var tmpDir string

func generateSingleCertChain(template *x509.Certificate, key crypto.Signer, ocspStaple, sctList []byte) CertificateChain {
cert := generateTestCert(template, nil, key, ocspStaple, sctList)
tmpCertPath, tmpKeyPath := writeTempCertFile([]*x509.Certificate{cert}), writeTempKeyFile(key)
return CertificateChain{
Certificate: [][]byte{cert.Raw},
PrivateKey: key,
OCSPStaple: ocspStaple,
SignedCertificateTimestampList: sctList,
Leaf: cert,
ChainPath: tmpCertPath,
KeyPath: tmpKeyPath,
RootPath: tmpCertPath,
}
}

func writeTempCertFile(certs []*x509.Certificate) string {
f, err := os.CreateTemp(tmpDir, "test-cert")
if err != nil {
panic(fmt.Sprintf("failed to create temp file: %s", err))
}
for _, cert := range certs {
if _, err := f.Write(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})); err != nil {
panic(fmt.Sprintf("failed to write test certificate: %s", err))
}
}
tmpCertPath := f.Name()
if err := f.Close(); err != nil {
panic(fmt.Sprintf("failed to close test certificate temp file: %s", err))
}
return tmpCertPath
}

func writeTempKeyFile(privKey crypto.Signer) string {
f, err := os.CreateTemp(tmpDir, "test-key")
if err != nil {
panic(fmt.Sprintf("failed to create temp file: %s", err))
}
keyDER, err := x509.MarshalPKCS8PrivateKey(privKey)
if err != nil {
panic(fmt.Sprintf("failed to marshal test key: %s", err))
}
if _, err := f.Write(pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: keyDER})); err != nil {
panic(fmt.Sprintf("failed to write test key: %s", err))
}
tmpKeyPath := f.Name()
if err := f.Close(); err != nil {
panic(fmt.Sprintf("failed to close test key temp file: %s", err))
}
return tmpKeyPath
}

func generateTestCert(template, issuer *x509.Certificate, key crypto.Signer, ocspStaple, sctList []byte) *x509.Certificate {
if template == nil {
template = baseCertTemplate
}
if issuer == nil {
issuer = template
}
der, err := x509.CreateCertificate(rand.Reader, template, issuer, key.Public(), key)
if err != nil {
panic(fmt.Sprintf("failed to create test certificate: %s", err))
}
cert, err := x509.ParseCertificate(der)
if err != nil {
panic(fmt.Sprintf("failed to parse test certificate: %s", err))
}

return cert
}
12 changes: 0 additions & 12 deletions ssl/test/runner/ecdsa_p224_cert.pem

This file was deleted.

12 changes: 0 additions & 12 deletions ssl/test/runner/ecdsa_p256_cert.pem

This file was deleted.

15 changes: 0 additions & 15 deletions ssl/test/runner/ecdsa_p384_cert.pem

This file was deleted.

17 changes: 0 additions & 17 deletions ssl/test/runner/ecdsa_p521_cert.pem

This file was deleted.

11 changes: 0 additions & 11 deletions ssl/test/runner/ed25519_cert.pem

This file was deleted.

Loading

0 comments on commit 412018d

Please sign in to comment.