-
Notifications
You must be signed in to change notification settings - Fork 0
/
fingerprint.go
104 lines (89 loc) · 2.65 KB
/
fingerprint.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
97
98
99
100
101
102
103
104
package sprint
import (
"bytes"
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/x509/pkix"
"errors"
"fmt"
"net/http"
"net/url"
"strings"
)
type Fingerprints struct {
MD5 string
SHA1 string
SHA256 string
SHA512 string
Issuer pkix.Name
CommonNames []string
}
func GetFingerprint(s string, disableNth bool) (*Fingerprints, error) {
urlData, _ := url.Parse(s)
requestedHost := urlData.Host
certFingerprints := Fingerprints{}
// This will handle if the client does not have the url and its just the domain name.
if requestedHost == "" && s == "" {
requestedHost = "localhost"
} else if requestedHost == "" {
requestedHost = s
}
req, _ := http.NewRequest("HEAD", "https://"+requestedHost, bytes.NewBufferString(""))
req.Header.Set("User-Agent", "GoFingerprint/2.0")
resp, err := http.DefaultClient.Do(req)
if err != nil {
// Rewrite an error from the HTTP Client to make it clear of possible causes.
if strings.Contains(err.Error(), ": no such host") {
return nil, errors.New("failed to connect or lookup host, check dns and network connection")
}
return nil, err
}
// To handle the situations where the connection fails.
if resp != nil {
tls := resp.TLS
if tls != nil {
// Try the first one for simplicity
cert := tls.PeerCertificates[0]
certFingerprints.CommonNames = cert.DNSNames
certFingerprints.Issuer = cert.Issuer
fingerprintMD5 := strings.ToUpper(fmt.Sprintf("%x", md5.Sum(cert.Raw)))
if disableNth == false {
fingerprintMD5 = insertNth(fingerprintMD5, 2)
}
certFingerprints.MD5 = fingerprintMD5
fingerprintSHA1 := strings.ToUpper(fmt.Sprintf("%x", sha1.Sum(cert.Raw)))
if disableNth == false {
fingerprintSHA1 = insertNth(fingerprintSHA1, 2)
}
certFingerprints.SHA1 = fingerprintSHA1
fingerprintSHA256 := strings.ToUpper(fmt.Sprintf("%x", sha256.Sum256(cert.Raw)))
if disableNth == false {
fingerprintSHA256 = insertNth(fingerprintSHA256, 2)
}
certFingerprints.SHA256 = fingerprintSHA256
fingerprintSHA512 := strings.ToUpper(fmt.Sprintf("%x", sha512.Sum512(cert.Raw)))
if disableNth == false {
fingerprintSHA512 = insertNth(fingerprintSHA512, 2)
}
certFingerprints.SHA512 = fingerprintSHA512
}
}
return &certFingerprints, nil
}
// insertNth inserts a set charter every nth char
// Modified, To use `:` in place of `-`
// @link https://stackoverflow.com/a/33633451/5779200
func insertNth(s string, n int) string {
var buffer bytes.Buffer
var n1 = n - 1
var l1 = len(s) - 1
for i, runei := range s {
buffer.WriteRune(runei)
if i%n == n1 && i != l1 {
buffer.WriteRune(':')
}
}
return buffer.String()
}