-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
sebel.go
96 lines (74 loc) · 2.01 KB
/
sebel.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package sebel
import (
"fmt"
"crypto/tls"
"crypto/x509"
"net/http"
"github.com/teler-sh/sebel/pkg/cert"
"github.com/teler-sh/sebel/pkg/sslbl"
)
// Sebel holds information and [Options].
type Sebel struct {
data data
options *Options
tls *tls.ConnectionState
}
// New creates a new instance of [Sebel] with the provided options.
func New(opt ...Options) *Sebel {
sebel := new(Sebel)
if len(opt) > 0 {
sebel.options = &opt[0]
} else {
sebel.options = new(Options)
}
sebel.data.sslbl = sslbl.MustGet()
return sebel
}
// RoundTripper creates a new RoundTripper using the provided [http.RoundTripper]
// and [Sebel] instance.
func (s *Sebel) RoundTripper(rt http.RoundTripper) http.RoundTripper {
return &roundTripper{RoundTripper: rt, sebel: s}
}
// CheckTLS checks the TLS connection against the SSLBL (SSL Blacklist) and
// returns the SSLBL record.
//
// It returns [ErrSSLBlacklist] error if the certificate is blacklisted.
func (s *Sebel) CheckTLS(connState *tls.ConnectionState) (*sslbl.Record, error) {
s.tls = connState
return s.checkTLS()
}
// getCert retrieves the peer certificate from the TLS connection state.
func (s *Sebel) getCert() *x509.Certificate {
if s.tls == nil {
return nil
}
if cert := s.tls.PeerCertificates; len(cert) > 0 {
return cert[0]
}
return nil
}
// checkTLS runs actual checks on the TLS connection and returns the SSLBL
// record and [ErrSSLBlacklist] error if blacklisted.
func (s *Sebel) checkTLS() (*sslbl.Record, error) {
record, ok := new(sslbl.Record), false
// return early if disabled
if s.options.DisableSSLBlacklist {
return record, nil
}
data := s.data.sslbl
if len(data) == 0 {
return record, ErrNoSSLBLData
}
certificate := s.getCert()
if certificate == nil {
return record, nil
}
fingerprint := cert.New(certificate)
sha1sum := fingerprint.SHA1().String()
record, ok = sslbl.Find(sha1sum, data)
if ok {
reason := record.Listing.Reason
return record, fmt.Errorf("%w: %s detected", ErrSSLBlacklist, reason)
}
return record, nil
}