github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/internal/enforcer/utils/ephemeralkeys/ephemeralkeys.go (about)

     1  package ephemeralkeys
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"crypto/elliptic"
     6  	"crypto/rand"
     7  	"sync"
     8  	"time"
     9  
    10  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/secrets"
    11  	"go.aporeto.io/enforcerd/trireme-lib/utils/crypto"
    12  )
    13  
    14  //PrivateKey struct holds the ecdsa private key and its encoded string
    15  type PrivateKey struct {
    16  	*ecdsa.PrivateKey
    17  	PrivateKeyString string
    18  }
    19  
    20  type ephemeralKey struct {
    21  	privateKey  *PrivateKey
    22  	publicKeyV1 []byte
    23  	publicKeyV2 []byte
    24  	sync.RWMutex
    25  }
    26  
    27  const keyInterval = 5 * time.Minute
    28  
    29  // New creates a new key accessor
    30  func New() (KeyAccessor, error) {
    31  	privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  
    36  	publicKeyBytesV1 := crypto.EncodePublicKeyV1(&privateKey.PublicKey)
    37  	publicKeyBytesV2 := crypto.EncodePublicKeyV2(&privateKey.PublicKey)
    38  	pvtKeyBytes := crypto.EncodePrivateKey(privateKey)
    39  
    40  	keys := &ephemeralKey{
    41  		privateKey:  &PrivateKey{privateKey, string(pvtKeyBytes)},
    42  		publicKeyV1: publicKeyBytesV1,
    43  		publicKeyV2: publicKeyBytesV2,
    44  	}
    45  
    46  	return keys, nil
    47  }
    48  
    49  // NewWithRenewal creates a new key accessor and renews it every keyInterval
    50  func NewWithRenewal() (KeyAccessor, error) {
    51  	privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  
    56  	publicKeyBytesV1 := crypto.EncodePublicKeyV1(&privateKey.PublicKey)
    57  	publicKeyBytesV2 := crypto.EncodePublicKeyV2(&privateKey.PublicKey)
    58  	pvtKeyBytes := crypto.EncodePrivateKey(privateKey)
    59  
    60  	keys := &ephemeralKey{
    61  		privateKey:  &PrivateKey{privateKey, string(pvtKeyBytes)},
    62  		publicKeyV1: publicKeyBytesV1,
    63  		publicKeyV2: publicKeyBytesV2,
    64  	}
    65  
    66  	go func() {
    67  		for {
    68  			<-time.After(keyInterval)
    69  			for i := 0; i < 5; i++ {
    70  				privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    71  				if err != nil {
    72  					continue
    73  				}
    74  				publicKeyBytesV1 := crypto.EncodePublicKeyV1(&privateKey.PublicKey)
    75  				publicKeyBytesV2 := crypto.EncodePublicKeyV2(&privateKey.PublicKey)
    76  				pvtKeyBytes := crypto.EncodePrivateKey(privateKey)
    77  
    78  				keys.Lock()
    79  				keys.privateKey = &PrivateKey{privateKey, string(pvtKeyBytes)}
    80  				keys.publicKeyV1 = publicKeyBytesV1
    81  				keys.publicKeyV2 = publicKeyBytesV2
    82  				keys.Unlock()
    83  				break
    84  			}
    85  		}
    86  	}()
    87  
    88  	return keys, nil
    89  }
    90  
    91  // PrivateKey return the private key of the keypair
    92  func (k *ephemeralKey) PrivateKey() *PrivateKey {
    93  	k.RLock()
    94  	defer k.RUnlock()
    95  	return k.privateKey
    96  }
    97  
    98  func (k *ephemeralKey) DecodingKeyV1() []byte {
    99  	k.RLock()
   100  	defer k.RUnlock()
   101  	return k.publicKeyV1
   102  }
   103  
   104  func (k *ephemeralKey) DecodingKeyV2() []byte {
   105  	k.RLock()
   106  	defer k.RUnlock()
   107  	return k.publicKeyV2
   108  }
   109  
   110  var secret secrets.Secrets
   111  var lock sync.RWMutex
   112  
   113  //GetDatapathSecret returns the secrets
   114  func GetDatapathSecret() secrets.Secrets {
   115  	lock.RLock()
   116  	defer lock.RUnlock()
   117  	return secret
   118  }
   119  
   120  //UpdateDatapathSecrets updates the secrets
   121  func UpdateDatapathSecrets(s secrets.Secrets) {
   122  	lock.Lock()
   123  	secret = s
   124  	lock.Unlock()
   125  }