Add support for left/right groups

LeftOwners and RightOwners can now be used as either disjoint
or overlapping sets of users for encrypting a message. Default
behavior is to set them to Owners given a non-empty Owners set.

One member from each group are required to decrypt the message.
This commit is contained in:
Nick Sullivan
2015-02-09 18:51:33 -08:00
parent c372a02990
commit 8c21db7ba4
2 changed files with 39 additions and 11 deletions
+11 -4
View File
@@ -49,9 +49,11 @@ type encrypt struct {
Name string
Password string
Minimum int
Owners []string
Data []byte
Minimum int
Owners []string
LeftOwners []string
RightOwners []string
Data []byte
}
type decrypt struct {
@@ -266,8 +268,13 @@ func Encrypt(jsonIn []byte) ([]byte, error) {
return jsonStatusError(err)
}
if len(s.Owners) > 0 {
s.LeftOwners = s.Owners
s.RightOwners = s.Owners
}
// Encrypt file with list of owners
if resp, err := cryptor.Encrypt(s.Data, s.Owners, s.Minimum); err != nil {
if resp, err := cryptor.Encrypt(s.Data, s.LeftOwners, s.RightOwners, s.Minimum); err != nil {
log.Println("Error encrypting:", err)
return jsonStatusError(err)
} else {
+28 -7
View File
@@ -255,7 +255,7 @@ func computeHmac(key []byte, encrypted EncryptedData) []byte {
// Encrypt encrypts data with the keys associated with names. This
// requires a minimum of min keys to decrypt. NOTE: as currently
// implemented, the maximum value for min is 2.
func Encrypt(in []byte, names []string, min int) (resp []byte, err error) {
func Encrypt(in []byte, leftNames, rightNames []string, min int) (resp []byte, err error) {
if min > 2 {
return nil, errors.New("Minimum restricted to 2")
}
@@ -281,14 +281,35 @@ func Encrypt(in []byte, names []string, min int) (resp []byte, err error) {
return
}
// Allocate set of keys to be able to cover all ordered subsets of
// length 2 of names
var names = make(map[string]bool)
var overlap int
encrypted.KeySet = make([]MultiWrappedKey, len(names)*(len(names)-1))
// Count overlapping names, we don't want to double-encrypt
// with the same name
for _, n := range leftNames {
names[n] = true
}
for _, n := range rightNames {
used, ok := names[n]
if !used && ok {
names[n] = true
} else {
overlap++
}
}
// Allocate set of keys to be able to cover all unequal pairs of
// names with one from leftNames and one from rightNames
// Combinatorially, the number of ordered pairs with one element
// from one set and one from another for which both elements of
// the pair is distinct is
// len(n) * len(k) - overlap
encrypted.KeySet = make([]MultiWrappedKey, (len(leftNames)*len(rightNames) - overlap))
encrypted.KeySetRSA = make(map[string]SingleWrappedKey)
var singleWrappedKey SingleWrappedKey
for _, name := range names {
for name := range names {
rec, ok := passvault.GetRecord(name)
if !ok {
err = errors.New("Missing user on disk")
@@ -312,8 +333,8 @@ func Encrypt(in []byte, names []string, min int) (resp []byte, err error) {
// encrypt file key with every combination of two keys
var n int
for _, nameOuter := range names {
for _, nameInner := range names {
for _, nameOuter := range leftNames {
for _, nameInner := range rightNames {
if nameInner != nameOuter {
encrypted.KeySet[n], err = encryptKey(nameInner, nameOuter, clearKey, encrypted.KeySetRSA)
n += 1