Skip to content

Commit

Permalink
Add delegation option for any user to be able to decrypt
Browse files Browse the repository at this point in the history
core: Add AnyUser field to DelegateRequest and pass to cache calls

keycache: Add AnyUser parameter to AddKeyFromRecord function signature

keycache_test: Add tests for AnyUser and update AddKeyFromRecord calls

cryptor: Update tests to AddKeyFromRecord to reflect API update

cmd/ro: Add bool flag for anyUser parameter
  • Loading branch information
Tyler J committed Apr 13, 2016
1 parent 5b4b464 commit 2e982e9
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 20 deletions.
4 changes: 4 additions & 0 deletions cmd/ro/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ var owners, lefters, righters, inPath, labels, outPath, outEnv string

var uses, minUsers int

var anyUser bool

var duration, users string

var pollInterval time.Duration
Expand Down Expand Up @@ -52,6 +54,7 @@ func registerFlags() {
flag.StringVar(&users, "users", "", "comma separated user list")
flag.IntVar(&uses, "uses", 0, "number of delegated key uses")
flag.IntVar(&minUsers, "minUsers", 2, "minimum number of delegations")
flag.BoolVar(&anyUser, "anyUser", false, "whether any user can decrypt")
flag.StringVar(&duration, "time", "0h", "duration of delegated key uses")
flag.StringVar(&lefters, "left", "", "comma separated left owners")
flag.StringVar(&righters, "right", "", "comma separated right owners")
Expand Down Expand Up @@ -110,6 +113,7 @@ func runDelegate() {
Time: duration,
Users: processCSL(users),
Labels: processCSL(labels),
AnyUser: anyUser,
}
resp, err := roServer.Delegate(req)
processError(err)
Expand Down
13 changes: 7 additions & 6 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@ type DelegateRequest struct {
Name string
Password string

Uses int
Time string
Slot string
Users []string
Labels []string
Uses int
Time string
Slot string
Users []string
Labels []string
AnyUser bool
}

type CreateUserRequest struct {
Expand Down Expand Up @@ -396,7 +397,7 @@ func Delegate(jsonIn []byte) ([]byte, error) {
}

// add signed-in record to active set
if err = cache.AddKeyFromRecord(pr, s.Name, s.Password, s.Users, s.Labels, s.Uses, s.Slot, s.Time); err != nil {
if err = cache.AddKeyFromRecord(pr, s.Name, s.Password, s.Users, s.Labels, s.Uses, s.Slot, s.Time, s.AnyUser); err != nil {
return jsonStatusError(err)
}

Expand Down
2 changes: 1 addition & 1 deletion cryptor/cryptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func TestDuplicates(t *testing.T) {

// Delegate one key at a time and check that decryption fails.
for name, pr := range recs {
err = cache.AddKeyFromRecord(pr, name, "weakpassword", nil, nil, 2, "", "1h")
err = cache.AddKeyFromRecord(pr, name, "weakpassword", nil, nil, 2, "", "1h", false)
if err != nil {
t.Fatalf("%v", err)
}
Expand Down
20 changes: 13 additions & 7 deletions keycache/keycache.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ type DelegateIndex struct {

// Usage holds the permissions of a delegated permission
type Usage struct {
Uses int // Number of uses delegated
Labels []string // File labels allowed to decrypt
Users []string // Set of users allows to decrypt
Expiry time.Time // Expiration of usage
Uses int // Number of uses delegated
Labels []string // File labels allowed to decrypt
Users []string // Set of users allows to decrypt
Expiry time.Time // Expiration of usage
AnyUser bool // True if any user is permitted, false otherwise
}

// ActiveUser holds the information about an actively delegated key.
Expand Down Expand Up @@ -72,15 +73,19 @@ func (usage Usage) matchesLabel(labels []string) bool {
}

// matches returns true if this usage applies the user and label
// an empty array of Users indicates that all users are valid
// also returns true if the usage is marked with AnyUser set to true
// DEPRECATED: an empty array of Users indicates that all users are valid
func (usage Usage) matches(user string, labels []string) bool {
if !usage.matchesLabel(labels) {
return false
}
// if usage lists no users, always match
// DEPRECATED: if usage lists no users, always match
if len(usage.Users) == 0 {
return true
}
if usage.AnyUser {
return true
}
for _, validUser := range usage.Users {
if user == validUser {
return true
Expand Down Expand Up @@ -173,7 +178,7 @@ func (cache *Cache) Refresh() {
}

// AddKeyFromRecord decrypts a key for a given record and adds it to the cache.
func (cache *Cache) AddKeyFromRecord(record passvault.PasswordRecord, name, password string, users, labels []string, uses int, slot, durationString string) (err error) {
func (cache *Cache) AddKeyFromRecord(record passvault.PasswordRecord, name, password string, users, labels []string, uses int, slot, durationString string, anyUser bool) (err error) {
var current ActiveUser

cache.Refresh()
Expand All @@ -187,6 +192,7 @@ func (cache *Cache) AddKeyFromRecord(record passvault.PasswordRecord, name, pass
current.Usage.Expiry = time.Now().Add(duration)
current.Usage.Users = users
current.Usage.Labels = labels
current.Usage.AnyUser = anyUser

// get decryption keys
switch record.Type {
Expand Down
59 changes: 53 additions & 6 deletions keycache/keycache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestUsesFlush(t *testing.T) {
// Initialize keycache and delegate the user's key to it.
cache := NewCache()

err = cache.AddKeyFromRecord(pr, "user", "weakpassword", nil, nil, 2, "", "1h")
err = cache.AddKeyFromRecord(pr, "user", "weakpassword", nil, nil, 2, "", "1h", false)
if err != nil {
t.Fatalf("%v", err)
}
Expand Down Expand Up @@ -90,7 +90,7 @@ func TestTimeFlush(t *testing.T) {

cache := NewCache()

err = cache.AddKeyFromRecord(pr, "user", "weakpassword", nil, nil, 10, "", "1s")
err = cache.AddKeyFromRecord(pr, "user", "weakpassword", nil, nil, 10, "", "1s", false)
if err != nil {
t.Fatalf("%v", err)
}
Expand Down Expand Up @@ -129,7 +129,7 @@ func TestGoodLabel(t *testing.T) {

cache := NewCache()

err = cache.AddKeyFromRecord(pr, "user", "weakpassword", nil, []string{"red"}, 1, "", "1h")
err = cache.AddKeyFromRecord(pr, "user", "weakpassword", nil, []string{"red"}, 1, "", "1h", false)
if err != nil {
t.Fatalf("%v", err)
}
Expand Down Expand Up @@ -171,7 +171,7 @@ func TestBadLabel(t *testing.T) {

cache := NewCache()

err = cache.AddKeyFromRecord(pr, "user", "weakpassword", nil, []string{"red"}, 1, "", "1h")
err = cache.AddKeyFromRecord(pr, "user", "weakpassword", nil, []string{"red"}, 1, "", "1h", false)
if err != nil {
t.Fatalf("%v", err)
}
Expand Down Expand Up @@ -217,7 +217,7 @@ func TestGoodUser(t *testing.T) {
pr, "user", "weakpassword",
[]string{"ci", "buildeng", "user"},
[]string{"red", "blue"},
1, "", "1h",
1, "", "1h", false,
)
if err != nil {
t.Fatalf("%v", err)
Expand Down Expand Up @@ -264,7 +264,7 @@ func TestBadUser(t *testing.T) {
pr, "user", "weakpassword",
[]string{"ci", "buildeng", "user"},
[]string{"red", "blue"},
1, "", "1h",
1, "", "1h", false,
)
if err != nil {
t.Fatalf("%v", err)
Expand All @@ -291,3 +291,50 @@ func TestBadUser(t *testing.T) {
t.Fatalf("Error in number of live keys %v", cache.UserKeys)
}
}

func TestAnyUser(t *testing.T) {
// Initialize passvault and keycache. Delegate a key with tag and user
// restrictions and verify that permissible decryption is allowed.
records, err := passvault.InitFrom("memory")
if err != nil {
t.Fatalf("%v", err)
}

pr, err := records.AddNewRecord("user", "weakpassword", true, passvault.DefaultRecordType)
if err != nil {
t.Fatalf("%v", err)
}

cache := NewCache()

err = cache.AddKeyFromRecord(
pr, "user", "weakpassword",
nil,
[]string{"red", "blue"},
1, "", "1h", true,
)
if err != nil {
t.Fatalf("%v", err)
}

cache.Refresh()
if len(cache.UserKeys) != 1 {
t.Fatalf("Error in number of live keys")
}

dummy := make([]byte, 16)
pubEncryptedKey, err := pr.EncryptKey(dummy)
if err != nil {
t.Fatalf("%v", err)
}

_, err = cache.DecryptKey(dummy, "user", "anybody", []string{"red"}, pubEncryptedKey)
if err != nil {
t.Fatalf("%v", err)
}

cache.Refresh()
if len(cache.UserKeys) != 0 {
t.Fatalf("Error in number of live keys %v", cache.UserKeys)
}
}

0 comments on commit 2e982e9

Please sign in to comment.