From 6d5b8ff54a07c70eb16e5760f8f7373644af6f0c Mon Sep 17 00:00:00 2001 From: David Lawrence Date: Mon, 21 Dec 2015 23:00:06 -0800 Subject: [PATCH] add role into PEM headers Signed-off-by: David Lawrence (github: endophage) --- cmd/notary/integration_test.go | 2 +- cryptoservice/import_export_test.go | 2 +- trustmanager/keyfilestore.go | 10 +++++----- trustmanager/keyfilestore_test.go | 6 ++++-- trustmanager/x509utils.go | 19 ++++++++++++++++--- trustmanager/x509utils_test.go | 12 ++++++------ trustmanager/yubikey/yubikeystore_test.go | 8 ++++---- 7 files changed, 37 insertions(+), 22 deletions(-) diff --git a/cmd/notary/integration_test.go b/cmd/notary/integration_test.go index ef257325e3..aaefadeb6d 100644 --- a/cmd/notary/integration_test.go +++ b/cmd/notary/integration_test.go @@ -465,7 +465,7 @@ func TestClientKeyImportExportRootOnly(t *testing.T) { privKey, err := trustmanager.GenerateECDSAKey(rand.Reader) assert.NoError(t, err) - pemBytes, err := trustmanager.EncryptPrivateKey(privKey, testPassphrase) + pemBytes, err := trustmanager.EncryptPrivateKey(privKey, "root", testPassphrase) assert.NoError(t, err) nBytes, err := tempFile.Write(pemBytes) diff --git a/cryptoservice/import_export_test.go b/cryptoservice/import_export_test.go index e6e762581f..5b4399b5cc 100644 --- a/cryptoservice/import_export_test.go +++ b/cryptoservice/import_export_test.go @@ -328,7 +328,7 @@ func TestImportExportRootKey(t *testing.T) { assert.NoError(t, err, "could not read key file") privKey, err := trustmanager.ParsePEMPrivateKey(pemBytes, oldPassphrase) assert.NoError(t, err, "could not decrypt key file") - decryptedPEMBytes, err := trustmanager.KeyToPEM(privKey) + decryptedPEMBytes, err := trustmanager.KeyToPEM(privKey, "root") assert.NoError(t, err, "could not convert key to PEM") err = cs2.ImportRootKey(bytes.NewReader(decryptedPEMBytes)) diff --git a/trustmanager/keyfilestore.go b/trustmanager/keyfilestore.go index d087afe910..bd9612a472 100644 --- a/trustmanager/keyfilestore.go +++ b/trustmanager/keyfilestore.go @@ -333,7 +333,7 @@ func GetPasswdDecryptBytes(passphraseRetriever passphrase.Retriever, pemBytes [] return privKey, passwd, nil } -func encryptAndAddKey(s LimitedFileStore, passwd string, cachedKeys map[string]*cachedKey, name, alias string, privKey data.PrivateKey) error { +func encryptAndAddKey(s LimitedFileStore, passwd string, cachedKeys map[string]*cachedKey, name, role string, privKey data.PrivateKey) error { var ( pemPrivKey []byte @@ -341,17 +341,17 @@ func encryptAndAddKey(s LimitedFileStore, passwd string, cachedKeys map[string]* ) if passwd != "" { - pemPrivKey, err = EncryptPrivateKey(privKey, passwd) + pemPrivKey, err = EncryptPrivateKey(privKey, role, passwd) } else { - pemPrivKey, err = KeyToPEM(privKey) + pemPrivKey, err = KeyToPEM(privKey, role) } if err != nil { return err } - cachedKeys[name] = &cachedKey{alias: alias, key: privKey} - return s.Add(filepath.Join(getSubdir(alias), name+"_"+alias), pemPrivKey) + cachedKeys[name] = &cachedKey{alias: role, key: privKey} + return s.Add(filepath.Join(getSubdir(role), name+"_"+role), pemPrivKey) } func importKey(s LimitedFileStore, passphraseRetriever passphrase.Retriever, cachedKeys map[string]*cachedKey, alias string, pemBytes []byte) error { diff --git a/trustmanager/keyfilestore_test.go b/trustmanager/keyfilestore_test.go index dabfb98e62..87cf24dad3 100644 --- a/trustmanager/keyfilestore_test.go +++ b/trustmanager/keyfilestore_test.go @@ -55,6 +55,8 @@ func TestAddKey(t *testing.T) { func TestGet(t *testing.T) { testData := []byte(`-----BEGIN RSA PRIVATE KEY----- +role: root + MIIEogIBAAKCAQEAyUIXjsrWRrvPa4Bzp3VJ6uOUGPay2fUpSV8XzNxZxIG/Opdr +k3EQi1im6WOqF3Y5AS1UjYRxNuRN+cAZeo3uS1pOTuoSupBXuchVw8s4hZJ5vXn TRmGb+xY7tZ1ZVgPfAZDib9sRSUsL/gC+aSyprAjG/YBdbF06qKbfOfsoCEYW1OQ @@ -109,7 +111,7 @@ EMl3eFOJXjIch/wIesRSN+2dGOsl7neercjMh1i9RvpCwHDx/E0= privKey, _, err := store.GetKey(testName) assert.NoError(t, err, "failed to get key from store") - pemPrivKey, err := KeyToPEM(privKey) + pemPrivKey, err := KeyToPEM(privKey, testAlias) assert.NoError(t, err, "failed to convert key to PEM") assert.Equal(t, testData, pemPrivKey) } @@ -513,7 +515,7 @@ func assertExportKeySuccess( func assertImportKeySuccess( t *testing.T, s KeyStore, expectedKey data.PrivateKey) { - pemBytes, err := EncryptPrivateKey(expectedKey, cannedPassphrase) + pemBytes, err := EncryptPrivateKey(expectedKey, "root", cannedPassphrase) assert.NoError(t, err) err = s.ImportKey(pemBytes, "root") diff --git a/trustmanager/x509utils.go b/trustmanager/x509utils.go index 09b65d6258..4fbbff987e 100644 --- a/trustmanager/x509utils.go +++ b/trustmanager/x509utils.go @@ -414,18 +414,26 @@ func blockType(k data.PrivateKey) (string, error) { } // KeyToPEM returns a PEM encoded key from a Private Key -func KeyToPEM(privKey data.PrivateKey) ([]byte, error) { +func KeyToPEM(privKey data.PrivateKey, role string) ([]byte, error) { bt, err := blockType(privKey) if err != nil { return nil, err } - return pem.EncodeToMemory(&pem.Block{Type: bt, Bytes: privKey.Private()}), nil + block := &pem.Block{ + Type: bt, + Headers: map[string]string{ + "role": role, + }, + Bytes: privKey.Private(), + } + + return pem.EncodeToMemory(block), nil } // EncryptPrivateKey returns an encrypted PEM key given a Privatekey // and a passphrase -func EncryptPrivateKey(key data.PrivateKey, passphrase string) ([]byte, error) { +func EncryptPrivateKey(key data.PrivateKey, role, passphrase string) ([]byte, error) { bt, err := blockType(key) if err != nil { return nil, err @@ -443,6 +451,11 @@ func EncryptPrivateKey(key data.PrivateKey, passphrase string) ([]byte, error) { return nil, err } + if encryptedPEMBlock.Headers == nil { + encryptedPEMBlock.Headers = make(map[string]string) + } + encryptedPEMBlock.Headers["role"] = role + return pem.EncodeToMemory(encryptedPEMBlock), nil } diff --git a/trustmanager/x509utils_test.go b/trustmanager/x509utils_test.go index cba6e84a6d..738a4f1c0c 100644 --- a/trustmanager/x509utils_test.go +++ b/trustmanager/x509utils_test.go @@ -69,15 +69,15 @@ func TestKeyOperations(t *testing.T) { rsaKey, err := GenerateRSAKey(rand.Reader, 512) // Encode our ED private key - edPEM, err := KeyToPEM(edKey) + edPEM, err := KeyToPEM(edKey, "root") assert.NoError(t, err) // Encode our EC private key - ecPEM, err := KeyToPEM(ecKey) + ecPEM, err := KeyToPEM(ecKey, "root") assert.NoError(t, err) // Encode our RSA private key - rsaPEM, err := KeyToPEM(rsaKey) + rsaPEM, err := KeyToPEM(rsaKey, "root") assert.NoError(t, err) // Check to see if ED key it is encoded @@ -108,15 +108,15 @@ func TestKeyOperations(t *testing.T) { assert.Equal(t, rsaKey.Private(), decodedRSAKey.Private()) // Encrypt our ED Key - encryptedEDKey, err := EncryptPrivateKey(edKey, "ponies") + encryptedEDKey, err := EncryptPrivateKey(edKey, "root", "ponies") assert.NoError(t, err) // Encrypt our EC Key - encryptedECKey, err := EncryptPrivateKey(ecKey, "ponies") + encryptedECKey, err := EncryptPrivateKey(ecKey, "root", "ponies") assert.NoError(t, err) // Encrypt our RSA Key - encryptedRSAKey, err := EncryptPrivateKey(rsaKey, "ponies") + encryptedRSAKey, err := EncryptPrivateKey(rsaKey, "root", "ponies") assert.NoError(t, err) // Check to see if ED key it is encrypted diff --git a/trustmanager/yubikey/yubikeystore_test.go b/trustmanager/yubikey/yubikeystore_test.go index 621b8dd11e..95d45af8bd 100644 --- a/trustmanager/yubikey/yubikeystore_test.go +++ b/trustmanager/yubikey/yubikeystore_test.go @@ -339,7 +339,7 @@ func TestYubiImportNewKey(t *testing.T) { privKey, err := trustmanager.GenerateECDSAKey(rand.Reader) assert.NoError(t, err) - pemBytes, err := trustmanager.EncryptPrivateKey(privKey, "passphrase") + pemBytes, err := trustmanager.EncryptPrivateKey(privKey, "root", "passphrase") assert.NoError(t, err) err = store.ImportKey(pemBytes, "root") @@ -388,7 +388,7 @@ func TestYubiImportExistingKey(t *testing.T) { assert.NotNil(t, k) // import the key, which should have already been added to the yubikey - pemBytes, err := trustmanager.EncryptPrivateKey(key, "passphrase") + pemBytes, err := trustmanager.EncryptPrivateKey(key, "root", "passphrase") assert.NoError(t, err) err = newStore.ImportKey(pemBytes, "root") assert.NoError(t, err) @@ -418,7 +418,7 @@ func TestYubiImportNonRootKey(t *testing.T) { privKey, err := trustmanager.GenerateECDSAKey(rand.Reader) assert.NoError(t, err) - pemBytes, err := trustmanager.EncryptPrivateKey(privKey, "passphrase") + pemBytes, err := trustmanager.EncryptPrivateKey(privKey, "root", "passphrase") assert.NoError(t, err) err = store.ImportKey(pemBytes, privKey.ID()) @@ -690,7 +690,7 @@ func TestYubiImportKeyCleansUpOnError(t *testing.T) { privKey, err := trustmanager.GenerateECDSAKey(rand.Reader) assert.NoError(t, err) - pemBytes, err := trustmanager.EncryptPrivateKey(privKey, "passphrase") + pemBytes, err := trustmanager.EncryptPrivateKey(privKey, "root", "passphrase") assert.NoError(t, err) var _importkey = func() error { return store.ImportKey(pemBytes, "root") }