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  }