Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/gencerts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ func writePKCS1KeyPair(dir, name string, key *rsa.PrivateKey, certDER []byte) er

// Write private key
keyDER := x509.MarshalPKCS1PrivateKey(key)
if err := writePEM(keyPath, "EC PRIVATE KEY", keyDER); err != nil {
if err := writePEM(keyPath, "RSA PRIVATE KEY", keyDER); err != nil {
return err
}

Expand Down
40 changes: 40 additions & 0 deletions client/runtime_tls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ package client

import (
"crypto"
"crypto/ed25519"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/json"
"errors"
"math/big"
"net/http"
"net/http/httptest"
"net/url"
Expand Down Expand Up @@ -67,6 +71,19 @@ func TestRuntimeTLSOptions(t *testing.T) {
assert.Len(t, cfg.Certificates, 1)
})

t.Run("with TLSAuthConfig configured with loaded Ed25519 key/certificate", func(t *testing.T) {
edKey, edCert := newEd25519KeyCert(t)
opts := TLSClientOptions{
LoadedKey: edKey,
LoadedCertificate: edCert,
}

cfg, err := TLSClientAuth(opts)
require.NoError(t, err)
require.NotNil(t, cfg)
assert.Len(t, cfg.Certificates, 1)
})

t.Run("with TLSAuthConfig configured with loaded Certificate Authority", func(t *testing.T) {
opts := TLSClientOptions{
LoadedCA: fixtures.RSA.LoadedCA,
Expand Down Expand Up @@ -259,6 +276,29 @@ type (
}
)

func newEd25519KeyCert(t testing.TB) (ed25519.PrivateKey, *x509.Certificate) {
t.Helper()

pub, priv, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)

template := &x509.Certificate{
SerialNumber: big.NewInt(42),
Subject: pkix.Name{CommonName: "ed25519-test"},
NotBefore: time.Now().Add(-time.Hour),
NotAfter: time.Now().Add(time.Hour),
KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
}

der, err := x509.CreateCertificate(rand.Reader, template, template, pub, priv)
require.NoError(t, err)
cert, err := x509.ParseCertificate(der)
require.NoError(t, err)

return priv, cert
}

func systemCAPool(t testing.TB) *x509.CertPool {
if goruntime.GOOS == "windows" {
// Windows doesn't have the system cert pool.
Expand Down
24 changes: 7 additions & 17 deletions client/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@ package client

import (
"crypto"
"crypto/ecdsa"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"net/http"
"os"
Expand Down Expand Up @@ -47,7 +44,7 @@ type TLSClientOptions struct {

// LoadedCAPool specifies a pool of RootCAs to use when validating the server's TLS certificate.
// If set, it will be combined with the other loaded certificates (see LoadedCA and CA).
// If neither LoadedCA or CA is set, the provided pool with override the system
// If neither LoadedCA or CA is set, the provided pool will override the system
// certificate pool.
// The caller must not use the supplied pool after calling TLSClientAuth.
LoadedCAPool *x509.CertPool
Expand Down Expand Up @@ -114,18 +111,11 @@ func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
block := pem.Block{Type: "CERTIFICATE", Bytes: opts.LoadedCertificate.Raw}
certPem := pem.EncodeToMemory(&block)

var keyBytes []byte
switch k := opts.LoadedKey.(type) {
case *rsa.PrivateKey:
keyBytes = x509.MarshalPKCS1PrivateKey(k)
case *ecdsa.PrivateKey:
var err error
keyBytes, err = x509.MarshalECPrivateKey(k)
if err != nil {
return nil, fmt.Errorf("tls client priv key: %v", err)
}
default:
return nil, errors.New("tls client priv key: unsupported key type")
// PKCS#8 covers RSA, ECDSA, Ed25519, X25519 (the key types tls.X509KeyPair
// understands) and pairs with the canonical "PRIVATE KEY" PEM label.
keyBytes, err := x509.MarshalPKCS8PrivateKey(opts.LoadedKey)
if err != nil {
return nil, fmt.Errorf("tls client priv key: %v", err)
}

block = pem.Block{Type: "PRIVATE KEY", Bytes: keyBytes}
Expand Down Expand Up @@ -166,7 +156,7 @@ func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
cfg.RootCAs = opts.LoadedCAPool
}

// apply servername overrride
// apply servername override
if opts.ServerName != "" {
cfg.InsecureSkipVerify = false
cfg.ServerName = opts.ServerName
Expand Down
Loading