github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/pkg/secrets/compactpki/compactpki.go (about) 1 package compactpki 2 3 import ( 4 "crypto/ecdsa" 5 "crypto/x509" 6 "errors" 7 "time" 8 9 "go.aporeto.io/enforcerd/trireme-lib/controller/pkg/claimsheader" 10 "go.aporeto.io/enforcerd/trireme-lib/controller/pkg/pkiverifier" 11 "go.aporeto.io/enforcerd/trireme-lib/controller/pkg/secrets" 12 "go.aporeto.io/enforcerd/trireme-lib/utils/crypto" 13 ) 14 15 const ( 16 compactPKIAckSize = 300 17 ) 18 19 // CompactPKI holds all PKI information 20 type CompactPKI struct { 21 privateKeyPEM []byte 22 publicKeyPEM []byte 23 authorityPEM []byte 24 trustedControllers []*secrets.ControllerInfo 25 compressed claimsheader.CompressionType 26 privateKey *ecdsa.PrivateKey 27 publicKey *x509.Certificate 28 txKey []byte 29 verifier pkiverifier.PKITokenVerifier 30 } 31 32 // NewCompactPKIWithTokenCA creates new secrets for PKI implementation based on compact encoding. 33 // keyPEM: is the private key that will be used for signing tokens formated as a PEM file. 34 // certPEM: is the public key that will be used formated as a PEM file. 35 // trustedControllers: is a list of trusted controllers. 36 // txKey: is the public key that is send over the wire. 37 // compressionType: is packed with the secrets to indicate compression. 38 func NewCompactPKIWithTokenCA(keyPEM []byte, certPEM []byte, caPEM []byte, trustedControllers []*secrets.ControllerInfo, txKey []byte, compress claimsheader.CompressionType) (*CompactPKI, error) { 39 40 key, cert, _, err := crypto.LoadAndVerifyECSecrets(keyPEM, certPEM, caPEM) 41 if err != nil { 42 return nil, err 43 } 44 45 tokenKeys := make([]*pkiverifier.PKIPublicKey, len(trustedControllers)) 46 for _, tokenKey := range trustedControllers { 47 caCert, err := crypto.LoadCertificate(tokenKey.PublicKey) 48 if err != nil { 49 return nil, err 50 } 51 52 namespaceKey := &pkiverifier.PKIPublicKey{ 53 PublicKey: caCert.PublicKey.(*ecdsa.PublicKey), 54 Controller: tokenKey.Controller, 55 } 56 57 tokenKeys = append(tokenKeys, namespaceKey) 58 } 59 60 if len(txKey) == 0 { 61 return nil, errors.New("transmit token missing") 62 } 63 64 p := &CompactPKI{ 65 privateKeyPEM: keyPEM, 66 publicKeyPEM: certPEM, 67 authorityPEM: caPEM, 68 trustedControllers: trustedControllers, 69 compressed: compress, 70 privateKey: key, 71 publicKey: cert, 72 txKey: txKey, 73 verifier: pkiverifier.NewPKIVerifier(tokenKeys, 5*time.Minute), 74 } 75 76 return p, nil 77 } 78 79 // EncodingKey returns the private key 80 func (p *CompactPKI) EncodingKey() interface{} { 81 return p.privateKey 82 } 83 84 // PublicKey returns the public key 85 func (p *CompactPKI) PublicKey() interface{} { 86 return p.publicKey 87 } 88 89 // CertAuthority returns the cert authority 90 func (p *CompactPKI) CertAuthority() []byte { 91 return p.authorityPEM 92 } 93 94 //KeyAndClaims returns both the key and any attributes associated with the public key. 95 func (p *CompactPKI) KeyAndClaims(pkey []byte) (interface{}, []string, time.Time, *pkiverifier.PKIControllerInfo, error) { 96 kc, err := p.verifier.Verify(pkey) 97 if err != nil { 98 return nil, nil, time.Unix(0, 0), nil, err 99 } 100 return kc.PublicKey, kc.Tags, kc.Expiration, kc.Controller, nil 101 } 102 103 // TransmittedKey returns the PEM of the public key in the case of PKI 104 // if there is no certificate cache configured 105 func (p *CompactPKI) TransmittedKey() []byte { 106 return p.txKey 107 } 108 109 // AckSize returns the default size of an ACK packet 110 func (p *CompactPKI) AckSize() uint32 { 111 return uint32(compactPKIAckSize) 112 } 113 114 // RPCSecrets returns the secrets that are marshallable over the RPC interface. 115 func (p *CompactPKI) RPCSecrets() secrets.RPCSecrets { 116 return secrets.RPCSecrets{ 117 Key: p.privateKeyPEM, 118 Certificate: p.publicKeyPEM, 119 CA: p.authorityPEM, 120 Token: p.txKey, 121 TrustedControllers: p.trustedControllers, 122 Compressed: p.compressed, 123 } 124 }