forked from gravitational/teleport
-
Notifications
You must be signed in to change notification settings - Fork 0
/
interfaces.go
94 lines (81 loc) · 2.64 KB
/
interfaces.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
/*
Copyright 2015 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package client
import (
"bytes"
"time"
"github.com/gravitational/trace"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
)
// Key describes a complete (signed) client key
type Key struct {
Priv []byte `json:"Priv,omitempty"`
Pub []byte `json:"Pub,omitempty"`
Cert []byte `json:"Cert,omitempty"`
// ProxyHost (optionally) contains the hostname of the proxy server
// which issued this key
ProxyHost string
}
// LocalKeyStore interface allows for different storage back-ends for TSH to load/save its keys
type LocalKeyStore interface {
// client key management
GetKeys(username string) ([]Key, error)
AddKey(host string, username string, key *Key) error
GetKey(host string, username string) (*Key, error)
DeleteKey(host string, username string) error
// interface to known_hosts file:
AddKnownHostKeys(hostname string, keys []ssh.PublicKey) error
GetKnownHostKeys(hostname string) ([]ssh.PublicKey, error)
}
// AsAgentKey converts our Key structure to ssh.Agent.Key
func (k *Key) AsAgentKey() (*agent.AddedKey, error) {
// parse the returned&signed key:
pcert, _, _, _, err := ssh.ParseAuthorizedKey(k.Cert)
if err != nil {
return nil, trace.Wrap(err)
}
pk, err := ssh.ParseRawPrivateKey(k.Priv)
if err != nil {
return nil, trace.Wrap(err)
}
return &agent.AddedKey{
PrivateKey: pk,
Certificate: pcert.(*ssh.Certificate),
Comment: "",
LifetimeSecs: 0,
ConfirmBeforeUse: false,
}, nil
}
// EqualsTo returns true if this key is the same as the other.
// Primarily used in tests
func (k *Key) EqualsTo(other *Key) bool {
if k == other {
return true
}
return bytes.Equal(k.Cert, other.Cert) &&
bytes.Equal(k.Priv, other.Priv) &&
bytes.Equal(k.Pub, other.Pub)
}
// CertValidBefore returns the time of the cert expiration
func (k *Key) CertValidBefore() (t time.Time, err error) {
pcert, _, _, _, err := ssh.ParseAuthorizedKey(k.Cert)
if err != nil {
return t, trace.Wrap(err)
}
cert, ok := pcert.(*ssh.Certificate)
if !ok {
return t, trace.Errorf("not supported certificate type")
}
return time.Unix(int64(cert.ValidBefore), 0), nil
}