538 lines
11 KiB
Go
538 lines
11 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
var expiry = 1 * time.Minute
|
|
|
|
var invalidProfileConfig = &Config{
|
|
Signing: &Signing{
|
|
Profiles: map[string]*SigningProfile{
|
|
"invalid": {
|
|
Usage: []string{"wiretapping"},
|
|
Expiry: expiry,
|
|
},
|
|
"empty": {},
|
|
},
|
|
Default: &SigningProfile{
|
|
Usage: []string{"digital signature"},
|
|
Expiry: expiry,
|
|
},
|
|
},
|
|
}
|
|
|
|
var invalidDefaultConfig = &Config{
|
|
Signing: &Signing{
|
|
Profiles: map[string]*SigningProfile{
|
|
"key usage": {
|
|
Usage: []string{"digital signature"},
|
|
},
|
|
},
|
|
Default: &SigningProfile{
|
|
Usage: []string{"s/mime"},
|
|
},
|
|
},
|
|
}
|
|
|
|
var validConfig = &Config{
|
|
Signing: &Signing{
|
|
Profiles: map[string]*SigningProfile{
|
|
"valid": {
|
|
Usage: []string{"digital signature"},
|
|
Expiry: expiry,
|
|
},
|
|
},
|
|
Default: &SigningProfile{
|
|
Usage: []string{"digital signature"},
|
|
Expiry: expiry,
|
|
},
|
|
},
|
|
}
|
|
|
|
var validMixedConfig = `
|
|
{
|
|
"signing": {
|
|
"profiles": {
|
|
"CA": {
|
|
"auth_key": "sample",
|
|
"remote": "localhost"
|
|
},
|
|
"email": {
|
|
"usages": ["s/mime"],
|
|
"expiry": "720h"
|
|
}
|
|
},
|
|
"default": {
|
|
"usages": ["digital signature", "email protection"],
|
|
"expiry": "8000h"
|
|
}
|
|
},
|
|
"auth_keys": {
|
|
"sample": {
|
|
"type":"standard",
|
|
"key":"0123456789ABCDEF0123456789ABCDEF"
|
|
}
|
|
},
|
|
"remotes": {
|
|
"localhost": "127.0.0.1:8888"
|
|
}
|
|
}`
|
|
|
|
var validMinimalRemoteConfig = `
|
|
{
|
|
"signing": {
|
|
"default": {
|
|
"auth_key": "sample",
|
|
"remote": "localhost"
|
|
}
|
|
},
|
|
"auth_keys": {
|
|
"sample": {
|
|
"type":"standard",
|
|
"key":"0123456789ABCDEF0123456789ABCDEF"
|
|
}
|
|
},
|
|
"remotes": {
|
|
"localhost": "127.0.0.1:8888"
|
|
}
|
|
}`
|
|
|
|
var validMinimalRemoteConfig2 = `
|
|
{
|
|
"signing": {
|
|
"default": {
|
|
"auth_remote":{
|
|
"auth_key": "sample",
|
|
"remote": "localhost"
|
|
}
|
|
}
|
|
},
|
|
"auth_keys": {
|
|
"sample": {
|
|
"type":"standard",
|
|
"key":"0123456789ABCDEF0123456789ABCDEF"
|
|
}
|
|
},
|
|
"remotes": {
|
|
"localhost": "127.0.0.1:8888"
|
|
}
|
|
}`
|
|
|
|
var invalidConflictRemoteConfig = `
|
|
{
|
|
"signing": {
|
|
"default": {
|
|
"auth_remote":{
|
|
"auth_key": "sample",
|
|
"remote": "localhost"
|
|
},
|
|
"remote": "localhost"
|
|
}
|
|
},
|
|
"auth_keys": {
|
|
"sample": {
|
|
"type":"standard",
|
|
"key":"0123456789ABCDEF0123456789ABCDEF"
|
|
}
|
|
},
|
|
"remotes": {
|
|
"localhost": "127.0.0.1:8888"
|
|
}
|
|
}`
|
|
|
|
var invalidRemoteConfig = `
|
|
{
|
|
"signing": {
|
|
"default": {
|
|
"auth_remotes_typos":{
|
|
"auth_key": "sample",
|
|
"remote": "localhost"
|
|
}
|
|
}
|
|
},
|
|
"auth_keys": {
|
|
"sample": {
|
|
"type":"standard",
|
|
"key":"0123456789ABCDEF0123456789ABCDEF"
|
|
}
|
|
},
|
|
"remotes": {
|
|
"localhost": "127.0.0.1:8888"
|
|
}
|
|
}`
|
|
|
|
var invalidAuthRemoteConfigMissingRemote = `
|
|
{
|
|
"signing": {
|
|
"default": {
|
|
"auth_remote":{
|
|
"auth_key": "sample"
|
|
}
|
|
}
|
|
},
|
|
"auth_keys": {
|
|
"sample": {
|
|
"type":"standard",
|
|
"key":"0123456789ABCDEF0123456789ABCDEF"
|
|
}
|
|
},
|
|
"remotes": {
|
|
"localhost": "127.0.0.1:8888"
|
|
}
|
|
}`
|
|
|
|
var invalidAuthRemoteConfigMissingKey = `
|
|
{
|
|
"signing": {
|
|
"default": {
|
|
"auth_remote":{
|
|
"remote": "localhost"
|
|
}
|
|
}
|
|
},
|
|
"auth_keys": {
|
|
"sample": {
|
|
"type":"standard",
|
|
"key":"0123456789ABCDEF0123456789ABCDEF"
|
|
}
|
|
},
|
|
"remotes": {
|
|
"localhost": "127.0.0.1:8888"
|
|
}
|
|
}`
|
|
|
|
var validMinimalLocalConfig = `
|
|
{
|
|
"signing": {
|
|
"default": {
|
|
"usages": ["digital signature", "email protection"],
|
|
"expiry": "8000h"
|
|
}
|
|
}
|
|
}`
|
|
|
|
var validLocalConfigsWithCAConstraint = []string{
|
|
`{
|
|
"signing": {
|
|
"default": {
|
|
"usages": ["digital signature", "email protection"],
|
|
"ca_constraint": { "is_ca": true },
|
|
"expiry": "8000h"
|
|
}
|
|
}
|
|
}`,
|
|
`{
|
|
"signing": {
|
|
"default": {
|
|
"usages": ["digital signature", "email protection"],
|
|
"ca_constraint": { "is_ca": true, "max_path_len": 1 },
|
|
"expiry": "8000h"
|
|
}
|
|
}
|
|
}`,
|
|
`{
|
|
"signing": {
|
|
"default": {
|
|
"usages": ["digital signature", "email protection"],
|
|
"ca_constraint": { "is_ca": true, "max_path_len_zero": true },
|
|
"expiry": "8000h"
|
|
}
|
|
}
|
|
}`,
|
|
}
|
|
|
|
func TestInvalidProfile(t *testing.T) {
|
|
if invalidProfileConfig.Signing.Profiles["invalid"].validProfile(false) {
|
|
t.Fatal("invalid profile accepted as valid")
|
|
}
|
|
|
|
if invalidProfileConfig.Signing.Profiles["empty"].validProfile(false) {
|
|
t.Fatal("invalid profile accepted as valid")
|
|
}
|
|
|
|
if invalidProfileConfig.Valid() {
|
|
t.Fatal("invalid config accepted as valid")
|
|
}
|
|
|
|
if !invalidProfileConfig.Signing.Profiles["invalid"].validProfile(true) {
|
|
t.Fatal("invalid profile should be a valid default profile")
|
|
}
|
|
}
|
|
|
|
func TestRemoteProfiles(t *testing.T) {
|
|
var validRemoteProfile = &SigningProfile{
|
|
RemoteName: "localhost",
|
|
RemoteServer: "localhost:8080",
|
|
}
|
|
|
|
var invalidRemoteProfile = &SigningProfile{
|
|
RemoteName: "localhost",
|
|
}
|
|
|
|
var invalidRemoteAuthProfile = &SigningProfile{
|
|
RemoteName: "localhost",
|
|
RemoteServer: "localhost:8080",
|
|
AuthKeyName: "blahblah",
|
|
}
|
|
|
|
if !validRemoteProfile.validProfile(true) ||
|
|
!validRemoteProfile.validProfile(false) {
|
|
t.Fatal("valid remote profile is rejected.")
|
|
}
|
|
|
|
if invalidRemoteProfile.validProfile(true) ||
|
|
invalidRemoteProfile.validProfile(false) {
|
|
t.Fatal("invalid remote profile is accepted.")
|
|
}
|
|
|
|
if invalidRemoteAuthProfile.validProfile(true) ||
|
|
invalidRemoteAuthProfile.validProfile(false) {
|
|
t.Fatal("invalid remote profile is accepted.")
|
|
}
|
|
}
|
|
|
|
func TestInvalidDefault(t *testing.T) {
|
|
if invalidDefaultConfig.Signing.Default.validProfile(true) {
|
|
t.Fatal("invalid default accepted as valid")
|
|
}
|
|
|
|
if invalidDefaultConfig.Valid() {
|
|
t.Fatal("invalid config accepted as valid")
|
|
}
|
|
|
|
if !invalidDefaultConfig.Signing.Default.validProfile(false) {
|
|
t.Fatal("invalid default profile should be a valid profile")
|
|
}
|
|
}
|
|
|
|
func TestValidConfig(t *testing.T) {
|
|
if !validConfig.Valid() {
|
|
t.Fatal("Valid config is not valid")
|
|
}
|
|
bytes, _ := json.Marshal(validConfig)
|
|
fmt.Printf("%v", string(bytes))
|
|
}
|
|
|
|
func TestDefaultConfig(t *testing.T) {
|
|
if !DefaultConfig().validProfile(false) {
|
|
t.Fatal("global default signing profile should be a valid profile.")
|
|
}
|
|
|
|
if !DefaultConfig().validProfile(true) {
|
|
t.Fatal("global default signing profile should be a valid default profile")
|
|
}
|
|
}
|
|
|
|
func TestParse(t *testing.T) {
|
|
var validProfiles = []*SigningProfile{
|
|
{
|
|
ExpiryString: "8760h",
|
|
},
|
|
{
|
|
ExpiryString: "168h",
|
|
},
|
|
{
|
|
ExpiryString: "300s",
|
|
},
|
|
}
|
|
|
|
var invalidProfiles = []*SigningProfile{
|
|
nil,
|
|
{},
|
|
{
|
|
ExpiryString: "",
|
|
},
|
|
{
|
|
ExpiryString: "365d",
|
|
},
|
|
{
|
|
ExpiryString: "1y",
|
|
},
|
|
{
|
|
ExpiryString: "one year",
|
|
},
|
|
}
|
|
|
|
for _, p := range validProfiles {
|
|
if p.populate(nil) != nil {
|
|
t.Fatalf("Failed to parse ExpiryString=%s", p.ExpiryString)
|
|
}
|
|
}
|
|
|
|
for _, p := range invalidProfiles {
|
|
if p.populate(nil) == nil {
|
|
if p != nil {
|
|
t.Fatalf("ExpiryString=%s should not be parseable", p.ExpiryString)
|
|
}
|
|
t.Fatalf("Nil profile should not be parseable")
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func TestLoadFile(t *testing.T) {
|
|
validConfigFiles := []string{
|
|
"testdata/valid_config.json",
|
|
"testdata/valid_config_auth.json",
|
|
"testdata/valid_config_no_default.json",
|
|
"testdata/valid_config_auth_no_default.json",
|
|
}
|
|
|
|
for _, configFile := range validConfigFiles {
|
|
_, err := LoadFile(configFile)
|
|
if err != nil {
|
|
t.Fatal("Load valid config file failed.", configFile, "error is ", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestLoadInvalidConfigFile(t *testing.T) {
|
|
invalidConfigFiles := []string{"", "testdata/no_such_file",
|
|
"testdata/invalid_default.json",
|
|
"testdata/invalid_profiles.json",
|
|
"testdata/invalid_usage.json",
|
|
"testdata/invalid_config.json",
|
|
"testdata/invalid_auth.json",
|
|
"testdata/invalid_auth_bad_key.json",
|
|
"testdata/invalid_no_auth_keys.json",
|
|
"testdata/invalid_remote.json",
|
|
"testdata/invalid_no_remotes.json",
|
|
}
|
|
for _, configFile := range invalidConfigFiles {
|
|
_, err := LoadFile(configFile)
|
|
if err == nil {
|
|
t.Fatal("Invalid config is loaded.", configFile)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNeedLocalSigner(t *testing.T) {
|
|
|
|
c, err := LoadConfig([]byte(validMixedConfig))
|
|
if err != nil {
|
|
t.Fatal("load valid config failed:", err)
|
|
}
|
|
|
|
// This signing config needs both local signer and remote signer.
|
|
if c.Signing.NeedsLocalSigner() != true {
|
|
t.Fatal("incorrect NeedsLocalSigner().")
|
|
}
|
|
|
|
if c.Signing.NeedsRemoteSigner() != true {
|
|
t.Fatal("incorrect NeedsRemoteSigner()")
|
|
}
|
|
|
|
remoteConfig, err := LoadConfig([]byte(validMinimalRemoteConfig))
|
|
if err != nil {
|
|
t.Fatal("Load valid config failed:", err)
|
|
}
|
|
|
|
if remoteConfig.Signing.NeedsLocalSigner() != false {
|
|
t.Fatal("incorrect NeedsLocalSigner().")
|
|
}
|
|
|
|
if remoteConfig.Signing.NeedsRemoteSigner() != true {
|
|
t.Fatal("incorrect NeedsRemoteSigner().")
|
|
}
|
|
|
|
localConfig, err := LoadConfig([]byte(validMinimalLocalConfig))
|
|
if localConfig.Signing.NeedsLocalSigner() != true {
|
|
t.Fatal("incorrect NeedsLocalSigner().")
|
|
}
|
|
|
|
if localConfig.Signing.NeedsRemoteSigner() != false {
|
|
t.Fatal("incorrect NeedsRemoteSigner().")
|
|
}
|
|
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestOverrideRemotes(t *testing.T) {
|
|
c, err := LoadConfig([]byte(validMixedConfig))
|
|
if err != nil {
|
|
t.Fatal("load valid config failed:", err)
|
|
}
|
|
|
|
host := "localhost:8888"
|
|
c.Signing.OverrideRemotes(host)
|
|
|
|
if c.Signing.Default.RemoteServer != host {
|
|
t.Fatal("should override default profile's RemoteServer")
|
|
}
|
|
|
|
for _, p := range c.Signing.Profiles {
|
|
if p.RemoteServer != host {
|
|
t.Fatal("failed to override profile's RemoteServer")
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func TestAuthRemoteConfig(t *testing.T) {
|
|
c, err := LoadConfig([]byte(validMinimalRemoteConfig2))
|
|
if err != nil {
|
|
t.Fatal("load valid config failed:", err)
|
|
}
|
|
|
|
if c.Signing.Default.RemoteServer != "127.0.0.1:8888" {
|
|
t.Fatal("load valid config failed: incorrect remote server")
|
|
}
|
|
|
|
host := "localhost:8888"
|
|
c.Signing.OverrideRemotes(host)
|
|
|
|
if c.Signing.Default.RemoteServer != host {
|
|
t.Fatal("should override default profile's RemoteServer")
|
|
}
|
|
|
|
for _, p := range c.Signing.Profiles {
|
|
if p.RemoteServer != host {
|
|
t.Fatal("failed to override profile's RemoteServer")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDuplicateRemoteConfig(t *testing.T) {
|
|
_, err := LoadConfig([]byte(invalidConflictRemoteConfig))
|
|
if err == nil {
|
|
t.Fatal("fail to reject invalid config")
|
|
}
|
|
}
|
|
|
|
func TestBadAuthRemoteConfig(t *testing.T) {
|
|
_, err := LoadConfig([]byte(invalidRemoteConfig))
|
|
if err == nil {
|
|
t.Fatal("load invalid config should failed")
|
|
}
|
|
|
|
_, err = LoadConfig([]byte(invalidAuthRemoteConfigMissingRemote))
|
|
if err == nil {
|
|
t.Fatal("load invalid config should failed")
|
|
}
|
|
|
|
_, err = LoadConfig([]byte(invalidAuthRemoteConfigMissingKey))
|
|
if err == nil {
|
|
t.Fatal("load invalid config should failed")
|
|
}
|
|
|
|
var p *Signing
|
|
if p.Valid() {
|
|
t.Fatal("nil Signing config should be invalid")
|
|
}
|
|
}
|
|
|
|
func TestValidCAConstraint(t *testing.T) {
|
|
for _, config := range validLocalConfigsWithCAConstraint {
|
|
_, err := LoadConfig([]byte(config))
|
|
if err != nil {
|
|
t.Fatal("can't parse valid ca constraint")
|
|
}
|
|
}
|
|
}
|