go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/network/resources/certificates/cert.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package certificates 5 6 import ( 7 "crypto/md5" 8 "crypto/sha1" 9 "crypto/sha256" 10 "crypto/tls" 11 "crypto/x509" 12 "encoding/hex" 13 "fmt" 14 "net" 15 "time" 16 ) 17 18 var cipherSuites = map[string]uint16{ 19 // TLS 1.0 - 1.2 cipher suites. 20 "TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA, 21 "TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, 22 "TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA, 23 "TLS_RSA_WITH_AES_256_CBC_SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA, 24 "TLS_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_RSA_WITH_AES_128_CBC_SHA256, 25 "TLS_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_RSA_WITH_AES_128_GCM_SHA256, 26 "TLS_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_RSA_WITH_AES_256_GCM_SHA384, 27 "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 28 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 29 "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 30 "TLS_ECDHE_RSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, 31 "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 32 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 33 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 34 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 35 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 36 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 37 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 38 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 39 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 40 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 41 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 42 43 // TLS 1.3 cipher suites. 44 "TLS_AES_128_GCM_SHA256": tls.TLS_AES_128_GCM_SHA256, 45 "TLS_AES_256_GCM_SHA384": tls.TLS_AES_256_GCM_SHA384, 46 } 47 48 var userTempl string 49 50 var TimeoutSeconds = 3 51 52 func cipherSuite(suite string) ([]uint16, error) { 53 if suite == "" { 54 return nil, nil 55 } 56 57 var cs []uint16 58 cs = []uint16{cipherSuites[suite]} 59 if cs[0] == 0 { 60 return nil, fmt.Errorf("%s is unsupported cipher suite or tls1.3 cipher suite.", suite) 61 } 62 return cs, nil 63 } 64 65 func tlsVersion(suite string) uint16 { 66 if suite != "" { 67 return tls.VersionTLS12 68 } 69 // Currently TLS 1.3 70 return 0 71 } 72 73 var gatherPeerCertificates = func(host, port string, ciphersuite string, insecureskipverify bool) ([]*x509.Certificate, error) { 74 d := &net.Dialer{ 75 Timeout: time.Duration(TimeoutSeconds) * time.Second, 76 } 77 78 cs, err := cipherSuite(ciphersuite) 79 if err != nil { 80 return nil, err 81 } 82 83 conn, err := tls.DialWithDialer(d, "tcp", host+":"+port, &tls.Config{ 84 InsecureSkipVerify: insecureskipverify, 85 CipherSuites: cs, 86 MaxVersion: tlsVersion(ciphersuite), 87 }) 88 if err != nil { 89 return nil, err 90 } 91 defer conn.Close() 92 93 // addr := conn.RemoteAddr() 94 // ip, _, _ := net.SplitHostPort(addr.String()) 95 cert := conn.ConnectionState().PeerCertificates 96 97 return cert, nil 98 } 99 100 func Fetch(hostport string) ([]*x509.Certificate, error) { 101 host, port, err := net.SplitHostPort(hostport) 102 if err != nil { 103 return nil, err 104 } 105 106 return gatherPeerCertificates(host, port, "", true) 107 } 108 109 func HexEncodeToHumanString(b []byte) string { 110 if len(b) == 0 { 111 return "" 112 } 113 buf := make([]byte, 0, 3*len(b)) 114 x := buf[1*len(b) : 3*len(b)] 115 hex.Encode(x, b) 116 for i := 0; i < len(x); i += 2 { 117 buf = append(buf, x[i], x[i+1], ':') 118 } 119 return string(buf[:len(buf)-1]) 120 } 121 122 func Sha1Hash(cert *x509.Certificate) []byte { 123 h := sha1.New() 124 if cert != nil { 125 h.Write(cert.Raw) 126 } 127 return h.Sum(nil) 128 } 129 130 func Sha256Hash(cert *x509.Certificate) []byte { 131 h := sha256.New() 132 if cert != nil { 133 h.Write(cert.Raw) 134 } 135 return h.Sum(nil) 136 } 137 138 func Md5Hash(cert *x509.Certificate) []byte { 139 h := md5.New() 140 if cert != nil { 141 h.Write(cert.Raw) 142 } 143 return h.Sum(nil) 144 } 145 146 func Fingerprints(cert *x509.Certificate) map[string]interface{} { 147 return map[string]interface{}{ 148 "sha1": hex.EncodeToString(Sha1Hash(cert)), 149 "sha256": hex.EncodeToString(Sha256Hash(cert)), 150 "md5": hex.EncodeToString(Md5Hash(cert)), 151 } 152 }