Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support session packet decryption #1

Open
szszszsz opened this issue Sep 5, 2022 · 4 comments
Open

Support session packet decryption #1

szszszsz opened this issue Sep 5, 2022 · 4 comments

Comments

@szszszsz
Copy link
Member

szszszsz commented Sep 5, 2022

Support session packet decryption through Nitrokey Webcrypt.

Previous discussions:

See below for the details:

@szszszsz
Copy link
Member Author

szszszsz commented Sep 5, 2022

Hi! @tomholub @twiss @onlykey

I would like to implement support for Nitrokey Webcrypt inside OpenPGP.js as a POC, so the key management and private key operations could be realized on the USB stick, instead of the PC. See ticket's description for more information.

In the past conversation there was a request for a session key decryption operation. Can you suggest how this could be done given OpenPGP.js current internals?

The way its done in the OpenPGP card specification is, that only the shared secret is calculated from the given ECC session public key of the sender. This should be enough to continue with the process on the OpenPGP.js side. Then this would be a function of a public key and algorithm OID, which could be injected inside the current session key decryption process.
What do you think?

Relevant excerpt:

PS We plan to introduce RSA after we have ECC support working.

@twiss
Copy link

twiss commented Sep 5, 2022

Hey 👋

Just to confirm, the USB key only performs (in the case of ECC) the ECDH key derivation (i.e. the equivalent of this line of code), not the KDF and key unwrapping done afterwards, correct? (Or can it also do the latter? If so, it would simplify things, and you can ignore most of this comment :))

OpenPGP.js does not export those low-level operations, however, if you're making a fork you do of course have access to them. Or, you could simply replace the linked line with one that calls out to the USB key to do the key derivation.

That would make it a bit difficult to merge back the functionality into OpenPGP.js, though, if we want to do so at some point. But, one way I could see that might be feasible would be to add a function / hook to the config object, which OpenPGP.js could call out to to do the decryption operation. Something like:

await openpgp.decrypt({ // or decryptSessionKeys
  message,
  decryptionKeys,
  config: { deriveSharedKey }
});

async function deriveSharedKey(fingerprint, oid, publicEphemeral) {
  // Call out to the USB key...
  return sharedKey;
}

Where deriveSharedKey (or an object containing multiple hooks / functions) could be imported from elsewhere, e.g. a plugin.

And decryptionKeys would be OpenPGP.js key objects with GNU-dummy private keys for the subkeys that are stored on the USB key (I believe that's what GnuPG does as well). This approach would have the advantage that OpenPGP.js can handle looking for the relevant subkey, and call deriveSharedKey multiple times if it's unknown which subkey the message was encrypted with (each time with the fingerprint of a different subkey). The downside might be that, in that case, it might be less efficient than having this handled elsewhere, especially if you anyway need to fetch all keys to match them to the given fingerprint? I'm not sure about this part. (If we go this route, we'd need to modify this code.)

One slightly annoying thing (if my understanding above is correct) is that the KDF and AES-KW operations are specific to ECDH, RSA doesn't do them. So we'd need separate helper functions for RSA and ECC. But maybe that's livable / just the way it is.

@tomholub
Copy link

tomholub commented Sep 5, 2022

Indeed - what Daniel describes is a more specific proposal of what I hinted at here #8

@szszszsz
Copy link
Member Author

Hey! Thank you for the pointers and sorry for being silent for the last weeks!

I have published a potential plugin solution at openpgpjs#1567. Please take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants