github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/pkg/secrets/compactpki.go (about)

     1  package secrets
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"crypto/x509"
     6  	"errors"
     7  	"time"
     8  
     9  	"go.aporeto.io/trireme-lib/controller/pkg/claimsheader"
    10  	"go.aporeto.io/trireme-lib/controller/pkg/pkiverifier"
    11  	"go.aporeto.io/trireme-lib/utils/crypto"
    12  	"go.uber.org/zap"
    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  	TokenKeyPEMs  [][]byte
    25  	Compressed    claimsheader.CompressionType
    26  	privateKey    *ecdsa.PrivateKey
    27  	publicKey     *x509.Certificate
    28  	txKey         []byte
    29  	verifier      pkiverifier.PKITokenVerifier
    30  }
    31  
    32  // NewCompactPKI creates new secrets for PKI implementation based on compact encoding
    33  func NewCompactPKI(keyPEM []byte, certPEM []byte, caPEM []byte, txKey []byte, compress claimsheader.CompressionType) (*CompactPKI, error) {
    34  
    35  	zap.L().Warn("DEPRECATED. secrets.NewCompactPKI is deprecated in favor of secrets.NewCompactPKIWithTokenCA")
    36  	return NewCompactPKIWithTokenCA(keyPEM, certPEM, caPEM, [][]byte{caPEM}, txKey, compress)
    37  }
    38  
    39  // NewCompactPKIWithTokenCA creates new secrets for PKI implementation based on compact encoding.
    40  //    keyPEM: is the private key that will be used for signing tokens formated as a PEM file.
    41  //    certPEM: is the public key that will be used formated as a PEM file.
    42  //    tokenKeyPEMs: is a list of public keys that can be used to verify the public token that
    43  //                  that is transmitted over the wire. These are essentially the public CA PEMs
    44  //                  that were used to sign the txtKey
    45  //    txKey: is the public key that is send over the wire.
    46  //    compressionType: is packed with the secrets to indicate compression.
    47  func NewCompactPKIWithTokenCA(keyPEM []byte, certPEM []byte, caPEM []byte, tokenKeyPEMs [][]byte, txKey []byte, compress claimsheader.CompressionType) (*CompactPKI, error) {
    48  
    49  	key, cert, _, err := crypto.LoadAndVerifyECSecrets(keyPEM, certPEM, caPEM)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	tokenKeys := make([]*ecdsa.PublicKey, len(tokenKeyPEMs))
    55  	for _, ca := range tokenKeyPEMs {
    56  		caCert, err := crypto.LoadCertificate(ca)
    57  		if err != nil {
    58  			return nil, err
    59  		}
    60  		tokenKeys = append(tokenKeys, caCert.PublicKey.(*ecdsa.PublicKey))
    61  	}
    62  
    63  	if len(txKey) == 0 {
    64  		return nil, errors.New("transmit token missing")
    65  	}
    66  
    67  	p := &CompactPKI{
    68  		PrivateKeyPEM: keyPEM,
    69  		PublicKeyPEM:  certPEM,
    70  		AuthorityPEM:  caPEM,
    71  		TokenKeyPEMs:  tokenKeyPEMs,
    72  		Compressed:    compress,
    73  		privateKey:    key,
    74  		publicKey:     cert,
    75  		txKey:         txKey,
    76  		verifier:      pkiverifier.NewPKIVerifier(tokenKeys, 5*time.Minute),
    77  	}
    78  
    79  	return p, nil
    80  }
    81  
    82  // Type implements the interface Secrets
    83  func (p *CompactPKI) Type() PrivateSecretsType {
    84  	return PKICompactType
    85  }
    86  
    87  // EncodingKey returns the private key
    88  func (p *CompactPKI) EncodingKey() interface{} {
    89  	return p.privateKey
    90  }
    91  
    92  // PublicKey returns the public key
    93  func (p *CompactPKI) PublicKey() interface{} {
    94  	return p.publicKey
    95  }
    96  
    97  //KeyAndClaims returns both the key and any attributes associated with the public key.
    98  func (p *CompactPKI) KeyAndClaims(pkey []byte) (interface{}, []string, time.Time, error) {
    99  	kc, err := p.verifier.Verify(pkey)
   100  	if err != nil {
   101  		return nil, nil, time.Unix(0, 0), err
   102  	}
   103  	return kc.PublicKey, kc.Tags, kc.Expiration, nil
   104  }
   105  
   106  // TransmittedKey returns the PEM of the public key in the case of PKI
   107  // if there is no certificate cache configured
   108  func (p *CompactPKI) TransmittedKey() []byte {
   109  	return p.txKey
   110  }
   111  
   112  // AckSize returns the default size of an ACK packet
   113  func (p *CompactPKI) AckSize() uint32 {
   114  	return uint32(compactPKIAckSize)
   115  }
   116  
   117  // PublicSecrets returns the secrets that are marshallable over the RPC interface.
   118  func (p *CompactPKI) PublicSecrets() PublicSecrets {
   119  	return &CompactPKIPublicSecrets{
   120  		Type:        PKICompactType,
   121  		Key:         p.PrivateKeyPEM,
   122  		Certificate: p.PublicKeyPEM,
   123  		CA:          p.AuthorityPEM,
   124  		Token:       p.txKey,
   125  		TokenCAs:    p.TokenKeyPEMs,
   126  		Compressed:  p.Compressed,
   127  	}
   128  }
   129  
   130  // CompactPKIPublicSecrets includes all the secrets that can be transmitted over
   131  // the RPC interface.
   132  type CompactPKIPublicSecrets struct {
   133  	Type        PrivateSecretsType
   134  	Key         []byte
   135  	Certificate []byte
   136  	CA          []byte
   137  	TokenCAs    [][]byte
   138  	Token       []byte
   139  	Compressed  claimsheader.CompressionType
   140  }
   141  
   142  // SecretsType returns the type of secrets.
   143  func (p *CompactPKIPublicSecrets) SecretsType() PrivateSecretsType {
   144  	return p.Type
   145  }
   146  
   147  // CertAuthority returns the cert authority
   148  func (p *CompactPKIPublicSecrets) CertAuthority() []byte {
   149  	return p.CA
   150  }