|
|
|
|
@ -7,7 +7,14 @@
|
|
|
|
|
package bmcs
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"crypto/rand"
|
|
|
|
|
"crypto/rsa"
|
|
|
|
|
"crypto/x509"
|
|
|
|
|
"encoding/asn1"
|
|
|
|
|
"encoding/pem"
|
|
|
|
|
"os"
|
|
|
|
|
"reflect"
|
|
|
|
|
"strings"
|
|
|
|
|
"testing"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
@ -119,3 +126,164 @@ func TestNewConfigDefaultsOverridden(t *testing.T) {
|
|
|
|
|
adminConfig.Fingerprint)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestParseEncryptedPrivateKeyValidPassword(t *testing.T) {
|
|
|
|
|
// Generate private key
|
|
|
|
|
priv, err := rsa.GenerateKey(rand.Reader, 2014)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Unexpected generating RSA key: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
publicKey := priv.PublicKey
|
|
|
|
|
|
|
|
|
|
// ASN.1 DER encoded form
|
|
|
|
|
privDer := x509.MarshalPKCS1PrivateKey(priv)
|
|
|
|
|
|
|
|
|
|
blockType := "RSA PRIVATE KEY"
|
|
|
|
|
password := []byte("password")
|
|
|
|
|
cipherType := x509.PEMCipherAES256
|
|
|
|
|
|
|
|
|
|
// Encrypt priv with password
|
|
|
|
|
encryptedPEMBlock, err := x509.EncryptPEMBlock(
|
|
|
|
|
rand.Reader,
|
|
|
|
|
blockType,
|
|
|
|
|
privDer,
|
|
|
|
|
password,
|
|
|
|
|
cipherType)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Unexpected error encryting PEM block: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parse private key
|
|
|
|
|
key, err := ParsePrivateKey(pem.EncodeToMemory(encryptedPEMBlock), password)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("unexpected error: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check we get the same key back
|
|
|
|
|
if !reflect.DeepEqual(publicKey, key.PublicKey) {
|
|
|
|
|
t.Errorf("expected public key of encrypted and decrypted key to match")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestParseEncryptedPrivateKeyPKCS8(t *testing.T) {
|
|
|
|
|
// Generate private key
|
|
|
|
|
priv, err := rsa.GenerateKey(rand.Reader, 2014)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Unexpected generating RSA key: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
publicKey := priv.PublicKey
|
|
|
|
|
|
|
|
|
|
// Implements x509.MarshalPKCS8PrivateKey which is not included in the
|
|
|
|
|
// standard library.
|
|
|
|
|
pkey := struct {
|
|
|
|
|
Version int
|
|
|
|
|
PrivateKeyAlgorithm []asn1.ObjectIdentifier
|
|
|
|
|
PrivateKey []byte
|
|
|
|
|
}{
|
|
|
|
|
Version: 0,
|
|
|
|
|
PrivateKeyAlgorithm: []asn1.ObjectIdentifier{{1, 2, 840, 113549, 1, 1, 1}},
|
|
|
|
|
PrivateKey: x509.MarshalPKCS1PrivateKey(priv),
|
|
|
|
|
}
|
|
|
|
|
privDer, err := asn1.Marshal(pkey)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Unexpected marshaling RSA key: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
blockType := "RSA PRIVATE KEY"
|
|
|
|
|
password := []byte("password")
|
|
|
|
|
cipherType := x509.PEMCipherAES256
|
|
|
|
|
|
|
|
|
|
// Encrypt priv with password
|
|
|
|
|
encryptedPEMBlock, err := x509.EncryptPEMBlock(
|
|
|
|
|
rand.Reader,
|
|
|
|
|
blockType,
|
|
|
|
|
privDer,
|
|
|
|
|
password,
|
|
|
|
|
cipherType)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Unexpected error encryting PEM block: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parse private key
|
|
|
|
|
key, err := ParsePrivateKey(pem.EncodeToMemory(encryptedPEMBlock), password)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("unexpected error: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check we get the same key back
|
|
|
|
|
if !reflect.DeepEqual(publicKey, key.PublicKey) {
|
|
|
|
|
t.Errorf("expected public key of encrypted and decrypted key to match")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestParseEncryptedPrivateKeyInvalidPassword(t *testing.T) {
|
|
|
|
|
// Generate private key
|
|
|
|
|
priv, err := rsa.GenerateKey(rand.Reader, 2014)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Unexpected generating RSA key: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ASN.1 DER encoded form
|
|
|
|
|
privDer := x509.MarshalPKCS1PrivateKey(priv)
|
|
|
|
|
|
|
|
|
|
blockType := "RSA PRIVATE KEY"
|
|
|
|
|
password := []byte("password")
|
|
|
|
|
cipherType := x509.PEMCipherAES256
|
|
|
|
|
|
|
|
|
|
// Encrypt priv with password
|
|
|
|
|
encryptedPEMBlock, err := x509.EncryptPEMBlock(
|
|
|
|
|
rand.Reader,
|
|
|
|
|
blockType,
|
|
|
|
|
privDer,
|
|
|
|
|
password,
|
|
|
|
|
cipherType)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Unexpected error encrypting PEM block: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parse private key (with wrong password)
|
|
|
|
|
_, err = ParsePrivateKey(pem.EncodeToMemory(encryptedPEMBlock), []byte("foo"))
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("Expected error, got nil")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(err.Error(), "decryption password incorrect") {
|
|
|
|
|
t.Errorf("Expected error to contain 'decryption password incorrect', got %+v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestParseEncryptedPrivateKeyInvalidNoPassword(t *testing.T) {
|
|
|
|
|
// Generate private key
|
|
|
|
|
priv, err := rsa.GenerateKey(rand.Reader, 2014)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Unexpected generating RSA key: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ASN.1 DER encoded form
|
|
|
|
|
privDer := x509.MarshalPKCS1PrivateKey(priv)
|
|
|
|
|
|
|
|
|
|
blockType := "RSA PRIVATE KEY"
|
|
|
|
|
password := []byte("password")
|
|
|
|
|
cipherType := x509.PEMCipherAES256
|
|
|
|
|
|
|
|
|
|
// Encrypt priv with password
|
|
|
|
|
encryptedPEMBlock, err := x509.EncryptPEMBlock(
|
|
|
|
|
rand.Reader,
|
|
|
|
|
blockType,
|
|
|
|
|
privDer,
|
|
|
|
|
password,
|
|
|
|
|
cipherType)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("Unexpected error encrypting PEM block: %+v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parse private key (with wrong password)
|
|
|
|
|
_, err = ParsePrivateKey(pem.EncodeToMemory(encryptedPEMBlock), []byte{})
|
|
|
|
|
if err == nil {
|
|
|
|
|
t.Fatalf("Expected error, got nil")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !strings.Contains(err.Error(), "no pass phrase provided") {
|
|
|
|
|
t.Errorf("Expected error to contain 'no pass phrase provided', got %+v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|