-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Marco Paoletti
committed
Feb 19, 2024
0 parents
commit d0d6187
Showing
8 changed files
with
231 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
.vscode/ | ||
.idea/ | ||
localhost.crt | ||
localhost.key | ||
localCA.crt | ||
.golangci.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
Esempio di utilizzo: | ||
|
||
```go | ||
func main() { | ||
// crea il tuo mux | ||
mux := http.NewServeMux() | ||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { | ||
_, _ = w.Write([]byte("hello server")) | ||
}) | ||
// crea il Trust con i tuoi certificati self signed | ||
t, err := https.NewTrust("localhost.crt", "localhost.key", "localCA.crt", tls.RequireAndVerifyClientCert) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
// avvia il server HTTPS | ||
if e := t.StartServer(mux, 8080); e != nil { | ||
log.Fatal(e) | ||
} | ||
} | ||
``` | ||
|
||
La cartella `sample` contiene un esempio di esecuzione. È necessario avere i certificati self signed creati | ||
con lo script `certs.sh`; utilizzando [Task](https://taskfile.dev/) viene fatto tutto in automatico come riportato | ||
nell'esempio di output qui di seguito | ||
|
||
```bash | ||
$> task sample | ||
|
||
task: [sample] go run main.go | ||
2024/02/19 14:52:42 server started at port 8080 | ||
2024/02/19 14:52:43 ***** Trusted client: | ||
2024/02/19 14:52:43 > hello server | ||
2024/02/19 14:52:43 ***** Bad client error: | ||
2024/02/19 14:52:43 http: TLS handshake error from [::1]:59274: remote error: tls: bad certificate | ||
2024/02/19 14:52:43 Get "https://localhost:8080": tls: failed to verify certificate: x509: certificate signed by unknown authority | ||
2024/02/19 14:52:43 Server closed, BYE :) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
version: "3" | ||
|
||
tasks: | ||
lint: | ||
cmds: | ||
- golangci-lint cache clean && golangci-lint run ./... | ||
cert: | ||
dir: ./sample | ||
cmds: | ||
- chmod +x certs.sh | ||
- ./certs.sh | ||
clean: | ||
dir: ./sample | ||
cmds: | ||
- rm localCA.crt localhost.crt localhost.key | ||
test: | ||
cmds: | ||
- task: lint | ||
- task: cert | ||
- go test -race -count=1 ./... -v -cover | ||
- task: clean | ||
sample: | ||
dir: ./sample | ||
cmds: | ||
- task: cert | ||
- go run main.go |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module ssc | ||
|
||
go 1.22.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#!/bin/bash | ||
|
||
# CA cert | ||
openssl req -new -newkey rsa:2048 -days 3650 -extensions v3_ca -nodes -x509 -sha256 -set_serial 0 \ | ||
-keyout localCA.key -out localCA.crt -subj "/CN=RootCA/" | ||
# Certificate Signing Request | ||
openssl req -new -newkey rsa:2048 -nodes -keyout localhost.key -out localhost.csr \ | ||
-config request.cnf -extensions v3_req | ||
# Self-Signing | ||
openssl x509 -req -sha256 -CAcreateserial -in localhost.csr -days 3650 -CA localCA.crt \ | ||
-CAkey localCA.key -out localhost.crt -extfile <(printf "subjectAltName=DNS:localhost") | ||
|
||
rm localhost.csr localCA.key localCA.srl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package main | ||
|
||
import ( | ||
"crypto/tls" | ||
"io" | ||
"log" | ||
"net/http" | ||
"time" | ||
|
||
"ssc" | ||
) | ||
|
||
func main() { | ||
t, err := ssc.NewTrust("localhost.crt", "localhost.key", "localCA.crt", tls.RequireAndVerifyClientCert) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
mux := http.NewServeMux() | ||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { | ||
_, _ = w.Write([]byte("hello server")) | ||
}) | ||
go func() { | ||
log.Println("server started at port 8080") | ||
if e := t.StartServer(mux, 8080); e != nil { | ||
log.Fatal(e) | ||
} | ||
}() | ||
time.Sleep(1 * time.Second) | ||
client := t.Client(10 * time.Second) | ||
resp, err := client.Get("https://localhost:8080") | ||
if err != nil { | ||
log.Println(err) | ||
} | ||
body := resp.Body | ||
b, _ := io.ReadAll(body) | ||
resp.Body.Close() | ||
log.Println("***** Trusted client:") | ||
log.Printf("> %s\n", string(b)) | ||
log.Println("***** Bad client error:") | ||
_, err = http.Get("https://localhost:8080") | ||
if err != nil { | ||
log.Println(err) | ||
} | ||
log.Println("Server closed, BYE :)") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
[req] | ||
distinguished_name = req_distinguished_name | ||
x509_extensions = v3_req | ||
req_extensions = req_ext | ||
prompt = no | ||
[req_distinguished_name] | ||
C = IT | ||
ST = Italia | ||
L = Florence | ||
O = development | ||
OU = development | ||
CN = localhost | ||
[v3_req] | ||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment | ||
extendedKeyUsage = serverAuth | ||
[req_ext] | ||
subjectAltName = @alt_names | ||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment | ||
extendedKeyUsage = serverAuth | ||
[alt_names] | ||
DNS.1 = localhost |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package ssc | ||
|
||
import ( | ||
"crypto/tls" | ||
"crypto/x509" | ||
"fmt" | ||
"net/http" | ||
"os" | ||
"time" | ||
) | ||
|
||
// Trust raccoglie gli elementi di certificazione della connessione | ||
type Trust struct { | ||
Cert tls.Certificate | ||
Pool *x509.CertPool | ||
cert string | ||
key string | ||
ClientAuth tls.ClientAuthType | ||
} | ||
|
||
// NewTrust crea un nuovo trust a partire dai certificati passati come argomento | ||
func NewTrust(certificate, key, ca string, auth tls.ClientAuthType) (*Trust, error) { | ||
root, err := os.ReadFile(ca) | ||
if err != nil { | ||
return nil, err | ||
} | ||
pool, err := x509.SystemCertPool() | ||
if err != nil { | ||
return nil, err | ||
} | ||
pool.AppendCertsFromPEM(root) | ||
c, err := tls.LoadX509KeyPair(certificate, key) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &Trust{ | ||
Pool: pool, | ||
Cert: c, | ||
ClientAuth: auth, | ||
cert: certificate, | ||
key: key, | ||
}, nil | ||
} | ||
|
||
// Client crea client HTTP con certificati trusted | ||
func (t *Trust) Client(timeout time.Duration) *http.Client { | ||
return &http.Client{ | ||
Transport: t.transport(), | ||
Timeout: timeout, | ||
} | ||
} | ||
|
||
// StartServer avvia un server HTTPS configurato per gestire le richieste definite dal Trust | ||
func (t *Trust) StartServer(mux *http.ServeMux, port int) error { | ||
server := &http.Server{ | ||
Addr: fmt.Sprintf(":%d", port), | ||
ReadTimeout: 10 * time.Second, | ||
WriteTimeout: 10 * time.Second, | ||
IdleTimeout: 30 * time.Second, | ||
Handler: mux, | ||
TLSConfig: &tls.Config{ | ||
MinVersion: tls.VersionTLS12, | ||
ClientCAs: t.Pool, | ||
ClientAuth: t.ClientAuth, | ||
}, | ||
} | ||
return server.ListenAndServeTLS(t.cert, t.key) | ||
} | ||
|
||
// transport crea un Transport certificato | ||
func (t *Trust) transport() *http.Transport { | ||
return &http.Transport{ | ||
TLSClientConfig: &tls.Config{ | ||
MinVersion: tls.VersionTLS12, | ||
Certificates: []tls.Certificate{t.Cert}, | ||
RootCAs: t.Pool, | ||
}, | ||
DisableKeepAlives: false, | ||
} | ||
} |