-
Notifications
You must be signed in to change notification settings - Fork 51
/
compactpki.go
179 lines (145 loc) · 4.68 KB
/
compactpki.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package secrets
import (
"crypto/ecdsa"
"crypto/x509"
"errors"
"go.aporeto.io/trireme-lib/controller/constants"
"go.aporeto.io/trireme-lib/controller/pkg/pkiverifier"
"go.aporeto.io/trireme-lib/utils/crypto"
"go.uber.org/zap"
)
// CompactPKI holds all PKI information
type CompactPKI struct {
PrivateKeyPEM []byte
PublicKeyPEM []byte
AuthorityPEM []byte
TokenKeyPEMs [][]byte
Compressed constants.CompressionType
privateKey *ecdsa.PrivateKey
publicKey *x509.Certificate
txKey []byte
verifier pkiverifier.PKITokenVerifier
}
// NewCompactPKI creates new secrets for PKI implementation based on compact encoding
func NewCompactPKI(keyPEM []byte, certPEM []byte, caPEM []byte, txKey []byte, compress constants.CompressionType) (*CompactPKI, error) {
zap.L().Warn("DEPRECATED. secrets.NewCompactPKI is deprecated in favor of secrets.NewCompactPKIWithTokenCA")
return NewCompactPKIWithTokenCA(keyPEM, certPEM, caPEM, [][]byte{[]byte(caPEM)}, txKey, compress)
}
// NewCompactPKIWithTokenCA creates new secrets for PKI implementation based on compact encoding
func NewCompactPKIWithTokenCA(keyPEM []byte, certPEM []byte, caPEM []byte, tokenKeyPEMs [][]byte, txKey []byte, compress constants.CompressionType) (*CompactPKI, error) {
zap.L().Debug("Initializing with Compact PKI")
key, cert, _, err := crypto.LoadAndVerifyECSecrets(keyPEM, certPEM, caPEM)
if err != nil {
return nil, err
}
var tokenKeys []*ecdsa.PublicKey
for _, ca := range tokenKeyPEMs {
caCert, err := crypto.LoadCertificate(ca)
if err != nil {
return nil, err
}
tokenKeys = append(tokenKeys, caCert.PublicKey.(*ecdsa.PublicKey))
}
if len(txKey) == 0 {
return nil, errors.New("transmit token missing")
}
p := &CompactPKI{
PrivateKeyPEM: keyPEM,
PublicKeyPEM: certPEM,
AuthorityPEM: caPEM,
TokenKeyPEMs: tokenKeyPEMs,
Compressed: compress,
privateKey: key,
publicKey: cert,
txKey: txKey,
verifier: pkiverifier.NewPKIVerifier(tokenKeys, -1),
}
return p, nil
}
// Type implements the interface Secrets
func (p *CompactPKI) Type() PrivateSecretsType {
return PKICompactType
}
// EncodingKey returns the private key
func (p *CompactPKI) EncodingKey() interface{} {
return p.privateKey
}
// PublicKey returns the public key
func (p *CompactPKI) PublicKey() interface{} {
return p.publicKey
}
// DecodingKey returns the public key
func (p *CompactPKI) DecodingKey(server string, ackKey interface{}, prevKey interface{}) (interface{}, error) {
// If we have an inband certificate, return this one
if ackKey != nil {
return ackKey.(*ecdsa.PublicKey), nil
}
// Otherwise, return the prevCert
if prevKey != nil {
return prevKey, nil
}
return nil, errors.New("invalid certificate")
}
// VerifyPublicKey verifies if the inband public key is correct.
func (p *CompactPKI) VerifyPublicKey(pkey []byte) (interface{}, error) {
return p.verifier.Verify(pkey)
}
// TransmittedKey returns the PEM of the public key in the case of PKI
// if there is no certificate cache configured
func (p *CompactPKI) TransmittedKey() []byte {
return p.txKey
}
// AckSize returns the default size of an ACK packet
func (p *CompactPKI) AckSize() uint32 {
return uint32(280)
}
// AuthPEM returns the Certificate Authority PEM
func (p *CompactPKI) AuthPEM() []byte {
return p.AuthorityPEM
}
// TokenPEMs returns the Token Certificate Authorities
func (p *CompactPKI) TokenPEMs() [][]byte {
if len(p.TokenKeyPEMs) > 0 {
return p.TokenKeyPEMs
}
return [][]byte{p.AuthPEM()}
}
// TransmittedPEM returns the PEM certificate that is transmitted
func (p *CompactPKI) TransmittedPEM() []byte {
return p.PublicKeyPEM
}
// EncodingPEM returns the certificate PEM that is used for encoding
func (p *CompactPKI) EncodingPEM() []byte {
return p.PrivateKeyPEM
}
// PublicSecrets returns the secrets that are marshallable over the RPC interface.
func (p *CompactPKI) PublicSecrets() PublicSecrets {
return &CompactPKIPublicSecrets{
Type: PKICompactType,
Key: p.PrivateKeyPEM,
Certificate: p.PublicKeyPEM,
CA: p.AuthorityPEM,
Token: p.txKey,
TokenCAs: p.TokenKeyPEMs,
Compressed: p.Compressed,
}
}
// CompactPKIPublicSecrets includes all the secrets that can be transmitted over
// the RPC interface.
type CompactPKIPublicSecrets struct {
Type PrivateSecretsType
Key []byte
Certificate []byte
CA []byte
TokenCAs [][]byte
Token []byte
Compressed constants.CompressionType
}
// SecretsType returns the type of secrets.
func (p *CompactPKIPublicSecrets) SecretsType() PrivateSecretsType {
return p.Type
}
// CertAuthority returns the cert authority
func (p *CompactPKIPublicSecrets) CertAuthority() []byte {
return p.CA
}