Merge ""x/ref": Update w.r.t CL #17030"
diff --git a/lib/security/bcrypter/crypter.go b/lib/security/bcrypter/crypter.go
index 5e93126..5b59829 100644
--- a/lib/security/bcrypter/crypter.go
+++ b/lib/security/bcrypter/crypter.go
@@ -88,15 +88,15 @@
keys []ibe.PrivateKey
}
-// Encrypt encrypts the provided fixed-length 'plaintext' so that it can
-// only be decrypted by a crypter possessing a private key for a blessing
-// matching the provided blessing pattern.
+// Encrypt encrypts the provided 'plaintext' so that it can only be decrypted
+// by a crypter possessing a private key for a blessing matching the provided
+// blessing pattern.
//
// Encryption makes use of the public parameters of the identity provider
// that is authoritative on the set of blessings that match the provided
// blessing pattern. These paramaters must have been previously added to
// this crypter via AddParams.
-func (c *Crypter) Encrypt(ctx *context.T, forPattern security.BlessingPattern, plaintext *[32]byte) (*Ciphertext, error) {
+func (c *Crypter) Encrypt(ctx *context.T, forPattern security.BlessingPattern, plaintext []byte) (*Ciphertext, error) {
if !forPattern.IsValid() {
return nil, fmt.Errorf("provided blessing pattern %v is invalid", forPattern)
}
@@ -109,8 +109,8 @@
continue
}
for _, ibeParams := range ibeParamsList {
- ctxt := make([]byte, ibe.CiphertextSize)
- if err := ibeParams.Encrypt(string(forPattern), (*plaintext)[:], ctxt); err != nil {
+ ctxt := make([]byte, len(plaintext)+ibeParams.CiphertextOverhead())
+ if err := ibeParams.Encrypt(string(forPattern), plaintext, ctxt); err != nil {
return nil, NewErrInternal(ctx, err)
}
paramsId, err := idParams(ibeParams)
@@ -127,16 +127,24 @@
return ciphertext, nil
}
+func decrypt(key ibe.PrivateKey, ciphertext []byte) ([]byte, error) {
+ overhead := key.Params().CiphertextOverhead()
+ if got := len(ciphertext); got < overhead {
+ return nil, fmt.Errorf("ciphertext is of size %v bytes, want at least %v bytes", got, overhead)
+ }
+ plaintext := make([]byte, len(ciphertext)-overhead)
+ if err := key.Decrypt(ciphertext, plaintext); err != nil {
+ return nil, err
+ }
+ return plaintext, nil
+}
+
// Decrypt decrypts the provided 'ciphertext' and returns the corresponding
// plaintext.
//
// Decryption succeeds only if this crypter possesses a private key for a
// blessing that matches the blessing pattern corresponding to the ciphertext.
-func (c *Crypter) Decrypt(ctx *context.T, ciphertext *Ciphertext) (*[32]byte, error) {
- var (
- plaintext [32]byte
- keyFound bool
- )
+func (c *Crypter) Decrypt(ctx *context.T, ciphertext *Ciphertext) ([]byte, error) {
c.mu.RLock()
defer c.mu.RUnlock()
for paramsId, cbytes := range ciphertext.wire.Bytes {
@@ -144,16 +152,13 @@
continue
} else if key, found := keys[ciphertext.wire.PatternId]; !found {
continue
- } else if err := key.Decrypt(cbytes, plaintext[:]); err != nil {
- return nil, NewErrInternal(ctx, err)
+ } else if ptxt, err := decrypt(key, cbytes); err != nil {
+ return nil, err
+ } else {
+ return ptxt, nil
}
- keyFound = true
- break
}
- if !keyFound {
- return nil, NewErrPrivateKeyNotFound(ctx)
- }
- return &plaintext, nil
+ return nil, NewErrPrivateKeyNotFound(ctx)
}
// AddKey adds the provided private key 'key' and the associated public
diff --git a/lib/security/bcrypter/crypter_test.go b/lib/security/bcrypter/crypter_test.go
index cea179c..7efaf28 100644
--- a/lib/security/bcrypter/crypter_test.go
+++ b/lib/security/bcrypter/crypter_test.go
@@ -25,12 +25,8 @@
return NewRoot(name, master)
}
-func newPlaintext() [32]byte {
- var m [32]byte
- if n := copy(m[:], []byte("AThirtyTwoBytePieceOfTextThisIs!")); n != len(m) {
- panic(fmt.Errorf("plaintext string must be %d bytes, not %d", len(m), n))
- }
- return m
+func newPlaintext() []byte {
+ return []byte("AThirtyTwoBytePieceOfTextThisIs!")
}
func TextExtract(t *testing.T) {
@@ -79,7 +75,7 @@
)
// empty encrypter should not be able to encrypt for any pattern.
- if _, err := encrypter.Encrypt(ctx, "google/youtube/alice", &ptxt); verror.ErrorID(err) != ErrNoParams.ID {
+ if _, err := encrypter.Encrypt(ctx, "google/youtube/alice", ptxt); verror.ErrorID(err) != ErrNoParams.ID {
t.Fatalf("Got error %v, wanted error with ID %v", err, ErrNoParams.ID)
}
@@ -88,7 +84,7 @@
t.Fatal(err)
}
// encrypting for "google/youtube/alice" should now succeed.
- if _, err := encrypter.Encrypt(ctx, "google/youtube/alice", &ptxt); err != nil {
+ if _, err := encrypter.Encrypt(ctx, "google/youtube/alice", ptxt); err != nil {
t.Fatal(err)
}
@@ -96,7 +92,7 @@
// does not have params that are authoritative on all blessings matching
// the pattern "google" (the googleYoutube params are authoritative on
// blessings matching "google/youtube").
- if _, err := encrypter.Encrypt(ctx, "google", &ptxt); verror.ErrorID(err) != ErrNoParams.ID {
+ if _, err := encrypter.Encrypt(ctx, "google", ptxt); verror.ErrorID(err) != ErrNoParams.ID {
t.Fatalf("Got error %v, wanted error with ID %v", err, ErrNoParams.ID)
}
// add google's params to the encrypter.
@@ -104,21 +100,21 @@
t.Fatal(err)
}
// encrypting for "google" should now succeed.
- if _, err := encrypter.Encrypt(ctx, "google", &ptxt); err != nil {
+ if _, err := encrypter.Encrypt(ctx, "google", ptxt); err != nil {
t.Fatal(err)
}
// Encryption should succeed for all of the following patterns
patterns := []security.BlessingPattern{"google", "google/$", "google/alice", "google/bob", "google/bob/phone"}
for _, p := range patterns {
- if _, err := encrypter.Encrypt(ctx, p, &ptxt); err != nil {
+ if _, err := encrypter.Encrypt(ctx, p, ptxt); err != nil {
t.Fatal(err)
}
}
// Every ciphertext should be unique.
- ctxt1, _ := encrypter.Encrypt(ctx, "google", &ptxt)
- ctxt2, _ := encrypter.Encrypt(ctx, "google", &ptxt)
+ ctxt1, _ := encrypter.Encrypt(ctx, "google", ptxt)
+ ctxt2, _ := encrypter.Encrypt(ctx, "google", ptxt)
if reflect.DeepEqual(ctxt1, ctxt2) {
t.Fatal("Two Encrypt operations yielded the same Ciphertext")
}
@@ -156,7 +152,7 @@
addParams(encrypter, google1.Params())
addParams(encrypter, google2.Params())
// encrypt for the pattern "google/alice"
- ctxt, err := encrypter.Encrypt(ctx, "google/alice", &ptxt)
+ ctxt, err := encrypter.Encrypt(ctx, "google/alice", ptxt)
if err != nil {
t.Fatal(err)
}
@@ -175,8 +171,8 @@
// Decryption should now succeed.
if got, err := decrypter.Decrypt(ctx, ctxt); err != nil {
t.Fatal(err)
- } else if !bytes.Equal((*got)[:], ptxt[:]) {
- t.Fatalf("Got plaintext %v, want %v", *got, ptxt)
+ } else if !bytes.Equal(got, ptxt) {
+ t.Fatalf("Got plaintext %v, want %v", got, ptxt)
}
// Decryption should have succeeded had the decrypter only contained
@@ -187,8 +183,8 @@
}
if got, err := decrypter.Decrypt(ctx, ctxt); err != nil {
t.Fatal(err)
- } else if !bytes.Equal((*got)[:], ptxt[:]) {
- t.Fatalf("Got plaintext %v, want %v", *got, ptxt)
+ } else if !bytes.Equal(got, ptxt) {
+ t.Fatalf("Got plaintext %v, want %v", got, ptxt)
}
// Decryption should fail for ciphertexts encrypted for the following
@@ -196,7 +192,7 @@
// "google/alice/tablet/app" from the root google2).
patterns := []security.BlessingPattern{"google/alice/$", "google/bob", "google/alice/tablet/$", "google/bob/tablet"}
for _, p := range patterns {
- ctxt, err := encrypter.Encrypt(ctx, p, &ptxt)
+ ctxt, err := encrypter.Encrypt(ctx, p, ptxt)
if err != nil {
t.Fatal(err)
}
@@ -210,14 +206,14 @@
// patterns should succeed.
patterns = []security.BlessingPattern{"google", "google/$", "google/alice", "google/bob", "google/bob/phone"}
for _, p := range patterns {
- if _, err := decrypter.Encrypt(ctx, p, &ptxt); err != nil {
+ if _, err := decrypter.Encrypt(ctx, p, ptxt); err != nil {
t.Fatal(err)
}
}
// But encrypting for the following patterns should fail.
patterns = []security.BlessingPattern{"youtube", "youtube/$", "youtube/alice"}
for _, p := range patterns {
- if _, err := decrypter.Encrypt(ctx, p, &ptxt); verror.ErrorID(err) != ErrNoParams.ID {
+ if _, err := decrypter.Encrypt(ctx, p, ptxt); verror.ErrorID(err) != ErrNoParams.ID {
t.Fatalf("Got error %v, wanted error with ID %v", err, ErrNoParams.ID)
}
}
@@ -233,7 +229,7 @@
if err := enc.AddParams(ctx, params); err != nil {
t.Fatal(err)
}
- ctxt, err := enc.Encrypt(ctx, pattern, &ptxt)
+ ctxt, err := enc.Encrypt(ctx, pattern, ptxt)
if err != nil {
t.Fatal(err)
}
@@ -246,8 +242,8 @@
}
if got, err := dec.Decrypt(ctx, ctxt); err != nil {
return err
- } else if !bytes.Equal((*got)[:], ptxt[:]) {
- return fmt.Errorf("got plaintext %v, want %v", *got, ptxt)
+ } else if !bytes.Equal(got, ptxt) {
+ return fmt.Errorf("got plaintext %v, want %v", got, ptxt)
}
return nil
}