Skip to content

Commit

Permalink
feat(key): handle expiration and creation time
Browse files Browse the repository at this point in the history
Former-commit-id: cdff6d7
  • Loading branch information
dignifiedquire committed Jul 5, 2018
1 parent 69e2e48 commit c314d09
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 89 deletions.
25 changes: 14 additions & 11 deletions src/composed/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
79 changes: 29 additions & 50 deletions src/packet/tags/privkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) <PrivateKey>, 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) <PrivateKey>, do_parse!(
named!(ecdh<(PublicParams, EncryptedPrivateParams)>, do_parse!(
// a one-octet size of the following field
len: be_u8
// octets representing a curve OID
Expand All @@ -43,57 +39,45 @@ named_args!(ecdh<'a>(alg: &'a PublicKeyAlgorithm, ver: &'a KeyVersion) <PrivateK
// a one-octet algorithm ID for the symmetric algorithm used to wrap
// the symmetric key used for the message encryption
>> 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) <PrivateKey>, 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) <PrivateKey>, 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) <PrivateKey>, do_parse!(
named!(rsa<(PublicParams, EncryptedPrivateParams)>, do_parse!(
n: mpi
>> e: mpi
>> s2k_typ: be_u8
Expand Down Expand Up @@ -125,11 +109,7 @@ named_args!(rsa<'a>(alg: &PublicKeyAlgorithm, ver: &'a KeyVersion) <PrivateKey>,
>> 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()
},
Expand All @@ -142,35 +122,34 @@ named_args!(rsa<'a>(alg: &PublicKeyAlgorithm, ver: &'a KeyVersion) <PrivateKey>,
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) <PrivateKey>, 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) <PrivateKey>, 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) <PrivateKey>, 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)
Expand Down
53 changes: 27 additions & 26 deletions src/packet/tags/pubkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) <PublicKey>, do_parse!(
named!(ecdsa<PublicParams>, 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) <PublicKey>, do_parse!(
named!(ecdh<PublicParams>, do_parse!(
// a one-octet size of the following field
len: be_u8
// octets representing a curve OID
Expand All @@ -35,59 +35,60 @@ named_args!(ecdh<'a>(alg: &'a PublicKeyAlgorithm, ver: &'a KeyVersion) <PublicKe
// a one-octet algorithm ID for the symmetric algorithm used to wrap
// the symmetric key used for the message encryption
>> 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) <PublicKey>, do_parse!(
named!(elgamal<PublicParams>, 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) <PublicKey>, do_parse!(
named!(dsa<PublicParams>, 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) <PublicKey>, do_parse!(
named!(rsa<PublicParams>, 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) <PublicKey>, switch!(
value!(&typ),

named_args!(key_from_fields<'a>(typ: &PublicKeyAlgorithm) <PublicParams>, 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) <PublicKey>, 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) <PublicKey>, 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)
Expand Down
4 changes: 2 additions & 2 deletions src/packet/tags/sig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ named!(subpackets(&[u8]) -> Vec<Subpacket>,
>> (p)
))));

fn unknown_sig<'a>(body: &'a [u8], typ: &PublicKeyAlgorithm) -> IResult<&'a [u8], Vec<u8>> {
fn unknown_sig<'a>(body: &'a [u8], typ: PublicKeyAlgorithm) -> IResult<&'a [u8], Vec<u8>> {
println!("unknown signature type {:?}", typ);
Ok((&b""[..], body.to_vec()))
}
Expand All @@ -287,7 +287,7 @@ named_args!(actual_signature<'a>(typ: &PublicKeyAlgorithm) <&'a [u8], Vec<u8>>,
acc
}) |
// TODO: check which other algorithms need handling
_ => call!(unknown_sig, typ)
_ => call!(unknown_sig, *typ)
));

/// Parse a v2 signature packet
Expand Down
24 changes: 24 additions & 0 deletions src/packet/types/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use packet::tags::privkey::rsa_private_params;
pub struct PrivateKey {
version: KeyVersion,
algorithm: PublicKeyAlgorithm,
created_at: u32,
expiration: Option<u16>,
public_params: PublicParams,
private_params: EncryptedPrivateParams,
}
Expand All @@ -17,6 +19,8 @@ pub struct PrivateKey {
pub struct PublicKey {
version: KeyVersion,
algorithm: PublicKeyAlgorithm,
created_at: u32,
expiration: Option<u16>,
public_params: PublicParams,
}

Expand Down Expand Up @@ -116,11 +120,15 @@ impl PublicKey {
pub fn new(
version: KeyVersion,
algorithm: PublicKeyAlgorithm,
created_at: u32,
expiration: Option<u16>,
public_params: PublicParams,
) -> PublicKey {
PublicKey {
version,
algorithm,
created_at,
expiration,
public_params,
}
}
Expand All @@ -130,12 +138,16 @@ impl PrivateKey {
pub fn new(
version: KeyVersion,
algorithm: PublicKeyAlgorithm,
created_at: u32,
expiration: Option<u16>,
public_params: PublicParams,
private_params: EncryptedPrivateParams,
) -> PrivateKey {
PrivateKey {
version,
algorithm,
created_at,
expiration,
public_params,
private_params,
}
Expand Down Expand Up @@ -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<u16> {
self.expiration
}

pub fn public_params(&self) -> &PublicParams {
&self.public_params
}
}
};
}
Expand Down

0 comments on commit c314d09

Please sign in to comment.