Skip to content

Commit

Permalink
Merge pull request #133 from fastly/dgryski/client-cert
Browse files Browse the repository at this point in the history
add client certificate and grpc backend builder options
  • Loading branch information
dgryski authored Aug 22, 2024
2 parents d70a99b + 49f359f commit a95214e
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 0 deletions.
27 changes: 27 additions & 0 deletions fsthttp/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

"github.com/fastly/compute-sdk-go/internal/abi/fastly"
"github.com/fastly/compute-sdk-go/secretstore"
)

var (
Expand Down Expand Up @@ -244,41 +245,67 @@ func (b *BackendOptions) UseSSL(v bool) *BackendOptions {
}

// SSLMinVersion sets the minimum allowed TLS version on SSL connections to this backend.
// Setting this will enable SSL for the connection as a side effect.
func (b *BackendOptions) SSLMinVersion(min TLSVersion) *BackendOptions {
b.abiOpts.UseSSL(true)
b.abiOpts.SSLMinVersion(fastly.TLSVersion(min))
return b
}

// SSLMaxVersion sets the maximum allowed TLS version on SSL connections to this backend.
// Setting this will enable SSL for the connection as a side effect.
func (b *BackendOptions) SSLMaxVersion(max TLSVersion) *BackendOptions {
b.abiOpts.UseSSL(true)
b.abiOpts.SSLMaxVersion(fastly.TLSVersion(max))
return b
}

// CertHostname sets the hostname that the server certificate should declare.
// Setting this will enable SSL for the connection as a side effect.
func (b *BackendOptions) CertHostname(host string) *BackendOptions {
b.abiOpts.UseSSL(true)
b.abiOpts.CertHostname(host)
return b
}

// CACert sets the CA certificate to use when checking the validity of the backend.
// Setting this will enable SSL for the connection as a side effect.
func (b *BackendOptions) CACert(cert string) *BackendOptions {
b.abiOpts.UseSSL(true)
b.abiOpts.CACert(cert)
return b
}

// Ciphers sets the list of OpenSSL ciphers to support for connections to this origin.
// Setting this will enable SSL for the connection as a side effect.
func (b *BackendOptions) Ciphers(ciphers string) *BackendOptions {
b.abiOpts.UseSSL(true)
b.abiOpts.Ciphers(ciphers)
return b
}

// SNIHostname sets the SNI hostname to use on connections to this backend.
// Setting this will enable SSL for the connection as a side effect.
func (b *BackendOptions) SNIHostname(host string) *BackendOptions {
b.abiOpts.UseSSL(true)
b.abiOpts.SNIHostname(host)
return b
}

// ClientCertificate sets the client certificate to be provided to the server as part of the SSL handshake.
// Setting this will enable SSL for the connection as a side effect.
func (b *BackendOptions) ClientCertificate(certificate string, key secretstore.Secret) *BackendOptions {
b.abiOpts.UseSSL(true)
b.abiOpts.ClientCert(certificate, key.Handle())
return b
}

// UseGRPC sets whether or not to connect to the backend via gRPC
func (b *BackendOptions) UseGRPC(v bool) *BackendOptions {
b.abiOpts.UseGRPC(v)
return b
}

// Register a new dynamic backend.
func RegisterDynamicBackend(name string, target string, options *BackendOptions) (*Backend, error) {
var abiOpts *fastly.BackendConfigOptions
Expand Down
4 changes: 4 additions & 0 deletions internal/abi/fastly/hostcalls_noguest.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,10 @@ func (s *Secret) Plaintext() ([]byte, error) {
return nil, fmt.Errorf("not implemented")
}

func (s *Secret) Handle() secretHandle {
return 0
}

func SecretFromBytes(b []byte) (*Secret, error) {
return nil, fmt.Errorf("not implemented")
}
Expand Down
4 changes: 4 additions & 0 deletions internal/abi/fastly/secret_store_guest.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ func (s *Secret) Plaintext() ([]byte, error) {
}
}

func (s *Secret) Handle() secretHandle {
return s.h
}

// witx:
//
// (@interface func (export "from_bytes")
Expand Down
24 changes: 24 additions & 0 deletions internal/abi/fastly/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,8 @@ const (
backendConfigOptionsMaskCiphers backendConfigOptionsMask = 1 << 10 // $ciphers
backendConfigOptionsMaskSNIHostname backendConfigOptionsMask = 1 << 11 // $sni_hostame
backendConfigOptionsMaskDontPool backendConfigOptionsMask = 1 << 12 // $dont_pool
backendConfigOptionsMaskClientCert backendConfigOptionsMask = 1 << 13 // $client_cert
backendConfigOptionsMaskGRPC backendConfigOptionsMask = 1 << 14 // $grpc
)

// witx:
Expand All @@ -751,6 +753,9 @@ const (
// (field $ciphers_len u32)
// (field $sni_hostname (@witx pointer (@witx char8)))
// (field $sni_hostname_len u32)
// (field $client_certificate (@witx pointer (@witx char8)))
// (field $client_certificate_len u32)
// (field $client_key $secret_handle)
// ))

type backendConfigOptions struct {
Expand All @@ -769,6 +774,9 @@ type backendConfigOptions struct {
ciphersLen prim.U32
sniHostnamePtr prim.Pointer[prim.Char8]
sniHostnameLen prim.U32
clientCertPtr prim.Pointer[prim.Char8]
clientCertLen prim.U32
clientCertKey secretHandle
}

// witx:
Expand Down Expand Up @@ -876,6 +884,22 @@ func (b *BackendConfigOptions) SNIHostname(sniHostname string) {
b.opts.sniHostnameLen = prim.U32(buf.Len())
}

func (b *BackendConfigOptions) ClientCert(certificate string, key *Secret) {
b.mask |= backendConfigOptionsMaskClientCert
buf := prim.NewReadBufferFromString(certificate)
b.opts.clientCertPtr = prim.ToPointer(buf.Char8Pointer())
b.opts.clientCertLen = prim.U32(buf.Len())
b.opts.clientCertKey = key.Handle()
}

func (b *BackendConfigOptions) UseGRPC(v bool) {
if v {
b.mask |= backendConfigOptionsMaskGRPC
} else {
b.mask &^= backendConfigOptionsMaskGRPC
}
}

// witx:
//
// (typename $send_error_detail_tag
Expand Down
7 changes: 7 additions & 0 deletions secretstore/secretstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ func (s *Secret) Plaintext() ([]byte, error) {
return plaintext, nil
}

// Handle returns an opaque pointer for other packages which need a Secret.
//
// This should not be needed by user code.
func (s *Secret) Handle() *fastly.Secret {
return s.s
}

// FromBytes creates an instance of the [Secret] type for use with APIs
// that require it from the provided byte slice.
//
Expand Down

0 comments on commit a95214e

Please sign in to comment.