diff --git a/src/composed/key.rs b/src/composed/key.rs index 0d41523c..657de738 100644 --- a/src/composed/key.rs +++ b/src/composed/key.rs @@ -276,17 +276,20 @@ mod tests { let primary_n = hex!("a5 4c fa 91 42 fb 75 26 53 22 05 5b 11 f7 50 f4 9a f3 7b 64 c6 7a d8 30 ed 74 43 d6 c2 04 77 b0 49 2e e9 09 0e 4c b8 b0 c2 c5 d4 9e 87 df f5 ac 80 1b 1a aa db 31 9e ee 9d 3d 29 b2 5b d9 aa 63 4b 12 6c 0e 5d a4 e6 6b 41 4e 9d bd de 5d ea 0e 38 c5 bf e7 e5 f7 fd b9 f4 c1 b1 f3 9e d8 92 dd 4e 08 73 a0 df 66 ff 46 fd 92 36 d2 91 c2 76 ce 69 fb 97 2f 5e f2 47 46 b6 79 4a 0f 70 e0 69 46 67 b9 de 57 35 33 30 c7 32 73 3c c6 d5 f2 4c d7 72 c5 c7 d5 bd b7 7d c0 a5 b6 e9 d3 ee 03 72 14 67 78 cd a6 14 49 76 e3 30 66 fc 57 bf b5 15 ef 39 7b 3a a8 82 c0 bd e0 2d 19 f7 a3 2d f7 b1 19 5c b0 f3 2e 6e 74 55 ac 19 9f a4 34 35 5f 0f a4 32 30 e5 23 7e 9a 6e 0f f6 ad 5b 21 b4 d8 92 c6 fc 38 42 78 8b a4 8b 02 0e e8 5e dd 13 5c ff 28 08 78 0e 83 4b 5d 94 cc 2c 2b 5f a7 47 16 7a 20 81 45 89 d7 f0 30 ee 9f 8a 66 97 37 bd b0 63 e6 b0 b8 8a b0 fd 74 54 c0 3f 69 67 8a 1d d9 94 42 cf d0 bf 62 0b c5 b6 89 6c d6 e2 b5 1f de cf 54 c7 e6 36 8c 11 c7 0f 30 24 44 ec 9d 5a 17 ce aa cb 4a 9a c3 c3 7d b3 47 8f 8f b0 4a 67 9f 09 57 a3 69 7e 8d 90 15 20 08 92 7c 75 1b 34 16 0c 72 e7 57 ef c8 50 53 dd 86 73 89 31 fd 35 1c f1 34 26 6e 43 6e fd 64 a1 4b 35 86 90 40 10 80 82 84 7f 7f 52 15 62 8e 7f 66 51 38 09 ae 0f 66 ea 73 d0 1f 5f d9 65 14 2c db 78 60 27 6d 4c 20 fa f7 16 c4 0a e0 63 2d 3b 18 01 37 43 8c b9 52 57 32 76 07 03 8f b3 b8 2f 76 55 6e 8d d1 86 b7 7c 2f 51 b0 bf dd 75 52 f1 68 f2 c4 eb 90 84 4f dc 05 cf 23 9a 57 69 02 25 90 33 99 78 3a d3 73 68 91 ed b8 77 45 a1 18 0e 04 74 15 26 38 40 45 c2 de 03 c4 63 c4 3b 27 d5 ab 7f fd 6d 0e cc cc 24 9f").to_vec(); - assert_eq!( - key.primary_key, - key::PublicKey::new( - KeyVersion::V4, - PublicKeyAlgorithm::RSA, - key::PublicParams::RSA { - n: primary_n, - e: vec![1u8, 0u8, 1u8], - } - ).into() - ); + let pk = key.primary_key; + assert_eq!(pk.version(), &KeyVersion::V4); + assert_eq!(pk.algorithm(), &PublicKeyAlgorithm::RSA); + + match pk.public_params() { + key::PublicParams::RSA { n, e } => { + assert_eq!(n, &primary_n); + assert_eq!(e, &vec![1u8, 0u8, 1u8]); + } + _ => panic!("wrong public params: {:?}", pk.public_params()), + } + + assert_eq!(pk.created_at(), 1402070261); + assert_eq!(pk.expiration(), None); // TODO: examine subkey details assert_eq!(key.subkeys.len(), 1, "missing subkey"); diff --git a/src/packet/tags/privkey.rs b/src/packet/tags/privkey.rs index 51d795d3..84825a1b 100644 --- a/src/packet/tags/privkey.rs +++ b/src/packet/tags/privkey.rs @@ -8,26 +8,22 @@ use composed; use util::{mpi, rest_len}; // Ref: https://tools.ietf.org/html/rfc6637#section-9 -named_args!(ecdsa<'a>(alg: &'a PublicKeyAlgorithm, ver: &'a KeyVersion) , do_parse!( +named!(ecdsa<(PublicParams, EncryptedPrivateParams)>, do_parse!( // a one-octet size of the following field len: be_u8 // octets representing a curve OID >> curve: map_opt!(take!(len), ecc_curve_from_oid) // MPI of an EC point representing a public key >> p: mpi - >> (PrivateKey::new( - *ver, - *alg, - PublicParams::ECDSA { + >> (PublicParams::ECDSA { curve, p: p.to_vec() }, - EncryptedPrivateParams::new_plaintext(vec![], vec![]), - )) + EncryptedPrivateParams::new_plaintext(vec![], vec![])) )); // Ref: https://tools.ietf.org/html/rfc6637#section-9 -named_args!(ecdh<'a>(alg: &'a PublicKeyAlgorithm, ver: &'a KeyVersion) , do_parse!( +named!(ecdh<(PublicParams, EncryptedPrivateParams)>, do_parse!( // a one-octet size of the following field len: be_u8 // octets representing a curve OID @@ -43,57 +39,45 @@ named_args!(ecdh<'a>(alg: &'a PublicKeyAlgorithm, ver: &'a KeyVersion) > alg_sym: take!(1) - >> (PrivateKey::new( - *ver, - *alg, - PublicParams::ECDH { + >> (PublicParams::ECDH { curve, p: p.to_vec(), hash: hash[0], alg_sym: alg_sym[0] }, - EncryptedPrivateParams::new_plaintext(vec![], vec![]) - )) + EncryptedPrivateParams::new_plaintext(vec![], vec![])) )); -named_args!(elgamal<'a>(alg: &'a PublicKeyAlgorithm, ver: &'a KeyVersion) , do_parse!( +named!(elgamal<(PublicParams, EncryptedPrivateParams)>, do_parse!( // MPI of Elgamal prime p p: mpi // MPI of Elgamal group generator g >> g: mpi // MPI of Elgamal public key value y (= g**x mod p where x is secret) >> y: mpi - >> (PrivateKey::new( - *ver, - *alg, - PublicParams::Elgamal { + >> (PublicParams::Elgamal { p: p.to_vec(), g: g.to_vec(), y: y.to_vec() }, - EncryptedPrivateParams::new_plaintext(vec![], vec![]), - )) + EncryptedPrivateParams::new_plaintext(vec![], vec![])) )); -named_args!(dsa<'a>(alg: &'a PublicKeyAlgorithm, ver: &'a KeyVersion) , do_parse!( +named!(dsa<(PublicParams, EncryptedPrivateParams)>, do_parse!( p: mpi >> q: mpi >> g: mpi >> y: mpi - >> (PrivateKey::new( - *ver, - *alg, - PublicParams::DSA{ + >> (PublicParams::DSA { p: p.to_vec(), q: q.to_vec(), g: g.to_vec(), y: y.to_vec() }, - EncryptedPrivateParams::new_plaintext(vec![], vec![]) - )) + EncryptedPrivateParams::new_plaintext(vec![], vec![])) )); -named_args!(rsa<'a>(alg: &PublicKeyAlgorithm, ver: &'a KeyVersion) , do_parse!( +named!(rsa<(PublicParams, EncryptedPrivateParams)>, do_parse!( n: mpi >> e: mpi >> s2k_typ: be_u8 @@ -125,11 +109,7 @@ named_args!(rsa<'a>(alg: &PublicKeyAlgorithm, ver: &'a KeyVersion) , >> data_len: map!(rest_len, |r| r - checksum_len) >> data: take!(data_len) >> checksum: take!(checksum_len) - >> ({ - PrivateKey::new( - *ver, - *alg, - PublicParams::RSA { + >> (PublicParams::RSA { n: n.to_vec(), e: e.to_vec() }, @@ -142,35 +122,34 @@ named_args!(rsa<'a>(alg: &PublicKeyAlgorithm, ver: &'a KeyVersion) , string_to_key_params: enc_params.3.map(|p| p.to_vec()), string_to_key_id: s2k_typ, }) - }) )); -named_args!(key_from_fields<'a>(typ: PublicKeyAlgorithm, ver: &'a KeyVersion) , switch!( +named_args!(key_from_fields<'a>(typ: &'a PublicKeyAlgorithm) <(PublicParams, EncryptedPrivateParams)>, switch!( value!(&typ), &PublicKeyAlgorithm::RSA | &PublicKeyAlgorithm::RSAEncrypt | - &PublicKeyAlgorithm::RSASign => call!(rsa, &typ, ver) | - &PublicKeyAlgorithm::DSA => call!(dsa, &typ, ver) | - &PublicKeyAlgorithm::ECDSA => call!(ecdsa, &typ, ver) | - &PublicKeyAlgorithm::ECDH => call!(ecdh, &typ, ver) | + &PublicKeyAlgorithm::RSASign => call!(rsa) | + &PublicKeyAlgorithm::DSA => call!(dsa) | + &PublicKeyAlgorithm::ECDSA => call!(ecdsa) | + &PublicKeyAlgorithm::ECDH => call!(ecdh) | &PublicKeyAlgorithm::Elgamal | - &PublicKeyAlgorithm::ElgamalSign => call!(elgamal, &typ, ver) + &PublicKeyAlgorithm::ElgamalSign => call!(elgamal) // &PublicKeyAlgorithm::DiffieHellman => )); named_args!(new_private_key_parser<'a>(key_ver: &'a KeyVersion) , do_parse!( - _key_time: be_u32 - >> alg: map_opt!(be_u8, |v| PublicKeyAlgorithm::from_u8(v)) - >> key: call!(key_from_fields, alg, key_ver) - >> (key) + created_at: be_u32 + >> alg: map_opt!(be_u8, |v| PublicKeyAlgorithm::from_u8(v)) + >> params: call!(key_from_fields, &alg) + >> (PrivateKey::new(*key_ver, alg, created_at, None, params.0, params.1)) )); named_args!(old_private_key_parser<'a>(key_ver: &'a KeyVersion) , do_parse!( - _key_time: be_u32 - >> _exp: be_u16 - >> alg: map_opt!(be_u8, PublicKeyAlgorithm::from_u8) - >> key: call!(key_from_fields, alg, key_ver) - >> (key) + created_at: be_u32 + >> exp: be_u16 + >> alg: map_opt!(be_u8, PublicKeyAlgorithm::from_u8) + >> params: call!(key_from_fields, &alg) + >> (PrivateKey::new(*key_ver, alg, created_at, Some(exp), params.0, params.1)) )); /// Parse a private key packet (Tag 5) diff --git a/src/packet/tags/pubkey.rs b/src/packet/tags/pubkey.rs index 9b676d25..f3e50e58 100644 --- a/src/packet/tags/pubkey.rs +++ b/src/packet/tags/pubkey.rs @@ -8,18 +8,18 @@ use composed; use util::mpi; // Ref: https://tools.ietf.org/html/rfc6637#section-9 -named_args!(ecdsa<'a>(alg: &'a PublicKeyAlgorithm, ver: &'a KeyVersion) , do_parse!( +named!(ecdsa, do_parse!( // a one-octet size of the following field len: be_u8 // octets representing a curve OID >> curve: map_opt!(take!(len), ecc_curve_from_oid) // MPI of an EC point representing a public key >> p: mpi - >> (PublicKey::new(*ver, *alg, PublicParams::ECDSA{ curve, p: p.to_vec()})) + >> (PublicParams::ECDSA{ curve, p: p.to_vec()}) )); // Ref: https://tools.ietf.org/html/rfc6637#section-9 -named_args!(ecdh<'a>(alg: &'a PublicKeyAlgorithm, ver: &'a KeyVersion) , do_parse!( +named!(ecdh, do_parse!( // a one-octet size of the following field len: be_u8 // octets representing a curve OID @@ -35,59 +35,60 @@ named_args!(ecdh<'a>(alg: &'a PublicKeyAlgorithm, ver: &'a KeyVersion) > alg_sym: take!(1) - >> (PublicKey::new(*ver, *alg, PublicParams::ECDH{curve, p: p.to_vec(), hash: hash[0], alg_sym: alg_sym[0]})) + >> (PublicParams::ECDH{curve, p: p.to_vec(), hash: hash[0], alg_sym: alg_sym[0]}) )); -named_args!(elgamal<'a>(alg: &'a PublicKeyAlgorithm, ver: &'a KeyVersion) , do_parse!( +named!(elgamal, do_parse!( // MPI of Elgamal prime p p: mpi // MPI of Elgamal group generator g >> g: mpi // MPI of Elgamal public key value y (= g**x mod p where x is secret) >> y: mpi - >> (PublicKey::new(*ver, *alg, PublicParams::Elgamal{p: p.to_vec(), g: g.to_vec(), y: y.to_vec()})) + >> (PublicParams::Elgamal{p: p.to_vec(), g: g.to_vec(), y: y.to_vec()}) )); -named_args!(dsa<'a>(alg: &'a PublicKeyAlgorithm, ver: &'a KeyVersion) , do_parse!( +named!(dsa, do_parse!( p: mpi >> q: mpi >> g: mpi >> y: mpi - >> (PublicKey::new(*ver, *alg, PublicParams::DSA{p: p.to_vec(), q: q.to_vec(), g: g.to_vec(), y: y.to_vec()})) + >> (PublicParams::DSA{p: p.to_vec(), q: q.to_vec(), g: g.to_vec(), y: y.to_vec()}) )); -named_args!(rsa<'a>(alg: &PublicKeyAlgorithm, ver: &'a KeyVersion) , do_parse!( +named!(rsa, do_parse!( n: mpi >> e: mpi - >> (PublicKey::new(*ver, *alg, PublicParams::RSA{n: n.to_vec(), e: e.to_vec()})) + >> (PublicParams::RSA{n: n.to_vec(), e: e.to_vec()}) )); -named_args!(key_from_fields<'a>(typ: PublicKeyAlgorithm, ver: &'a KeyVersion) , switch!( - value!(&typ), + +named_args!(key_from_fields<'a>(typ: &PublicKeyAlgorithm) , switch!( + value!(typ), &PublicKeyAlgorithm::RSA | &PublicKeyAlgorithm::RSAEncrypt | - &PublicKeyAlgorithm::RSASign => call!(rsa, &typ, ver) | - &PublicKeyAlgorithm::DSA => call!(dsa, &typ, ver) | - &PublicKeyAlgorithm::ECDSA => call!(ecdsa, &typ, ver) | - &PublicKeyAlgorithm::ECDH => call!(ecdh, &typ, ver) | + &PublicKeyAlgorithm::RSASign => call!(rsa) | + &PublicKeyAlgorithm::DSA => call!(dsa) | + &PublicKeyAlgorithm::ECDSA => call!(ecdsa) | + &PublicKeyAlgorithm::ECDH => call!(ecdh) | &PublicKeyAlgorithm::Elgamal | - &PublicKeyAlgorithm::ElgamalSign => call!(elgamal, &typ, ver) + &PublicKeyAlgorithm::ElgamalSign => call!(elgamal) // &PublicKeyAlgorithm::DiffieHellman => )); named_args!(new_public_key_parser<'a>(key_ver: &'a KeyVersion) , do_parse!( - _key_time: be_u32 - >> alg: map_opt!(be_u8, |v| PublicKeyAlgorithm::from_u8(v)) - >> key: call!(key_from_fields, alg, key_ver) - >> (key) + created_at: be_u32 + >> alg: map_opt!(be_u8, |v| PublicKeyAlgorithm::from_u8(v)) + >> params: call!(key_from_fields, &alg) + >> (PublicKey::new(*key_ver, alg, created_at, None, params)) )); named_args!(old_public_key_parser<'a>(key_ver: &'a KeyVersion) , do_parse!( - _key_time: be_u32 - >> _exp: be_u16 - >> alg: map_opt!(be_u8, PublicKeyAlgorithm::from_u8) - >> key: call!(key_from_fields, alg, key_ver) - >> (key) + created_at: be_u32 + >> exp: be_u16 + >> alg: map_opt!(be_u8, PublicKeyAlgorithm::from_u8) + >> params: call!(key_from_fields, &alg) + >> (PublicKey::new(*key_ver, alg, created_at, Some(exp), params)) )); /// Parse a public key packet (Tag 6) diff --git a/src/packet/tags/sig.rs b/src/packet/tags/sig.rs index 94ca079d..1d519f85 100644 --- a/src/packet/tags/sig.rs +++ b/src/packet/tags/sig.rs @@ -269,7 +269,7 @@ named!(subpackets(&[u8]) -> Vec, >> (p) )))); -fn unknown_sig<'a>(body: &'a [u8], typ: &PublicKeyAlgorithm) -> IResult<&'a [u8], Vec> { +fn unknown_sig<'a>(body: &'a [u8], typ: PublicKeyAlgorithm) -> IResult<&'a [u8], Vec> { println!("unknown signature type {:?}", typ); Ok((&b""[..], body.to_vec())) } @@ -287,7 +287,7 @@ named_args!(actual_signature<'a>(typ: &PublicKeyAlgorithm) <&'a [u8], Vec>, acc }) | // TODO: check which other algorithms need handling - _ => call!(unknown_sig, typ) + _ => call!(unknown_sig, *typ) )); /// Parse a v2 signature packet diff --git a/src/packet/types/key.rs b/src/packet/types/key.rs index 4a6d72b8..d4bbfeb5 100644 --- a/src/packet/types/key.rs +++ b/src/packet/types/key.rs @@ -8,6 +8,8 @@ use packet::tags::privkey::rsa_private_params; pub struct PrivateKey { version: KeyVersion, algorithm: PublicKeyAlgorithm, + created_at: u32, + expiration: Option, public_params: PublicParams, private_params: EncryptedPrivateParams, } @@ -17,6 +19,8 @@ pub struct PrivateKey { pub struct PublicKey { version: KeyVersion, algorithm: PublicKeyAlgorithm, + created_at: u32, + expiration: Option, public_params: PublicParams, } @@ -116,11 +120,15 @@ impl PublicKey { pub fn new( version: KeyVersion, algorithm: PublicKeyAlgorithm, + created_at: u32, + expiration: Option, public_params: PublicParams, ) -> PublicKey { PublicKey { version, algorithm, + created_at, + expiration, public_params, } } @@ -130,12 +138,16 @@ impl PrivateKey { pub fn new( version: KeyVersion, algorithm: PublicKeyAlgorithm, + created_at: u32, + expiration: Option, public_params: PublicParams, private_params: EncryptedPrivateParams, ) -> PrivateKey { PrivateKey { version, algorithm, + created_at, + expiration, public_params, private_params, } @@ -229,6 +241,18 @@ macro_rules! key { pub fn algorithm(&self) -> &PublicKeyAlgorithm { &self.algorithm } + + pub fn created_at(&self) -> u32 { + self.created_at + } + + pub fn expiration(&self) -> Option { + self.expiration + } + + pub fn public_params(&self) -> &PublicParams { + &self.public_params + } } }; }