diff --git a/go.mod b/go.mod index a43c8c3439a7b9faeef6998dba6a3513b577e7a6..a2317ff6ad983393775bb4f6c17e146daab7fd5e 100644 --- a/go.mod +++ b/go.mod @@ -15,11 +15,11 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.6.2 - gitlab.com/elixxir/comms v0.0.0-20200813225502-e879259ca741 - gitlab.com/elixxir/crypto v0.0.0-20200820010132-199706584933 + gitlab.com/elixxir/comms v0.0.0-20200825195434-49150e0605d8 + gitlab.com/elixxir/crypto v0.0.0-20200826034538-c67fec536436 gitlab.com/elixxir/ekv v0.0.0-20200729182028-159355ea5842 - gitlab.com/elixxir/primitives v0.0.0-20200812191102-31c01f08b4dc - gitlab.com/xx_network/comms v0.0.0-20200818182121-732dd75b1947 + gitlab.com/elixxir/primitives v0.0.0-20200826021242-53c364245a52 + gitlab.com/xx_network/comms v0.0.0-20200825213037-f58fa7c0a641 gitlab.com/xx_network/crypto v0.0.0-20200812183430-c77a5281c686 gitlab.com/xx_network/primitives v0.0.0-20200812183720-516a65a4a9b2 golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de diff --git a/go.sum b/go.sum index 1b5a3e0c9844badecef661ff02e257f33531083e..2a3f307a1065ada55e7b522b2e20d085f57cc043 100644 --- a/go.sum +++ b/go.sum @@ -165,6 +165,8 @@ gitlab.com/elixxir/comms v0.0.0-20200810165153-3039323b5656 h1:A5S3E7EPL95s3+PGh gitlab.com/elixxir/comms v0.0.0-20200810165153-3039323b5656/go.mod h1:EeS1z5wXKrnWOvR0dJlVNVv8OzuiGJz7fa6LyUeN6Q0= gitlab.com/elixxir/comms v0.0.0-20200813225502-e879259ca741 h1:yIjgre8xSDpnhJkDzTr1lgR7NC1bPWCk2Sgn8udiS2A= gitlab.com/elixxir/comms v0.0.0-20200813225502-e879259ca741/go.mod h1:hEi6dhcR1v6TGcp3tBy+QFuE25zux206xymuB+PpUqs= +gitlab.com/elixxir/comms v0.0.0-20200825195434-49150e0605d8 h1:6kwb++vm3XUf+AoR18bDfqNsKR8qghFkDERYmVAlwsU= +gitlab.com/elixxir/comms v0.0.0-20200825195434-49150e0605d8/go.mod h1:HW3Ige10aeJeyb2fcQ/YOBPiyzY/4jHau1Cj6/1WBHc= gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4 h1:28ftZDeYEko7xptCZzeFWS1Iam95dj46TWFVVlKmw6A= gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo+K0N2GwRRpaNr+tKXMIOVWzmyUD0SbOu2c= gitlab.com/elixxir/crypto v0.0.0-20200805174804-bdf909f2a16d/go.mod h1:cu6uNoANVLV0J6HyTL6KqVtVyh9SHU1RjJhytYlsbVQ= @@ -180,6 +182,10 @@ gitlab.com/elixxir/crypto v0.0.0-20200820001855-d8ff33b65ab5 h1:iZ8A3KnSxtI+WsMO gitlab.com/elixxir/crypto v0.0.0-20200820001855-d8ff33b65ab5/go.mod h1:pMageInOuHAQRZXnAD9yQMjhELcxb54bx4+NPT6K6tQ= gitlab.com/elixxir/crypto v0.0.0-20200820010132-199706584933 h1:A+wWm+OmGAUi4lnIqZUn6LtYguuO+wdLI5OOLwHqr5I= gitlab.com/elixxir/crypto v0.0.0-20200820010132-199706584933/go.mod h1:pMageInOuHAQRZXnAD9yQMjhELcxb54bx4+NPT6K6tQ= +gitlab.com/elixxir/crypto v0.0.0-20200826022234-44afcd036724 h1:9QUjB0U+fuAhMFWd6YFJVmmND0VEvxoxIa41PTtxu+E= +gitlab.com/elixxir/crypto v0.0.0-20200826022234-44afcd036724/go.mod h1:xELLVpaOMc4c14h6Lh3LlD++KYdEihWtRkHQI0FjjXc= +gitlab.com/elixxir/crypto v0.0.0-20200826034538-c67fec536436 h1:NvymTKdu5Zjf1tMpI6/TDvfok3xJx6EIrI3ZMWzmWx0= +gitlab.com/elixxir/crypto v0.0.0-20200826034538-c67fec536436/go.mod h1:xELLVpaOMc4c14h6Lh3LlD++KYdEihWtRkHQI0FjjXc= gitlab.com/elixxir/ekv v0.0.0-20200729182028-159355ea5842 h1:m1zDQ6UadpuMnV7nvnyR+DUXE3AisRnVjajTb1xZE4c= gitlab.com/elixxir/ekv v0.0.0-20200729182028-159355ea5842/go.mod h1:bXY0kgbV5BHYda4YY5/hiG5bjimGK+R3PYub5yM9C/s= gitlab.com/elixxir/primitives v0.0.0-20200731184040-494269b53b4d h1:OKWTmYN5q8XVHo8JXThIH0TCuvl/fLXR7MGVacpqfRg= @@ -193,12 +199,16 @@ gitlab.com/elixxir/primitives v0.0.0-20200805174810-86b366d1dd2d h1:ky5oz0D2EmOz gitlab.com/elixxir/primitives v0.0.0-20200805174810-86b366d1dd2d/go.mod h1:tzdFFvb1ESmuTCOl1z6+yf6oAICDxH2NPUemVgoNLxc= gitlab.com/elixxir/primitives v0.0.0-20200812191102-31c01f08b4dc h1:43innow2sbJLflB73gwS8gg1meInFXNA1LGYeeDQ6lw= gitlab.com/elixxir/primitives v0.0.0-20200812191102-31c01f08b4dc/go.mod h1:pJx2DZk9s8vVMnLN7x0hIPngDjbNSdOP6kk3RLlRxHg= +gitlab.com/elixxir/primitives v0.0.0-20200826021242-53c364245a52 h1:J+T7B6EurXrABFEWCRUPoJAXq93r1YCuv28RN0ICzaA= +gitlab.com/elixxir/primitives v0.0.0-20200826021242-53c364245a52/go.mod h1:kNp47yPqja2lHSiS4DddTvFpB/4D9dB2YKnw5c+LJCE= gitlab.com/xx_network/comms v0.0.0-20200805174823-841427dd5023/go.mod h1:owEcxTRl7gsoM8c3RQ5KAm5GstxrJp5tn+6JfQ4z5Hw= gitlab.com/xx_network/comms v0.0.0-20200806235452-3a82720833ba h1:7nozLSNBX0CfP53DDiDNLJx9obhYGfGf5na0/c9rMso= gitlab.com/xx_network/comms v0.0.0-20200806235452-3a82720833ba/go.mod h1:idLzPGYig57XE7xuU93OlIF9s6NgSJj7OArQvsd5DjY= gitlab.com/xx_network/comms v0.0.0-20200812204124-8dc2a2a1b9ca/go.mod h1:idLzPGYig57XE7xuU93OlIF9s6NgSJj7OArQvsd5DjY= gitlab.com/xx_network/comms v0.0.0-20200818182121-732dd75b1947 h1:g0k4nP0o/6qkh09F9d/Fy7Ys93fkyZU+kK71JviLdMg= gitlab.com/xx_network/comms v0.0.0-20200818182121-732dd75b1947/go.mod h1:idLzPGYig57XE7xuU93OlIF9s6NgSJj7OArQvsd5DjY= +gitlab.com/xx_network/comms v0.0.0-20200825213037-f58fa7c0a641 h1:d48S6FLIUJa1RMm5E20P/kbM8upHmfVgoc9G4+TDjhk= +gitlab.com/xx_network/comms v0.0.0-20200825213037-f58fa7c0a641/go.mod h1:idLzPGYig57XE7xuU93OlIF9s6NgSJj7OArQvsd5DjY= gitlab.com/xx_network/crypto v0.0.0-20200806202113-978fa1984bbf/go.mod h1:i0df/q6dDCBiscgD51fMoS2U2TBrm6LcyN822JmB5Tw= gitlab.com/xx_network/crypto v0.0.0-20200806235322-ede3c15881ce h1:gypNBUl2guESEv4MDgH+miwYqR4jPoWM8dLt2Zs5gIs= gitlab.com/xx_network/crypto v0.0.0-20200806235322-ede3c15881ce/go.mod h1:i0df/q6dDCBiscgD51fMoS2U2TBrm6LcyN822JmB5Tw= diff --git a/key/key.go b/key/key.go index a970c4531046f5e976425bc012c6ce76b11b449c..b59c7f6af7f28bc2591cdbd38cbce2b48ae309e0 100644 --- a/key/key.go +++ b/key/key.go @@ -2,8 +2,6 @@ package key import ( "github.com/pkg/errors" - "gitlab.com/elixxir/client/globals" - "gitlab.com/elixxir/client/parse" "gitlab.com/elixxir/crypto/e2e" "gitlab.com/elixxir/crypto/hash" "gitlab.com/elixxir/primitives/format" @@ -15,18 +13,14 @@ type Key struct { fp *format.Fingerprint - // Designation of crypto type - outer parse.CryptoType - // keyNum is the index of the key by order of creation // it is used to identify the key in the key.Session keyNum uint32 } -func newKey(session *Session, outer parse.CryptoType, keynum uint32) *Key { +func newKey(session *Session, keynum uint32) *Key { return &Key{ session: session, - outer: outer, keyNum: keynum, } } @@ -34,9 +28,6 @@ func newKey(session *Session, outer parse.CryptoType, keynum uint32) *Key { // return pointers to higher level management structures func (k *Key) GetSession() *Session { return k.session } -// return the type of encryption this key is for -func (k *Key) GetCryptoType() parse.CryptoType { return k.outer } - // returns the key fingerprint if it has it, otherwise generates it // this function does not memoize the fingerprint if it doesnt have it because // in most cases it will not be used for a long time and as a result should not @@ -45,19 +36,7 @@ func (k *Key) Fingerprint() format.Fingerprint { if k.fp != nil { return *k.fp } - - var fp format.Fingerprint - switch k.outer { - case parse.E2E: - fp = e2e.DeriveKeyFingerprint(k.session.baseKey, k.keyNum) - case parse.Rekey: - fp = e2e.DeriveReKeyFingerprint(k.session.baseKey, k.keyNum) - default: - globals.Log.FATAL.Panicf("Key has invalid cryptotype: %s", - k.outer) - } - - return fp + return e2e.DeriveKeyFingerprint(k.session.baseKey, k.keyNum) } // the E2E key to encrypt msg to its intended recipient @@ -74,45 +53,14 @@ func (k *Key) Encrypt(msg format.Message) format.Message { msg.SetTimestamp(encryptTimestamp(fp, key, msg.GetTimestamp()[:15])) // encrypt the payload - encPayload, err := e2e.Encrypt(key, fp, msg.Contents.GetRightAligned(), format.ContentsLen) - if err != nil { - globals.Log.ERROR.Panicf(err.Error()) - } - msg.Contents.Set(encPayload) - - // create the MAC - // MAC is HMAC(key, ciphertext) - // Currently, the MAC doesn't include any of the associated data - MAC := hash.CreateHMAC(encPayload, key[:]) - msg.SetMAC(MAC) - - return msg -} - -// the E2E key to encrypt msg to its intended recipient -// It also properly populates the associated data, including the MAC, fingerprint, -// and encrypted timestamp -// does not handle padding, so the underlying data must be unique or there are -// cryptographic vulnerabilities -func (k *Key) EncryptUnsafe(msg format.Message) format.Message { - fp := k.Fingerprint() - key := k.generateKey() - - // set the fingerprint - msg.SetKeyFP(fp) - - // encrypt the timestamp - msg.SetTimestamp(encryptTimestamp(fp, key, msg.GetTimestamp())) - - // encrypt the payload - encPayload := e2e.CryptUnsafe(key, fp, msg.Contents.Get()) - msg.Contents.Set(encPayload) + encPayload := e2e.Crypt(key, fp, msg.GetSecretPayload()) + msg.SetSecretPayload(encPayload) // create the MAC // MAC is HMAC(key, ciphertext) // Currently, the MAC doesn't include any of the associated data MAC := hash.CreateHMAC(encPayload, key[:]) - msg.SetMAC(MAC) + msg.SetMac(MAC) return msg } @@ -125,7 +73,7 @@ func (k *Key) Decrypt(msg format.Message) (format.Message, error) { key := k.generateKey() // Verify the MAC is correct - if !hash.VerifyHMAC(msg.Contents.Get(), msg.GetMAC(), key[:]) { + if !hash.VerifyHMAC(msg.GetSecretPayload(), msg.GetMac(), key[:]) { return format.Message{}, errors.New("HMAC verification failed for E2E message") } @@ -138,83 +86,22 @@ func (k *Key) Decrypt(msg format.Message) (format.Message, error) { msg.SetTimestamp(decryptedTimestamp) // Decrypt the payload - decryptedPayload, err := e2e.Decrypt(key, fp, msg.Contents.Get()) - - if err != nil { - return format.Message{}, errors.Errorf("Failed to decrypt E2E "+ - "message: %s", err.Error()) - } + decryptedPayload := e2e.Crypt(key, fp, msg.GetSecretPayload()) //put the decrypted payload back in the message - msg.Contents.SetRightAligned(decryptedPayload) - - return msg, nil -} - -// Decrypt uses the E2E key to decrypt the message -// It returns an error in case of HMAC verification failure -// assumes the payload has no padding -func (k *Key) DecryptUnsafe(msg format.Message) (format.Message, error) { - fp := k.Fingerprint() - key := k.generateKey() - - // Verify the MAC is correct - if !hash.VerifyHMAC(msg.Contents.Get(), msg.GetMAC(), key[:]) { - return format.Message{}, errors.New("HMAC verification failed for E2E message") - } + msg.SetSecretPayload(decryptedPayload) - //decrypt the timestamp - decryptedTimestamp, err := decryptTimestamp(fp, key, msg.GetTimestamp()) - if err != nil { - return format.Message{}, errors.Errorf("Failed to decrypt E2E "+ - "message: %s", err.Error()) - } - msg.SetTimestamp(decryptedTimestamp) - - // Decrypt the payload - decryptedPayload := e2e.CryptUnsafe(key, fp, msg.Contents.Get()) - - //put the decrypted payload back in the message - msg.Contents.Set(decryptedPayload) return msg, nil } // Sets the key as used func (k *Key) denoteUse() error { - switch k.outer { - case parse.E2E: - err := k.session.useKey(k.keyNum) - if err != nil { - return errors.WithMessage(err, "Could not use e2e key") - } - - case parse.Rekey: - err := k.session.useReKey(k.keyNum) - if err != nil { - return errors.WithMessage(err, "Could not use e2e rekey") - } - default: - globals.Log.FATAL.Panicf("Key has invalid cryptotype: %s", - k.outer) - } - return nil + return k.session.useKey(k.keyNum) } // Generates the key and returns it func (k *Key) generateKey() e2e.Key { - - var key e2e.Key - switch k.outer { - case parse.E2E: - key = e2e.DeriveKey(k.session.baseKey, k.keyNum) - case parse.Rekey: - key = e2e.DeriveReKey(k.session.baseKey, k.keyNum) - default: - globals.Log.FATAL.Panicf("Key has invalid cryptotype: %s", - k.outer) - } - - return key + return e2e.DeriveKey(k.session.baseKey, k.keyNum) } //encrypts the timestamp diff --git a/key/key_test.go b/key/key_test.go index 256d16279e3ea3f2135087dc1540e56efefe2a61..fa0ddb4e848cebe9832ceb338d5560c6dccba1ed 100644 --- a/key/key_test.go +++ b/key/key_test.go @@ -2,7 +2,6 @@ package key import ( "bytes" - "gitlab.com/elixxir/client/parse" "gitlab.com/elixxir/crypto/csprng" "gitlab.com/elixxir/crypto/cyclic" dh "gitlab.com/elixxir/crypto/diffieHellman" @@ -14,7 +13,7 @@ import ( "time" ) -func TestKey_EncryptDecrypt_Key(t *testing.T) { +func TestKey_EncryptDecrypt(t *testing.T) { const numTests = 100 @@ -33,15 +32,15 @@ func TestKey_EncryptDecrypt_Key(t *testing.T) { } //create the keys - k := newKey(s, parse.E2E, prng.Uint32()) + k := newKey(s, prng.Uint32()) //make the message to be encrypted - msg := format.NewMessage() + msg := format.NewMessage(grp.GetP().ByteLen()) //set the contents - contents := make([]byte, format.ContentsLen-format.PadMinLen) + contents := make([]byte, msg.ContentsSize()) prng.Read(contents) - msg.Contents.SetRightAligned(contents) + msg.SetContents(contents) //set the timestamp now := time.Now() @@ -50,7 +49,7 @@ func TestKey_EncryptDecrypt_Key(t *testing.T) { msg.SetTimestamp(extendedNowBytes) //Encrypt - ecrMsg := k.Encrypt(*msg) + ecrMsg := k.Encrypt(msg) if !reflect.DeepEqual(k.Fingerprint(), ecrMsg.GetKeyFP()) { t.Errorf("Fingerprint in the ecrypted payload is wrong: "+ @@ -60,127 +59,9 @@ func TestKey_EncryptDecrypt_Key(t *testing.T) { //Decrypt resultMsg, _ := k.Decrypt(ecrMsg) - if !bytes.Equal(resultMsg.Contents.Get(), msg.Contents.Get()) { + if !bytes.Equal(resultMsg.GetContents(), msg.GetContents()) { t.Errorf("contents in the decrypted payload does not match: "+ - "Expected: %v, Recieved: %v", msg.Contents.Get(), resultMsg.Contents.Get()) - } - - if !bytes.Equal(resultMsg.GetTimestamp(), msg.GetTimestamp()) { - t.Errorf("timestamp in the decrypted payload does not match: "+ - "Expected: %v, Recieved: %v", msg.GetTimestamp(), resultMsg.GetTimestamp()) - } - } - -} - -func TestKey_EncryptDecrypt_ReKey(t *testing.T) { - - const numTests = 100 - - grp := getGroup() - rng := csprng.NewSystemRNG() - prng := rand.New(rand.NewSource(42)) - - for i := 0; i < numTests; i++ { - //generate the baseKey and session - privateKey := dh.GeneratePrivateKey(dh.DefaultPrivateKeyLength, grp, rng) - publicKey := dh.GeneratePublicKey(privateKey, grp) - baseKey := dh.GenerateSessionKey(privateKey, publicKey, grp) - - s := &Session{ - baseKey: baseKey, - } - - //create the keys - k := newKey(s, parse.Rekey, prng.Uint32()) - - //make the message to be encrypted - msg := format.NewMessage() - - //set the contents - contents := make([]byte, format.ContentsLen-format.PadMinLen) - prng.Read(contents) - msg.Contents.SetRightAligned(contents) - - //set the timestamp - now := time.Now() - nowBytes, _ := now.MarshalBinary() - extendedNowBytes := append(nowBytes, 0) - msg.SetTimestamp(extendedNowBytes) - - //Encrypt - ecrMsg := k.Encrypt(*msg) - - if !reflect.DeepEqual(k.Fingerprint(), ecrMsg.GetKeyFP()) { - t.Errorf("Fingerprint in the ecrypted payload is wrong: "+ - "Expected: %+v, Recieved: %+v", k.Fingerprint(), ecrMsg.GetKeyFP()) - } - - //Decrypt - resultMsg, _ := k.Decrypt(ecrMsg) - - if !bytes.Equal(resultMsg.Contents.Get(), msg.Contents.Get()) { - t.Errorf("contents in the decrypted payload does not match: "+ - "Expected: %v, Recieved: %v", msg.Contents.Get(), resultMsg.Contents.Get()) - } - - if !bytes.Equal(resultMsg.GetTimestamp(), msg.GetTimestamp()) { - t.Errorf("timestamp in the decrypted payload does not match: "+ - "Expected: %v, Recieved: %v", msg.GetTimestamp(), resultMsg.GetTimestamp()) - } - } - -} - -func TestKey_EncryptDecrypt_Key_Unsafe(t *testing.T) { - - const numTests = 100 - - grp := getGroup() - rng := csprng.NewSystemRNG() - prng := rand.New(rand.NewSource(42)) - - for i := 0; i < numTests; i++ { - //generate the baseKey and session - privateKey := dh.GeneratePrivateKey(dh.DefaultPrivateKeyLength, grp, rng) - publicKey := dh.GeneratePublicKey(privateKey, grp) - baseKey := dh.GenerateSessionKey(privateKey, publicKey, grp) - - s := &Session{ - baseKey: baseKey, - } - - //create the keys - k := newKey(s, parse.E2E, 1) - - //make the message to be encrypted - msg := format.NewMessage() - - //set the contents - contents := make([]byte, format.ContentsLen) - prng.Read(contents) - msg.Contents.Set(contents) - - //set the timestamp - now := time.Now() - nowBytes, _ := now.MarshalBinary() - extendedNowBytes := append(nowBytes, 0) - msg.SetTimestamp(extendedNowBytes) - - //Encrypt - ecrMsg := k.EncryptUnsafe(*msg) - - if !reflect.DeepEqual(k.Fingerprint(), ecrMsg.GetKeyFP()) { - t.Errorf("Fingerprint in the ecrypted payload is wrong: "+ - "Expected: %+v, Recieved: %+v", k.Fingerprint(), ecrMsg.GetKeyFP()) - } - - //Decrypt - resultMsg, _ := k.DecryptUnsafe(ecrMsg) - - if !bytes.Equal(resultMsg.Contents.Get(), msg.Contents.Get()) { - t.Errorf("contents in the decrypted payload does not match: "+ - "Expected: %v, Recieved: %v", msg.Contents.Get(), resultMsg.Contents.Get()) + "Expected: %v, Recieved: %v", msg.GetContents(), resultMsg.GetContents()) } if !bytes.Equal(resultMsg.GetTimestamp(), msg.GetTimestamp()) { @@ -190,64 +71,6 @@ func TestKey_EncryptDecrypt_Key_Unsafe(t *testing.T) { } } -func TestKey_EncryptDecrypt_ReKey_Unsafe(t *testing.T) { - - const numTests = 100 - - grp := getGroup() - rng := csprng.NewSystemRNG() - prng := rand.New(rand.NewSource(42)) - - for i := 0; i < numTests; i++ { - //generate the baseKey and session - privateKey := dh.GeneratePrivateKey(dh.DefaultPrivateKeyLength, grp, rng) - publicKey := dh.GeneratePublicKey(privateKey, grp) - baseKey := dh.GenerateSessionKey(privateKey, publicKey, grp) - - s := &Session{ - baseKey: baseKey, - } - - //create the keys - k := newKey(s, parse.E2E, 1) - - //make the message to be encrypted - msg := format.NewMessage() - - //set the contents - contents := make([]byte, format.ContentsLen) - prng.Read(contents) - msg.Contents.Set(contents) - - //set the timestamp - now := time.Now() - nowBytes, _ := now.MarshalBinary() - extendedNowBytes := append(nowBytes, 0) - msg.SetTimestamp(extendedNowBytes) - - //Encrypt - ecrMsg := k.EncryptUnsafe(*msg) - - if !reflect.DeepEqual(k.Fingerprint(), ecrMsg.GetKeyFP()) { - t.Errorf("Fingerprint in the ecrypted payload is wrong: "+ - "Expected: %+v, Recieved: %+v", k.Fingerprint(), ecrMsg.GetKeyFP()) - } - - //Decrypt - resultMsg, _ := k.DecryptUnsafe(ecrMsg) - - if !bytes.Equal(resultMsg.Contents.Get(), msg.Contents.Get()) { - t.Errorf("contents in the decrypted payload does not match: "+ - "Expected: %v, Recieved: %v", msg.Contents.Get(), resultMsg.Contents.Get()) - } - - if !bytes.Equal(resultMsg.GetTimestamp(), msg.GetTimestamp()) { - t.Errorf("timestamp in the decrypted payload does not match: "+ - "Expected: %v, Recieved: %v", msg.GetTimestamp(), resultMsg.GetTimestamp()) - } - } - -} func getGroup() *cyclic.Group { e2eGrp := cyclic.NewGroup( diff --git a/key/session.go b/key/session.go index a62d866ae07832172dcb25bc7f96d0355b06ed79..905f98dc9178b4e82867baf81023071d98ee692d 100644 --- a/key/session.go +++ b/key/session.go @@ -2,7 +2,7 @@ package key import ( "encoding/json" - "gitlab.com/elixxir/client/parse" + "errors" "gitlab.com/elixxir/client/storage" "gitlab.com/elixxir/crypto/csprng" "gitlab.com/elixxir/crypto/cyclic" @@ -42,9 +42,6 @@ type Session struct { // Received Keys dirty bits // Each bit represents a single Key keyState *stateVector - // Received ReKeys dirty bits - // Each bit represents a single ReKey - reKeyState *stateVector //mutex mux sync.RWMutex @@ -137,7 +134,6 @@ func (s *Session) Delete() error { defer s.mux.Unlock() s.manager.ctx.fa.remove(s.getUnusedKeys()) - s.manager.ctx.fa.remove(s.getUnusedReKeys()) return s.manager.ctx.kv.Delete(makeSessionKey(s.GetID())) } @@ -208,47 +204,43 @@ func (s *Session) unmarshal(b []byte) error { return err } - s.reKeyState, err = loadStateVector(s.manager.ctx, makeStateVectorKey("reKeyStates", sid)) - if err != nil { - return err - } - if s.t == Receive { //register keys s.manager.ctx.fa.add(s.getUnusedKeys()) - - //register rekeys - s.manager.ctx.fa.add(s.getUnusedReKeys()) } return nil } //key usage -// Pops the first unused key, skipping any which are denoted as used. The status -// is returned to check if a rekey is nessessary +// Pops the first unused key, skipping any which are denoted as used. +// will return if the remaining keys are designated as rekeys func (s *Session) PopKey() (*Key, error) { + if s.keyState.numkeys-s.keyState.numAvalible <= uint32(s.params.NumRekeys) { + return nil, errors.New("no more keys left, remaining reserved " + + "for rekey") + } keyNum, err := s.keyState.Next() if err != nil { return nil, err } - return newKey(s, parse.E2E, keyNum), nil + return newKey(s, keyNum), nil } -// Pops the first unused rekey, skipping any which are denoted as used func (s *Session) PopReKey() (*Key, error) { - keyNum, err := s.reKeyState.Next() + keyNum, err := s.keyState.Next() if err != nil { return nil, err } - return newKey(s, parse.Rekey, keyNum), nil + + return newKey(s, keyNum), nil } // returns the state of the session, which denotes if the Session is active, // functional but in need of a rekey, empty of send key, or empty of rekeys func (s *Session) Status() Status { - if s.reKeyState.GetNumKeys() == 0 { + if s.keyState.numkeys-s.keyState.numAvalible <= uint32(s.params.NumRekeys) { return RekeyEmpty } else if s.keyState.GetNumKeys() == 0 { return Empty @@ -289,10 +281,6 @@ func (s *Session) useKey(keynum uint32) error { return s.keyState.Use(keynum) } -func (s *Session) useReKey(keynum uint32) error { - return s.reKeyState.Use(keynum) -} - // generates keys from the base data stored in the session object. // myPrivKey will be generated if not present func (s *Session) generate() { @@ -311,21 +299,21 @@ func (s *Session) generate() { keysTTL, numKeys := e2e.GenerateKeyTTL(s.baseKey.GetLargeInt(), s.params.MinKeys, s.params.MaxKeys, s.params.TTLParams) + //ensure that enough keys are remaining to rekey + if numKeys-uint32(keysTTL) < uint32(s.params.NumRekeys) { + numKeys = uint32(keysTTL + s.params.NumRekeys) + } + s.ttl = uint32(keysTTL) //create the new state vectors. This will cause disk operations storing them s.keyState = newStateVector(s.manager.ctx, keyEKVPrefix, numKeys) - s.reKeyState = newStateVector(s.manager.ctx, reKeyEKVPrefix, uint32(s.params.NumRekeys)) //register keys for reception if this is a reception session if s.t == Receive { //register keys - s.manager.ctx.fa.add(s.getUnusedKeys()) - - //register rekeys - s.manager.ctx.fa.add(s.getUnusedReKeys()) } } @@ -335,20 +323,8 @@ func (s *Session) getUnusedKeys() []*Key { keys := make([]*Key, len(keyNums)) for i, keyNum := range keyNums { - keys[i] = newKey(s, parse.E2E, keyNum) + keys[i] = newKey(s, keyNum) } return keys } - -//returns rekey objects for all unused rekeys -func (s *Session) getUnusedReKeys() []*Key { - reKeyNums := s.reKeyState.GetUnusedKeyNums() - - rekeys := make([]*Key, len(reKeyNums)) - for i, rekeyNum := range reKeyNums { - rekeys[i] = newKey(s, parse.Rekey, rekeyNum) - } - - return rekeys -} diff --git a/key/session_test.go b/key/session_test.go index d469780e82fbf660d5aea47891df7f31e33ed239..63bd0215ebd7b67097128dec0373a74fd6e55998 100644 --- a/key/session_test.go +++ b/key/session_test.go @@ -1,7 +1,6 @@ package key import ( - "gitlab.com/elixxir/client/parse" "gitlab.com/elixxir/client/storage" "gitlab.com/elixxir/crypto/csprng" dh "gitlab.com/elixxir/crypto/diffieHellman" @@ -58,21 +57,9 @@ func TestSession_generate_noPrivateKeyReceive(t *testing.T) { t.Errorf("keystates not generated") } - if s.reKeyState == nil { - t.Errorf("reKeyStates not generated") - } - //verify keys were registered in the fingerprintMap for keyNum := uint32(0); keyNum < s.keyState.numkeys; keyNum++ { - key := newKey(s, parse.E2E, keyNum) - if _, ok := fps.toKey[key.Fingerprint()]; !ok { - t.Errorf("key %v not in fingerprint map", keyNum) - } - } - - //verify rekeys were registered in the fingerprintMap - for keyNum := uint32(0); keyNum < s.reKeyState.numkeys; keyNum++ { - key := newKey(s, parse.Rekey, keyNum) + key := newKey(s, keyNum) if _, ok := fps.toKey[key.Fingerprint()]; !ok { t.Errorf("key %v not in fingerprint map", keyNum) } @@ -132,21 +119,9 @@ func TestSession_generate_PrivateKeySend(t *testing.T) { t.Errorf("keystates not generated") } - if s.reKeyState == nil { - t.Errorf("reKeyStates not generated") - } - //verify keys were not registered in the fingerprintMap for keyNum := uint32(0); keyNum < s.keyState.numkeys; keyNum++ { - key := newKey(s, parse.E2E, keyNum) - if _, ok := fps.toKey[key.Fingerprint()]; ok { - t.Errorf("key %v in fingerprint map", keyNum) - } - } - - //verify rekeys were not registered in the fingerprintMap - for keyNum := uint32(0); keyNum < s.reKeyState.numkeys; keyNum++ { - key := newKey(s, parse.Rekey, keyNum) + key := newKey(s, keyNum) if _, ok := fps.toKey[key.Fingerprint()]; ok { t.Errorf("key %v in fingerprint map", keyNum) } diff --git a/parse/partition.go b/parse/partition.go index b36c92de67722cfafaf71c7bd967b8c9cb507a0b..328a687c22dc8c88c85f2b9e4b68ace565a9d741 100644 --- a/parse/partition.go +++ b/parse/partition.go @@ -11,13 +11,13 @@ import ( "fmt" "github.com/pkg/errors" "gitlab.com/elixxir/client/globals" - "gitlab.com/elixxir/primitives/format" "math" "sync" ) func getMaxMessageLength() int { - return format.ContentsLen - format.PadMinLen + //fix-me: THIS IS A HACK SO IT COMPILES, THIS IS BROKEN + return 3192 / 8 } // TODO is there a better way to generate unique message IDs locally? @@ -131,7 +131,8 @@ func makePartition(maxLength int, body []byte, id []byte, i byte, func Assemble(partitions [][]byte) ([]byte, error) { // this will allocate a bit more capacity than needed but not so much that // it breaks the bank - result := make([]byte, 0, int(format.ContentsLen-format.PadMinLen)* + // fix-me: BROKEN DUE TO MAX_MESSAGE_LENGTH + result := make([]byte, 0, getMaxMessageLength()* len(partitions)) for i := range partitions { diff --git a/user/session.go b/user/session.go index 55f5744b66f7898786f6fa40c3c32904d7e6cc35..60baac5e298efb962fcc7903583f3cd857179928 100644 --- a/user/session.go +++ b/user/session.go @@ -106,7 +106,7 @@ func NewSession(store globals.Storage, KeyMaps: keyStore.NewStore(), RekeyManager: keyStore.NewRekeyManager(), store: store, - listeners: switchboard.NewSwitchboard(), + listeners: switchboard.New(), quitReceptionRunner: make(chan struct{}), password: password, Salt: salt, @@ -160,7 +160,7 @@ func LoadSession(store globals.Storage, password string) (Session, error) { session.KeyMaps.ReconstructKeys(session.E2EGrp, session.CurrentUser.User) // Create switchboard - session.listeners = switchboard.NewSwitchboard() + session.listeners = switchboard.New() // Create quit channel for reception runner session.quitReceptionRunner = make(chan struct{})