-
Notifications
You must be signed in to change notification settings - Fork 51
/
compactpki.go
150 lines (128 loc) · 4.45 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
package secrets
import (
"crypto/ecdsa"
"crypto/x509"
"errors"
"time"
"go.aporeto.io/trireme-lib/controller/pkg/claimsheader"
"go.aporeto.io/trireme-lib/controller/pkg/pkiverifier"
"go.aporeto.io/trireme-lib/utils/crypto"
"go.uber.org/zap"
)
const (
compactPKIAckSize = 300
)
// CompactPKI holds all PKI information
type CompactPKI struct {
PrivateKeyPEM []byte
PublicKeyPEM []byte
AuthorityPEM []byte
TokenKeyPEMs [][]byte
Compressed claimsheader.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 claimsheader.CompressionType) (*CompactPKI, error) {
zap.L().Warn("DEPRECATED. secrets.NewCompactPKI is deprecated in favor of secrets.NewCompactPKIWithTokenCA")
return NewCompactPKIWithTokenCA(keyPEM, certPEM, caPEM, [][]byte{caPEM}, txKey, compress)
}
// NewCompactPKIWithTokenCA creates new secrets for PKI implementation based on compact encoding.
// keyPEM: is the private key that will be used for signing tokens formated as a PEM file.
// certPEM: is the public key that will be used formated as a PEM file.
// tokenKeyPEMs: is a list of public keys that can be used to verify the public token that
// that is transmitted over the wire. These are essentially the public CA PEMs
// that were used to sign the txtKey
// txKey: is the public key that is send over the wire.
// compressionType: is packed with the secrets to indicate compression.
func NewCompactPKIWithTokenCA(keyPEM []byte, certPEM []byte, caPEM []byte, tokenKeyPEMs [][]byte, txKey []byte, compress claimsheader.CompressionType) (*CompactPKI, error) {
key, cert, _, err := crypto.LoadAndVerifyECSecrets(keyPEM, certPEM, caPEM)
if err != nil {
return nil, err
}
tokenKeys := make([]*ecdsa.PublicKey, len(tokenKeyPEMs))
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, 5*time.Minute),
}
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
}
//KeyAndClaims returns both the key and any attributes associated with the public key.
func (p *CompactPKI) KeyAndClaims(pkey []byte) (interface{}, []string, time.Time, error) {
kc, err := p.verifier.Verify(pkey)
if err != nil {
return nil, nil, time.Unix(0, 0), err
}
return kc.PublicKey, kc.Tags, kc.Expiration, nil
}
// 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(compactPKIAckSize)
}
// 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 claimsheader.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
}