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

Try to use OpenPGP v6 keys #6226

Closed
wants to merge 5 commits into from
Closed

Try to use OpenPGP v6 keys #6226

wants to merge 5 commits into from

Conversation

link2xt
Copy link
Collaborator

@link2xt link2xt commented Nov 18, 2024

Experiment to see if we will be possible to introduce V6 in the future.

Currently receiving v6 X25519 in Autocrypt header results in Delta Chat storing it, but then not encrypting to the recipient. Even worse, message is encrypted and consists of a single SEIPDv1 packet, but session key is not encrypted to any recipients so nobody can decrypt the message, which is worse than sending it plaintext.

We need to wait for rPGP version with rpgp/rpgp#434 and probably reject keys that have no encryption subkeys right away instead of storing them.

Other features of OpenPGP v6 like SEIPDv2 are not tested yet.

@link2xt
Copy link
Collaborator Author

link2xt commented Nov 19, 2024

Don't know yet what's the problem with x25519, this test passes in rpgp repo:

index fff5c63..617d34b 100644
--- a/tests/rfc9580.rs
+++ b/tests/rfc9580.rs
@@ -1,9 +1,11 @@
 use std::fs::File;
+use std::io::Cursor;

 use pgp::crypto::ecc_curve::ECCCurve;
 use pgp::crypto::{aead::AeadAlgorithm, hash::HashAlgorithm, sym::SymmetricKeyAlgorithm};
 use pgp::packet::LiteralData;
-use pgp::types::KeyVersion;
+use pgp::types::{SecretKeyTrait, KeyVersion};
+use pgp::SubkeyParamsBuilder;
 use pgp::{
     cleartext::CleartextSignedMessage, Deserializable, KeyType, Message, SecretKeyParamsBuilder,
     SignedPublicKey, SignedSecretKey,
@@ -237,3 +239,37 @@ fn rfc9580_legacy_25519_illegal_in_v6() {

     assert!(res.is_err());
 }
+
+#[test]
+fn rfc9580_x25519() {
+    let mut rng = ChaCha8Rng::seed_from_u64(0);
+
+    let key_params = SecretKeyParamsBuilder::default()
+        .version(pgp::types::KeyVersion::V6)
+        .key_type(KeyType::Ed25519)
+        .can_certify(true)
+        .can_sign(true)
+        .primary_user_id("Me <me@example.com>".into())
+        .subkey(
+            SubkeyParamsBuilder::default()
+                .version(pgp::types::KeyVersion::V6)
+                .key_type(KeyType::X25519)
+                .can_encrypt(true)
+                .build()
+                .unwrap()).build().unwrap();
+    let unsigned_secret_key = key_params.generate(&mut rng).unwrap();
+    let signed_secret_key = unsigned_secret_key.sign(&mut rng, || "".into()).unwrap();
+    let unsigned_public_key = SecretKeyTrait::public_key(&signed_secret_key);
+    let signed_public_key = unsigned_public_key.sign(&mut rng, &signed_secret_key, || "".into()).unwrap();
+    let subkey_for_encryption = signed_public_key.public_subkeys.first().unwrap();
+
+    let lit_msg = Message::new_literal_bytes("", b"foobar");
+    let encrypted_msg = lit_msg.encrypt_to_keys_seipdv1(&mut rng, SymmetricKeyAlgorithm::AES128, &[&subkey_for_encryption]).unwrap();
+    let encoded_msg = encrypted_msg.to_armored_string(Default::default()).unwrap();
+
+    let cursor = Cursor::new(encoded_msg);
+    let (decoded_msg, _headers) = Message::from_armor_single(cursor).unwrap();
+
+    let (decrypted_msg, _key_ids) = decoded_msg.decrypt(|| "".into(), &[&signed_secret_key]).unwrap();
+    assert_eq!(decrypted_msg.get_content().unwrap().unwrap(), b"foobar");
+}

@link2xt
Copy link
Collaborator Author

link2xt commented Nov 19, 2024

X25519 does not work because it is ignored when selecting encryption subkey: rpgp/rpgp#434

@link2xt
Copy link
Collaborator Author

link2xt commented Nov 19, 2024

Does not work yet without X25519 fixes in rPGP, we will need to wait for the new version.

We will also need to fix key selection to look at key flags rather than just "if the key supports encryption".
Regarding fingerprint lengths, v4 fingerprints are 20-bytes long and v6 fingerprints are 32-bytes long which makes it possible to distinguish them, but I think we need to explicitly drop all the incoming keys that are not v4 and v6 and prevent importing them, so we can be sure Delta Chat only deals with v4 and v6 keys.

@link2xt link2xt closed this Nov 19, 2024
@link2xt link2xt changed the title feat: switch to OpenPGP v6 Try to use OpenPGP v6 keys Nov 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Closed PRs and Issues
Development

Successfully merging this pull request may close these issues.

1 participant