Skip to content

Commit

Permalink
feature: allow preloaded certs with prefork (gofiber#2351)
Browse files Browse the repository at this point in the history
* allow preloaded certs with prefork

* add to documentation

* add comments for ListenMutualTLSWithCertificate

* add test for WithCertificate

* Update benchmark.yml

* Update benchmark.yml

* Update benchmark.yml

* Update benchmark.yml

* Update benchmark.yml

* Update benchmark.yml

---------

Co-authored-by: RW <[email protected]>
  • Loading branch information
lublak and ReneWerner87 authored Mar 6, 2023
1 parent e2da854 commit 2e7e879
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,7 @@ jobs:
github-token: ${{ secrets.BENCHMARK_TOKEN }}
benchmark-data-dir-path: 'benchmarks'
fail-on-alert: true
comment-on-alert: true
comment-on-alert: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }}
# Enable Job Summary for PRs
#summary-always: ${{ github.event_name != 'push' && github.event_name != 'workflow_dispatch' }}
auto-push: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }}
46 changes: 46 additions & 0 deletions docs/api/app.md
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,27 @@ Using `ListenTLS` defaults to the following config \( use `Listener` to provide
}
```
## ListenTLSWithCertificate
```go title="Signature"
func (app *App) ListenTLS(addr string, cert tls.Certificate) error
```
```go title="Examples"
app.ListenTLSWithCertificate(":443", cert);
```
Using `ListenTLSWithCertificate` defaults to the following config \( use `Listener` to provide your own config \)
```go title="Default \*tls.Config"
&tls.Config{
MinVersion: tls.VersionTLS12,
Certificates: []tls.Certificate{
cert,
},
}
```
## ListenMutualTLS
ListenMutualTLS serves HTTPs requests from the given address using certFile, keyFile and clientCertFile are the paths to TLS certificate and key file
Expand All @@ -550,6 +571,31 @@ Using `ListenMutualTLS` defaults to the following config \( use `Listener` to pr
}
```
## ListenMutualTLSWithCertificate
ListenMutualTLSWithCertificate serves HTTPs requests from the given address using certFile, keyFile and clientCertFile are the paths to TLS certificate and key file
```go title="Signature"
func (app *App) ListenMutualTLSWithCertificate(addr string, cert tls.Certificate, clientCertPool *x509.CertPool) error
```
```go title="Examples"
app.ListenMutualTLSWithCertificate(":443", cert, clientCertPool);
```
Using `ListenMutualTLSWithCertificate` defaults to the following config \( use `Listener` to provide your own config \)
```go title="Default \*tls.Config"
&tls.Config{
MinVersion: tls.VersionTLS12,
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: clientCertPool,
Certificates: []tls.Certificate{
cert,
},
}
```
## Listener
You can pass your own [`net.Listener`](https://pkg.go.dev/net/#Listener) using the `Listener` method. This method can be used to enable **TLS/HTTPS** with a custom tls.Config.
Expand Down
16 changes: 16 additions & 0 deletions listen.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ func (app *App) ListenTLS(addr, certFile, keyFile string) error {
return fmt.Errorf("tls: cannot load TLS key pair from certFile=%q and keyFile=%q: %w", certFile, keyFile, err)
}

return app.ListenTLSWithCertificate(addr, cert)
}

// ListenTLS serves HTTPS requests from the given addr.
// cert is a tls.Certificate
//
// app.ListenTLSWithCertificate(":8080", cert)
func (app *App) ListenTLSWithCertificate(addr string, cert tls.Certificate) error {
tlsHandler := &TLSHandler{}
config := &tls.Config{
MinVersion: tls.VersionTLS12,
Expand Down Expand Up @@ -161,6 +169,14 @@ func (app *App) ListenMutualTLS(addr, certFile, keyFile, clientCertFile string)
clientCertPool := x509.NewCertPool()
clientCertPool.AppendCertsFromPEM(clientCACert)

return app.ListenMutualTLSWithCertificate(addr, cert, clientCertPool)
}

// ListenMutualTLSWithCertificate serves HTTPS requests from the given addr.
// cert is a tls.Certificate and clientCertPool is a *x509.CertPool:
//
// app.ListenMutualTLS(":8080", cert, clientCertPool)
func (app *App) ListenMutualTLSWithCertificate(addr string, cert tls.Certificate, clientCertPool *x509.CertPool) error {
tlsHandler := &TLSHandler{}
config := &tls.Config{
MinVersion: tls.VersionTLS12,
Expand Down
94 changes: 94 additions & 0 deletions listen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ package fiber
import (
"bytes"
"crypto/tls"
"crypto/x509"
"io"
"log"
"os"
"path/filepath"
"strings"
"sync"
"testing"
Expand Down Expand Up @@ -142,6 +144,98 @@ func Test_App_Listener_TLS_Listener(t *testing.T) {
utils.AssertEqual(t, nil, app.Listener(ln))
}

// go test -run Test_App_ListenTLSWithCertificate
func Test_App_ListenTLSWithCertificate(t *testing.T) {
t.Parallel()

// Create tls certificate
cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key")
if err != nil {
utils.AssertEqual(t, nil, err)
}

app := New()

// invalid port
utils.AssertEqual(t, false, app.ListenTLSWithCertificate(":99999", cer) == nil)

go func() {
time.Sleep(1000 * time.Millisecond)
utils.AssertEqual(t, nil, app.Shutdown())
}()

utils.AssertEqual(t, nil, app.ListenTLSWithCertificate(":0", cer))
}

// go test -run Test_App_ListenTLSWithCertificate_Prefork
func Test_App_ListenTLSWithCertificate_Prefork(t *testing.T) {
testPreforkMaster = true

// Create tls certificate
cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key")
if err != nil {
utils.AssertEqual(t, nil, err)
}

app := New(Config{DisableStartupMessage: true, Prefork: true})

utils.AssertEqual(t, nil, app.ListenTLSWithCertificate(":99999", cer))
}

// go test -run Test_App_ListenMutualTLSWithCertificate
func Test_App_ListenMutualTLSWithCertificate(t *testing.T) {
t.Parallel()

// Create tls certificate
cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key")
if err != nil {
utils.AssertEqual(t, nil, err)
}

// Create pool
clientCACert, err := os.ReadFile(filepath.Clean("./.github/testdata/ca-chain.cert.pem"))
if err != nil {
utils.AssertEqual(t, nil, err)
}
clientCertPool := x509.NewCertPool()
clientCertPool.AppendCertsFromPEM(clientCACert)

app := New()

// invalid port
utils.AssertEqual(t, false, app.ListenMutualTLSWithCertificate(":99999", cer, clientCertPool) == nil)

go func() {
time.Sleep(1000 * time.Millisecond)
utils.AssertEqual(t, nil, app.Shutdown())
}()

utils.AssertEqual(t, nil, app.ListenMutualTLSWithCertificate(":0", cer, clientCertPool))
}

// go test -run Test_App_ListenMutualTLS_Prefork
func Test_App_ListenMutualTLSWithCertificate_Prefork(t *testing.T) {
testPreforkMaster = true

// Create tls certificate
cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key")
if err != nil {
utils.AssertEqual(t, nil, err)
}

// Create pool
clientCACert, err := os.ReadFile(filepath.Clean("./.github/testdata/ca-chain.cert.pem"))
if err != nil {
utils.AssertEqual(t, nil, err)
}
clientCertPool := x509.NewCertPool()
clientCertPool.AppendCertsFromPEM(clientCACert)

app := New(Config{DisableStartupMessage: true, Prefork: true})

utils.AssertEqual(t, nil, app.ListenMutualTLSWithCertificate(":99999", cer, clientCertPool))
}

func captureOutput(f func()) string {
reader, writer, err := os.Pipe()
if err != nil {
Expand Down

0 comments on commit 2e7e879

Please sign in to comment.