-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcertificate.go
60 lines (47 loc) · 1.68 KB
/
certificate.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
package sshx
import (
"fmt"
"os"
"time"
"golang.org/x/crypto/ssh"
)
// NewCertificateFromOpenSSHAuthorizedKeyBytes creates a certificate from an authorized ssh key formatted bytes.
func NewCertificateFromOpenSSHAuthorizedKeyBytes(raw []byte) (*Certificate, error) {
cert, _, _, _, err := ssh.ParseAuthorizedKey(raw)
if err != nil {
return nil, fmt.Errorf("unable to parse ssh certificate from raw openssh certificate: %v", err)
}
if cert, ok := cert.(*ssh.Certificate); ok {
return (*Certificate)(cert), nil
}
return nil, fmt.Errorf("parsed authorized key is not a certificate but %T", cert)
}
// NewCertificateFromOpenSSHAuthorizedKeyFile creates a certificate from an authorized ssh key formatted file.
func NewCertificateFromOpenSSHAuthorizedKeyFile(filePath string) (*Certificate, error) {
rawFile, err := os.ReadFile(filePath) //nolint:gosec // G304 is a choice here
if err != nil {
return nil, fmt.Errorf("unable to read %q file: %w", filePath, err)
}
cert, err := NewCertificateFromOpenSSHAuthorizedKeyBytes(rawFile)
if err != nil {
return nil, err
}
return cert, nil
}
// Certificate aliases ssh.Certificate to extend it.
type Certificate ssh.Certificate
// IsValid returns true if a certificate is valid.
func (c Certificate) IsValid() error {
now := time.Now()
if validAfter := time.Unix(int64(c.ValidAfter), 0); c.ValidAfter != 0 {
if now.Before(validAfter) {
return fmt.Errorf("certificate validity starts in %s", time.Until(validAfter))
}
}
if validBefore := time.Unix(int64(c.ValidBefore), 0); c.ValidBefore != 0 {
if now.After(validBefore) {
return fmt.Errorf("certificate validity expired %s ago", time.Until(validBefore)*-1)
}
}
return nil
}