-
Notifications
You must be signed in to change notification settings - Fork 162
refactor: Crypter/Wallet crypto operations #459
Conversation
Codecov Report
@@ Coverage Diff @@
## master #459 +/- ##
==========================================
- Coverage 90.24% 89.93% -0.31%
==========================================
Files 65 66 +1
Lines 3445 3489 +44
==========================================
+ Hits 3109 3138 +29
- Misses 180 193 +13
- Partials 156 158 +2
Continue to review full report at Codecov.
|
return nil, fmt.Errorf("failed to encrypt message: %w", err) | ||
func (c *BaseCrypter) Encrypt(payload, senderKey []byte, recipients [][]byte) ([]byte, error) { //nolint:funlen | ||
if len(senderKey) == 0 { | ||
return nil, fmt.Errorf("failed to encrypt message") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error message should include something like empty sender key
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will update...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pkg/wallet/api.go
Outdated
// returns: | ||
// kek []byte | ||
// error in case of errors | ||
DeriveKEK(alg, apu []byte, fromKey, toPubKey *[chacha.KeySize]byte, isFromKeyPriv bool) ([]byte, error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a case where private key would be provided here? I am not clear why we need to expose isFromKeyPriv flag here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, when deriving a KEK from an ephemeral key created in the crypter, in this case fromKey
will be a private key.. this is why we need isFromKeyPriv
flag
but deriving a KEK for a CEK doesn't require an ephemeral key, and therefore fromKey
will be public to tell the function to load its corresponding private key from the wallet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can probably hide this function and expose 2 functions in the interface:
DeriveKEKUsingPrivKeyFromWallet() which will call DeriveKEK
with isFromKeyPriv
= false
DeriveKEKUsingEphemeralPrivKey() which will call DeriveKEK
with isFromKeyPriv
= true
this way isFromKeyPriv
flag is hidden from the interface user.
Agree?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make more sense to create utility function DeriveKEK that will work with private key? In that case we can have have only one method in the wallet that will retrieve private key and call utility function DeriveKEK. And for ephemeral keys since you already have private key you just call utility function DeriveKEK. I am not sure where to put this utility function though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll move the util function to util.go under wallet package.. will push soon
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
member DeriveKEK function takes fromKey as public key and calls a util exported function with the same name that does the real derivation using a private key.
done
// Envelope contain msg, FromVerKey and ToVerKeys | ||
type Envelope struct { | ||
Message []byte | ||
FromVerKey string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"From" and "To" are relative to the direction the envelope is going (inbound vs outbound) and might get confusing. I suggest we keep it simple:
- FromVerKey -> MyVerKey
- ToVerKeys -> TheirVerKeys
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how MyVerKey is clearer than FromVerKey?
This will be more confusing from the agent's perspective since MyVerKey
for a receiving agent is going to be different from the sending agent's while FromVerKey
is clear to be the sender's agent key, no matter who is using the Envelope (From
will always be source agent).
Again, this code was moved from wallet
into envelope
, it's not new code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Envelope
is exported for reasons I don't understand.
If all the complexity of handling Envelope
structs is contained within the packing/unpacking functionality then it's okay. But if Envelope
starts percolating into the application layer where code would have to first determine their role (sender vs receiver) before picking the right attribute ("from" vs "to") - that would be an unnecessary burden imposed on the application layer.
Separating packaging concerns ( |
@llorllale We've pulled the secret-touching out of the crypter and into the wallet - my suggestion to @Baha-sk was to rename the Crypters to Packagers, now that they're the envelope builders. They still do a bit of crypto, but that's always going to be integral to envelope building/parsing so I think it's reasonable. |
@Moopli as discussed in today's morning call, it's probably better to separate the concerns of packaging vs. encryption:
|
this will be done as part of a separate PR |
@llorllale @Baha-sk I opened #475 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
pkg/wallet/utils.go
Outdated
} | ||
|
||
// Derive25519KEK is a utility function that will derive an ephemeral symmetric key (kek) using fromPrivKey and toPubKey | ||
func Derive25519KEK(alg, apu []byte, fromPrivKey, toPubKey *[chacha.KeySize]byte) ([]byte, error) { // nolint:lll |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this used outside the package?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's used in the Crypter - DeriveKEK was split into a util function because the crypter needs to be able to pass an ephemeral private key in at one point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It still seems odd that the generic wallet package has a special 25519 method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will move utils.go to pkg/internal/cryptoutil to separate the utility logic from the wallet.. in the end, they are internal to our go framework and should not be exposed in the wallet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done... moved utils.go to pkg/internal/cryptoutil
package and updated all its references.
The current wallet is calling Pack/Unpack This behavior has now changed and delegated to a newer Packager interface In addition, operations involving private keys have been moved to the wallet. Namely, DerviveKEK() is the only function in the crypto functionality that deals with private keys Aries framework has been updated with new context functions to support the new structure. In addtion to WithWallet(), 2 new functions are added to the context provider: WithCrypter() and WithPackager(). JWE Crypto functionality depends on these providers in the following order: 1. WithWallet() 2. WithCrypter() 3. WithPackager() Also, minor refactoring of function names in the crypter was done for better readability. Finally the recipient key is no longer needed in Crypter.Decrypt() as it will be matched with the recipients's list in the envelope and the wallet's first key found. Signed-off-by: Baha Shaaban <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
closes #385
Signed-off-by: Baha Shaaban [email protected]