Skip to content

Commit 4f5cb26

Browse files
TLS authentication working
1 parent 65555c9 commit 4f5cb26

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

armor.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package armor
22

33
import (
4+
"crypto/tls"
45
"sync"
56
"time"
67

@@ -75,6 +76,8 @@ type (
7576
Paths Paths `json:"paths"`
7677
Plugins []plugin.Plugin `json:"-"`
7778
Echo *echo.Echo `json:"-"`
79+
ClientCAs []string `json:"client_ca_der"`
80+
TLSConfig *tls.Config `json:"-"`
7881
}
7982

8083
Path struct {

http.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ func (a *Armor) NewHTTP() (h *HTTP) {
4949
ReadTimeout: a.ReadTimeout * time.Second,
5050
WriteTimeout: a.WriteTimeout * time.Second,
5151
}
52+
e.TLSServer.TLSConfig.GetConfigForClient = a.GetConfigForClient
5253
e.AutoTLSManager.Email = a.TLS.Email
5354
e.AutoTLSManager.Client = new(acme.Client)
5455
if a.TLS.DirectoryURL != "" {

tls.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package armor
2+
3+
import (
4+
"crypto/tls"
5+
"crypto/x509"
6+
"encoding/base64"
7+
)
8+
9+
// GetConfigForClient implements the
10+
func (a *Armor) GetConfigForClient(clientHelloInfo *tls.ClientHelloInfo) (*tls.Config, error) {
11+
// Get the host from the hello info
12+
host := a.Hosts[clientHelloInfo.ServerName]
13+
if len(host.ClientCAs) == 0 {
14+
return nil, nil
15+
}
16+
17+
// Use existing host config if exist
18+
if host.TLSConfig != nil {
19+
return host.TLSConfig, nil
20+
}
21+
22+
// Build and save the host config
23+
host.TLSConfig = a.buildTLSConfig(clientHelloInfo, host)
24+
25+
return host.TLSConfig, nil
26+
}
27+
28+
func (a *Armor) buildTLSConfig(clientHelloInfo *tls.ClientHelloInfo, host *Host) *tls.Config {
29+
// Copy the configurations from the regular server
30+
tlsConfig := new(tls.Config)
31+
*tlsConfig = *a.Echo.TLSServer.TLSConfig
32+
33+
// Set the client validation and the certification pool
34+
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
35+
tlsConfig.ClientCAs = a.buildClientCertPool(host)
36+
37+
return tlsConfig
38+
}
39+
40+
func (a *Armor) buildClientCertPool(host *Host) (certPool *x509.CertPool) {
41+
certPool = x509.NewCertPool()
42+
43+
// Loop every CA certs given as base64 DER encoding
44+
for _, clientCAString := range host.ClientCAs {
45+
// Decode base64
46+
derBytes, err := base64.StdEncoding.DecodeString(clientCAString)
47+
if err != nil {
48+
continue
49+
}
50+
if len(derBytes) == 0 {
51+
continue
52+
}
53+
54+
// Parse the DER encoded certificate
55+
var caCert *x509.Certificate
56+
caCert, err = x509.ParseCertificate(derBytes)
57+
if err != nil {
58+
continue
59+
}
60+
61+
// Add the certificate to CertPool
62+
certPool.AddCert(caCert)
63+
}
64+
65+
return certPool
66+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy