Add new operation: re-encrypt

're-encrypt' allows us to re-encrypt an RO encryption to a different set
of owners and labels. Currently two delegations are sufficient to carry
out this operation.
This commit is contained in:
Zi Lin
2015-08-11 16:31:30 -07:00
parent ce47aa1ecd
commit b1ac8b4cc0
5 changed files with 285 additions and 15 deletions

View File

@@ -189,6 +189,21 @@ func (c *RemoteServer) Encrypt(req core.EncryptRequest) (*core.ResponseData, err
return unmarshalResponseData(respBytes)
}
// ReEncrypt issues an re-encrypt request to the remote server
func (c *RemoteServer) ReEncrypt(req core.ReEncryptRequest) (*core.ResponseData, error) {
reqBytes, err := json.Marshal(req)
if err != nil {
return nil, err
}
respBytes, err := c.doAction("re-encrypt", reqBytes)
if err != nil {
return nil, err
}
return unmarshalResponseData(respBytes)
}
// Decrypt issues an decrypt request to the remote server
func (c *RemoteServer) Decrypt(req core.DecryptRequest) (*core.ResponseData, error) {
reqBytes, err := json.Marshal(req)

View File

@@ -31,11 +31,12 @@ type command struct {
var roServer *client.RemoteServer
var commandSet = map[string]command{
"create": command{Run: runCreate, Desc: "create a user account"},
"summary": command{Run: runSummary, Desc: "list the user and delegation summary"},
"delegate": command{Run: runDelegate, Desc: "do decryption delegation"},
"encrypt": command{Run: runEncrypt, Desc: "encrypt a file"},
"decrypt": command{Run: runDecrypt, Desc: "decrypt a file"},
"create": command{Run: runCreate, Desc: "create a user account"},
"summary": command{Run: runSummary, Desc: "list the user and delegation summary"},
"delegate": command{Run: runDelegate, Desc: "do decryption delegation"},
"encrypt": command{Run: runEncrypt, Desc: "encrypt a file"},
"decrypt": command{Run: runDecrypt, Desc: "decrypt a file"},
"re-encrypt": command{Run: runReEncrypt, Desc: "re-encrypt a file"},
}
func registerFlags() {
@@ -137,6 +138,34 @@ func runEncrypt() {
ioutil.WriteFile(outPath, outBytes, 0644)
}
func runReEncrypt() {
inBytes, err := ioutil.ReadFile(inPath)
processError(err)
// base64 decode the input
encBytes, err := base64.StdEncoding.DecodeString(string(inBytes))
if err != nil {
log.Println("fail to base64 decode the data, proceed with raw data")
encBytes = inBytes
}
req := core.ReEncryptRequest{
Name: user,
Password: pswd,
Owners: processCSL(owners),
LeftOwners: processCSL(lefters),
RightOwners: processCSL(righters),
Labels: processCSL(labels),
Data: encBytes,
}
resp, err := roServer.ReEncrypt(req)
processError(err)
fmt.Println("Response Status:", resp.Status)
outBytes := []byte(base64.StdEncoding.EncodeToString(resp.Response))
ioutil.WriteFile(outPath, outBytes, 0644)
}
func runDecrypt() {
inBytes, err := ioutil.ReadFile(inPath)
processError(err)

View File

@@ -71,6 +71,8 @@ type EncryptRequest struct {
Labels []string
}
type ReEncryptRequest EncryptRequest
type DecryptRequest struct {
Name string
Password string
@@ -402,6 +404,49 @@ func Encrypt(jsonIn []byte) ([]byte, error) {
return jsonResponse(resp)
}
// ReEncrypt processes an Re-encrypt request.
func ReEncrypt(jsonIn []byte) ([]byte, error) {
var s ReEncryptRequest
var err error
defer func() {
if err != nil {
log.Printf("core.re-encrypt failed: user=%s size=%d %v", s.Name, len(s.Data), err)
} else {
log.Printf("core.re-encrypt success: user=%s size=%d", s.Name, len(s.Data))
}
}()
err = json.Unmarshal(jsonIn, &s)
if err != nil {
return jsonStatusError(err)
}
if err = validateUser(s.Name, s.Password, false); err != nil {
return jsonStatusError(err)
}
data, _, secure, err := crypt.Decrypt(s.Data, s.Name)
if err != nil {
return jsonStatusError(err)
}
if !secure {
return jsonStatusError(errors.New("decryption's secure bit is false"))
}
access := cryptor.AccessStructure{
Names: s.Owners,
LeftNames: s.LeftOwners,
RightNames: s.RightOwners,
}
resp, err := crypt.Encrypt(data, s.Labels, access)
if err != nil {
return jsonStatusError(err)
}
return jsonResponse(resp)
}
// Decrypt processes a decrypt request.
func Decrypt(jsonIn []byte) ([]byte, error) {
var s DecryptRequest

View File

@@ -507,6 +507,186 @@ func TestEncryptDecrypt(t *testing.T) {
}
}
func TestReEncrypt(t *testing.T) {
delegateJson := []byte(`{"Name":"Alice","Password":"Hello","Time":"0s","Uses":0}`)
delegateJson2 := []byte(`{"Name":"Bob","Password":"Hello","Time":"0s","Uses":0}`)
delegateJson3 := []byte(`{"Name":"Carol","Password":"Hello","Time":"0s","Uses":0}`)
delegateJson4 := []byte(`{"Name":"Bob","Password":"Hello","Time":"10s","Uses":2,"Users":["Alice"],"Labels":["blue"]}`)
delegateJson5 := []byte(`{"Name":"Carol","Password":"Hello","Time":"10s","Uses":2,"Users":["Alice"],"Labels":["blue"]}`)
delegateJson6 := []byte(`{"Name":"Bob","Password":"Hello","Time":"10s","Uses":2,"Users":["Alice"],"Labels":["red"]}`)
delegateJson7 := []byte(`{"Name":"Carol","Password":"Hello","Time":"10s","Uses":2,"Users":["Alice"],"Labels":["red"]}`)
encryptJson := []byte(`{"Name":"Carol","Password":"Hello","Minumum":2,"Owners":["Alice","Bob","Carol"],"Data":"SGVsbG8gSmVsbG8=","Labels":["blue"]}`)
Init("memory")
// check for summary of initialized vault with new member
var s ResponseData
respJson, err := Create(delegateJson)
if err != nil {
t.Fatalf("Error in creating account, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in creating account, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in creating account, %v", s.Status)
}
respJson, err = Delegate(delegateJson2)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in delegating account, %v", s.Status)
}
respJson, err = Delegate(delegateJson3)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in delegating account, %v", s.Status)
}
// delegate two valid decryptors for label blue
respJson, err = Delegate(delegateJson4)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in delegating account, %v", s.Status)
}
respJson, err = Delegate(delegateJson5)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in delegating account, %v", s.Status)
}
// Encrypt
respJson, err = Encrypt(encryptJson)
if err != nil {
t.Fatalf("Error in encrypt, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in encrypt, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in encrypt, %v", s.Status)
}
// Prepare ReEncryptRequest
reEncryptJson, err := json.Marshal(
ReEncryptRequest{
Name: "Alice",
Password: "Hello",
Data: s.Response,
Owners: []string{"Alice", "Bob", "Carol"},
Labels: []string{"red"},
})
if err != nil {
t.Fatalf("Error in re-encrypt, %v", err)
}
// Re-Encrypt
respJson, err = ReEncrypt(reEncryptJson)
if err != nil {
t.Fatalf("Error in re-encrypt, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in re-encrypt, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in re-encrypt, %v", s.Status)
}
// Prepare DecryptRequest
decryptJson, err := json.Marshal(
DecryptRequest{
Name: "Alice",
Password: "Hello",
Data: s.Response,
})
if err != nil {
t.Fatalf("Error in dencrypt, %v", err)
}
// delegate two valid decryptors for label red
respJson, err = Delegate(delegateJson6)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in delegating account, %v", s.Status)
}
respJson, err = Delegate(delegateJson7)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in delegating account, %v", s.Status)
}
// Decrypt
respJson, err = Decrypt(decryptJson)
if err != nil {
t.Fatalf("Error in decrypt, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in decrypt, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in decrypt, %v", s.Status)
}
var d DecryptWithDelegates
err = json.Unmarshal(s.Response, &d)
if err != nil {
t.Fatalf("Error in decrypt, %v", err)
}
if string(d.Data) != "Hello Jello" {
t.Fatalf("Error in decrypt, %v", string(d.Data))
}
if d.Delegates[0] != "Bob" && d.Delegates[1] != "Carol" {
if d.Delegates[1] != "Bob" && d.Delegates[0] != "Carol" {
t.Fatalf("Error in decrypt, %v", d.Delegates)
}
}
}
func TestOwners(t *testing.T) {
delegateJson := []byte("{\"Name\":\"Alice\",\"Password\":\"Hello\",\"Time\":\"0s\",\"Uses\":0}")
delegateJson2 := []byte("{\"Name\":\"Bob\",\"Password\":\"Hello\",\"Time\":\"0s\",\"Uses\":0}")

View File

@@ -27,16 +27,17 @@ import (
// List of URLs to register and their related functions
var functions = map[string]func([]byte) ([]byte, error){
"/create": core.Create,
"/summary": core.Summary,
"/purge": core.Purge,
"/delegate": core.Delegate,
"/password": core.Password,
"/encrypt": core.Encrypt,
"/decrypt": core.Decrypt,
"/owners": core.Owners,
"/modify": core.Modify,
"/export": core.Export,
"/create": core.Create,
"/summary": core.Summary,
"/purge": core.Purge,
"/delegate": core.Delegate,
"/password": core.Password,
"/encrypt": core.Encrypt,
"/re-encrypt": core.ReEncrypt,
"/decrypt": core.Decrypt,
"/owners": core.Owners,
"/modify": core.Modify,
"/export": core.Export,
}
type userRequest struct {