-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinspect.go
111 lines (97 loc) · 2.84 KB
/
inspect.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
105
106
107
108
109
110
111
// source: https://github.com/smallstep/cli/blob/7f2d5f4cf96df302a913c5715f718851aaf5267c/internal/sshutil/sshutil.go
package main
import (
"fmt"
"time"
"golang.org/x/crypto/ssh"
)
// using the same layout than ssh-keygen
const certificateInspectLayout = "2006-01-02T15:04:05"
// CertificateInspect contains details of an ssh.Certificate in human readable
// format.
type CertificateInspect struct {
Type string
KeyName string
KeyID string
KeyAlgo string
KeyFingerprint string
SigningKeyAlgo string
SigningKeyFingerprint string
Signature Signature
Serial uint64
ValidAfter time.Time
ValidBefore time.Time
Principals []string
CriticalOptions map[string]string
Extensions map[string]string
}
type Signature struct {
Type string
Value []byte
Rest []byte `json:",omitempty"`
}
// InspectCertificate returns a CertificateInspect with the properties of the
// given ssh.Certificate.
func InspectCertificate(cert *ssh.Certificate) (*CertificateInspect, error) {
var certType string
var validAfter, validBefore time.Time
switch cert.CertType {
case ssh.HostCert:
certType = "host"
case ssh.UserCert:
certType = "user"
default:
certType = "unknown"
}
algo, sum, err := inspectPublicKey(cert.Key)
if err != nil {
return nil, err
}
sigAlgo, sigSum, err := inspectPublicKey(cert.SignatureKey)
if err != nil {
return nil, err
}
validAfter = time.Unix(int64(cert.ValidAfter), 0)
if cert.ValidBefore != ssh.CertTimeInfinity {
validBefore = time.Unix(int64(cert.ValidBefore), 0)
}
return &CertificateInspect{
Type: certType,
KeyName: cert.Type(),
KeyID: cert.KeyId,
KeyAlgo: algo,
KeyFingerprint: sum,
SigningKeyAlgo: sigAlgo,
SigningKeyFingerprint: sigSum,
Signature: Signature{
Type: cert.Signature.Format,
Value: cert.Signature.Blob,
Rest: cert.Signature.Rest,
},
Serial: cert.Serial,
ValidAfter: validAfter,
ValidBefore: validBefore,
Principals: cert.ValidPrincipals,
CriticalOptions: cert.CriticalOptions,
Extensions: cert.Extensions,
}, nil
}
// Validity returns a human version of the validity of the certificate. It
// returns the dates using the local time zone to behave as ssh-keygen.
func (c *CertificateInspect) Validity() string {
if c.ValidBefore.IsZero() {
return "forever"
}
return fmt.Sprintf("from %s to %s",
c.ValidAfter.Local().Format(certificateInspectLayout),
c.ValidBefore.Local().Format(certificateInspectLayout),
)
}
func inspectPublicKey(key ssh.PublicKey) (string, string, error) {
fp := ssh.FingerprintSHA256(key)
typ, _, err := publicKeyTypeAndSize(key)
if err != nil {
return "", "", err
}
return typ, fp, nil
}