Adding PGP key creation capability for vault init 79/34979/1
authorKiran Kamineni <kiran.k.kamineni@intel.com>
Fri, 9 Mar 2018 19:03:36 +0000 (11:03 -0800)
committerKiran Kamineni <kiran.k.kamineni@intel.com>
Fri, 9 Mar 2018 19:03:42 +0000 (11:03 -0800)
Adding a couple of functions to support PGP key generation
and using said keys to initialise vault.

Issue-ID: AAF-165
Change-Id: Ic65f8157f125005d544bbf8dede184bd282a5357
Signed-off-by: Kiran Kamineni <kiran.k.kamineni@intel.com>
sms-service/src/sms/auth/auth.go
sms-service/src/sms/backend/vault.go

index 8186738..341f377 100644 (file)
 package auth
 
 import (
+       "bytes"
        "crypto/tls"
        "crypto/x509"
+       "encoding/base64"
+       "golang.org/x/crypto/openpgp"
        "io/ioutil"
+
+       smslogger "sms/log"
 )
 
 var tlsConfig *tls.Config
@@ -47,3 +52,44 @@ func GetTLSConfig(caCertFile string) (*tls.Config, error) {
        }
        return tlsConfig, nil
 }
+
+// GeneratePGPKeyPair produces a PGP key pair and returns
+// two things:
+// A base64 encoded form of the public part of the entity
+// A base64 encoded form of the private key
+func GeneratePGPKeyPair() (string, string, error) {
+       var entity *openpgp.Entity
+       entity, err := openpgp.NewEntity("aaf.sms.init", "PGP Key for unsealing", "", nil)
+       if err != nil {
+               smslogger.WriteError(err.Error())
+               return "", "", err
+       }
+
+       // Sign the identity in the entity
+       for _, id := range entity.Identities {
+               err = id.SelfSignature.SignUserId(id.UserId.Id, entity.PrimaryKey, entity.PrivateKey, nil)
+               if err != nil {
+                       smslogger.WriteError(err.Error())
+                       return "", "", err
+               }
+       }
+
+       // Sign the subkey in the entity
+       for _, subkey := range entity.Subkeys {
+               err := subkey.Sig.SignKey(subkey.PublicKey, entity.PrivateKey, nil)
+               if err != nil {
+                       smslogger.WriteError(err.Error())
+                       return "", "", err
+               }
+       }
+
+       buffer := new(bytes.Buffer)
+       entity.Serialize(buffer)
+       pbkey := base64.StdEncoding.EncodeToString(buffer.Bytes())
+
+       buffer.Reset()
+       entity.SerializePrivate(buffer, nil)
+       prkey := base64.StdEncoding.EncodeToString(buffer.Bytes())
+
+       return pbkey, prkey, nil
+}
index a4ebaaa..ac5cc67 100644 (file)
@@ -19,6 +19,7 @@ package backend
 import (
        uuid "github.com/hashicorp/go-uuid"
        vaultapi "github.com/hashicorp/vault/api"
+       smsauth "sms/auth"
        smslogger "sms/log"
 
        "errors"
@@ -41,6 +42,10 @@ type Vault struct {
        vaultMount        string
        vaultTempTokenTTL time.Time
        vaultToken        string
+       unsealShards      []string
+       rootToken         string
+       pgpPub            string
+       pgpPr             string
 }
 
 // Init will initialize the vault connection
@@ -349,3 +354,36 @@ func (v *Vault) checkToken() error {
        v.vaultClient.SetToken(tok)
        return nil
 }
+
+// vaultInit() is used to initialize the vault in cases where it is not
+// initialized. This happens once during intial bring up.
+func (v *Vault) initializeVault() error {
+       initReq := &vaultapi.InitRequest{
+               SecretShares:    5,
+               SecretThreshold: 3,
+       }
+
+       pbkey, prkey, err := smsauth.GeneratePGPKeyPair()
+       if err != nil {
+               smslogger.WriteError("Error Generating PGP Keys. Vault Init will not use encryption!")
+       } else {
+               initReq.PGPKeys = []string{pbkey, pbkey, pbkey, pbkey, pbkey}
+               initReq.RootTokenPGPKey = pbkey
+               v.pgpPub = pbkey
+               v.pgpPr = prkey
+       }
+
+       resp, err := v.vaultClient.Sys().Init(initReq)
+       if err != nil {
+               smslogger.WriteError(err.Error())
+               return errors.New("FATAL: Unable to initialize Vault")
+       }
+
+       if resp != nil {
+               v.unsealShards = resp.KeysB64
+               v.rootToken = resp.RootToken
+               return nil
+       }
+
+       return errors.New("FATAL: Init response was empty")
+}