GithubHelp home page GithubHelp logo

Comments (4)

phiros avatar phiros commented on May 20, 2024

I can only second that. Observed this error recently and was completly confused...

from rpgp.

link2xt avatar link2xt commented on May 20, 2024

I have made a minimal test and added it to tests/key_test.rs:

#[test]
fn test_encrypted_key() {
    let p = Path::new("./tests/key-with-password-123.asc");
    let mut file = read_file(p.to_path_buf());

    let mut buf = vec![];
    file.read_to_end(&mut buf).unwrap();

    let input = ::std::str::from_utf8(buf.as_slice()).expect("failed to convert to string");
    let (key, _headers) = SignedSecretKey::from_armor_single(Cursor::new(input)).expect("failed to parse key");
    let (key, _headers) = SignedSecretKey::from_string(input).expect("failed to parse key");
    key.verify().expect("invalid key");
    let unsigned_pubkey = key.public_key();
    let _signed_pubkey = unsigned_pubkey.sign(&key, || "".into()).unwrap();
}

Key with password 123 generated with sq is here:

-----BEGIN PGP PRIVATE KEY BLOCK-----
Comment: B5A3 5856 0F60 BFC0 0885  4634 7C91 8F21 C12B 5F5B
Comment: [email protected]

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
yvKV8lJR3Pdw6go=
=aYbQ
-----END PGP PRIVATE KEY BLOCK-----

Here is what sq packet dump says about the first packet:

Secret-Key Packet, new CTB, 134 bytes
    Version: 4
    Creation time: 2023-12-17 16:19:56 UTC
    Pk algo: EdDSA
    Pk size: 256 bits
    Fingerprint: B5A358560F60BFC0088546347C918F21C12B5F5B
    KeyID: 7C918F21C12B5F5B
  
    Secret Key:
  
        Encrypted
        S2K: Iterated
          Hash: SHA256
          Salt: A913EF7B409815EB
          Hash bytes: 65011712
        Sym. algo: AES-256

gpg --list-packets output:

# off=0 ctb=c5 tag=5 hlen=2 plen=134 new-ctb
:secret key packet:
	version 4, algo 22, created 1702829996, expires 0
	pkey[0]: [80 bits] ed25519 (1.3.6.1.4.1.11591.15.1)
	pkey[1]: [263 bits]
	iter+salt S2K, algo: 9, SHA1 protection, hash: 8, salt: A913EF7B409815EB
	protect count: 65011712 (255)
	protect IV:  11 40 77 5c 21 09 e7 c9 bd c4 97 2f ce 74 41 ed
	skey[2]: [v4 protected]
	keyid: 7C918F21C12B5F5B

It is an AES-256 encrypted packet and there is a SHA1 checksum.

The test fails here:

PlainSecretParams::from_slice(&plaintext, alg, params)

Apparently it tries to parse plaintext "decrypted" with empty passphrase right above without checking any checksums.
RFC 4880 says about the secret-key packet:

   The two-octet checksum that follows the algorithm-specific portion is
   the algebraic sum, mod 65536, of the plaintext of all the algorithm-
   specific octets (including MPI prefix and data).  With V3 keys, the
   checksum is stored in the clear.  With V4 keys, the checksum is
   encrypted like the algorithm-specific data.  This value is used to
   check that the passphrase was correct.  However, this checksum is
   deprecated; an implementation SHOULD NOT use it, but should rather
   use the SHA-1 hash denoted with a usage octet of 254.  The reason for
   this is that there are some attacks that involve undetectably
   modifying the secret key.

So rPGP must check SHA-1 hash before attempting to parse decrypted data.

from rpgp.

link2xt avatar link2xt commented on May 20, 2024

This is where SHA-1 checksum is written in case of id 254:

data.extend_from_slice(&self.checksum_sha1()[..]);

But when parsing it is not checked.

from rpgp.

link2xt avatar link2xt commented on May 20, 2024

Made a fix: #260

from rpgp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.