package oci import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/asn1" "encoding/pem" "os" "reflect" "strings" "testing" ) func TestNewConfigMissingFile(t *testing.T) { // WHEN _, err := LoadConfigsFromFile("some/invalid/path") // THEN if err == nil { t.Error("Expected missing file error") } } func TestNewConfigDefaultOnly(t *testing.T) { // GIVEN // Get DEFAULT config cfg, keyFile, err := BaseTestConfig() defer os.Remove(keyFile.Name()) // Write test config to file f, err := WriteTestConfig(cfg) if err != nil { t.Fatal(err) } defer os.Remove(f.Name()) // clean up // WHEN // Load configs cfgs, err := LoadConfigsFromFile(f.Name()) if err != nil { t.Fatal(err) } // THEN if _, ok := cfgs["DEFAULT"]; !ok { t.Fatal("Expected DEFAULT config to exist in map") } } func TestNewConfigDefaultsPopulated(t *testing.T) { // GIVEN // Get DEFAULT config cfg, keyFile, err := BaseTestConfig() defer os.Remove(keyFile.Name()) admin := cfg.Section("ADMIN") admin.NewKey("user", "ocid1.user.oc1..bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") admin.NewKey("fingerprint", "11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11") // Write test config to file f, err := WriteTestConfig(cfg) if err != nil { t.Fatal(err) } defer os.Remove(f.Name()) // clean up // WHEN cfgs, err := LoadConfigsFromFile(f.Name()) adminConfig, ok := cfgs["ADMIN"] // THEN if !ok { t.Fatal("Expected ADMIN config to exist in map") } if adminConfig.Region != "us-phoenix-1" { t.Errorf("Expected 'us-phoenix-1', got '%s'", adminConfig.Region) } } func TestNewConfigDefaultsOverridden(t *testing.T) { // GIVEN // Get DEFAULT config cfg, keyFile, err := BaseTestConfig() defer os.Remove(keyFile.Name()) admin := cfg.Section("ADMIN") admin.NewKey("user", "ocid1.user.oc1..bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") admin.NewKey("fingerprint", "11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11") // Write test config to file f, err := WriteTestConfig(cfg) if err != nil { t.Fatal(err) } defer os.Remove(f.Name()) // clean up // WHEN cfgs, err := LoadConfigsFromFile(f.Name()) adminConfig, ok := cfgs["ADMIN"] // THEN if !ok { t.Fatal("Expected ADMIN config to exist in map") } if adminConfig.Fingerprint != "11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11" { t.Errorf("Expected fingerprint '11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11', got '%s'", 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) } }