diff options
author | Neal H. Walfield <neal@pep.foundation> | 2020-01-31 14:20:53 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2020-01-31 15:59:16 +0100 |
commit | a464ce819ccd1fa07ff8c6d0be74cff5eec5cf34 (patch) | |
tree | 31ed9d18b9c7802a93b4e4c8e6e85d1121b201d8 /guide | |
parent | b9b6533bd5394cd5cdb6b91b5c5ca7a02e3ea199 (diff) |
openpgp: Add a policy object.
- Change all functions that need to evaluate the validity of a
signature (either directly or indirectly to take a policy object.
- Use the policy object to allow the user to place additional
constraints on a signature's validity.
- This addresses the first half of #274 (it introduces the policy
object, but does not yet implement any policy).
Diffstat (limited to 'guide')
-rw-r--r-- | guide/src/chapter_01.md | 98 | ||||
-rw-r--r-- | guide/src/chapter_02.md | 88 |
2 files changed, 125 insertions, 61 deletions
diff --git a/guide/src/chapter_01.md b/guide/src/chapter_01.md index 16020b6b..629515eb 100644 --- a/guide/src/chapter_01.md +++ b/guide/src/chapter_01.md @@ -17,20 +17,24 @@ extern crate sequoia_openpgp as openpgp; use openpgp::serialize::stream::*; use openpgp::packet::prelude::*; use openpgp::parse::stream::*; +use openpgp::policy::Policy; +use openpgp::policy::StandardPolicy as P; const MESSAGE: &'static str = "дружба"; fn main() { + let p = &P::new(); + // Generate a key. let key = generate().unwrap(); // Sign the message. let mut signed_message = Vec::new(); - sign(&mut signed_message, MESSAGE, &key).unwrap(); + sign(p, &mut signed_message, MESSAGE, &key).unwrap(); // Verify the message. let mut plaintext = Vec::new(); - verify(&mut plaintext, &signed_message, &key).unwrap(); + verify(p, &mut plaintext, &signed_message, &key).unwrap(); assert_eq!(MESSAGE.as_bytes(), &plaintext[..]); } @@ -48,11 +52,14 @@ fn main() { # } # # /// Signs the given message. -# fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) -# -> openpgp::Result<()> { +# fn sign(policy: &dyn Policy, +# sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) +# -> openpgp::Result<()> +# { # // Get the keypair to do the signing from the Cert. -# let keypair = tsk.keys().policy(None).alive().revoked(false).for_signing().nth(0).unwrap(). -# key().clone().mark_parts_secret().unwrap().into_keypair()?; +# let keypair = tsk.keys().set_policy(policy, None) +# .alive().revoked(false).for_signing().nth(0).unwrap() +# .key().clone().mark_parts_secret().unwrap().into_keypair()?; # # // Start streaming an OpenPGP message. # let message = Message::new(sink); @@ -74,7 +81,8 @@ fn main() { # } # # /// Verifies the given message. -# fn verify(sink: &mut Write, signed_message: &[u8], sender: &openpgp::Cert) +# fn verify(policy: &dyn Policy, +# sink: &mut Write, signed_message: &[u8], sender: &openpgp::Cert) # -> openpgp::Result<()> { # // Make a helper that that feeds the sender's public key to the # // verifier. @@ -83,7 +91,7 @@ fn main() { # }; # # // Now, create a verifier with a helper using the given Certs. -# let mut verifier = Verifier::from_bytes(signed_message, helper, None)?; +# let mut verifier = Verifier::from_bytes(policy, signed_message, helper, None)?; # # // Verify the data. # io::copy(&mut verifier, sink)?; @@ -161,22 +169,26 @@ create it: # extern crate failure; # extern crate sequoia_openpgp as openpgp; # use openpgp::serialize::stream::*; -# use openpgp::parse::stream::*; # use openpgp::packet::prelude::*; +# use openpgp::parse::stream::*; +# use openpgp::policy::Policy; +# use openpgp::policy::StandardPolicy as P; # # const MESSAGE: &'static str = "дружба"; # # fn main() { +# let p = &P::new(); +# # // Generate a key. # let key = generate().unwrap(); # # // Sign the message. # let mut signed_message = Vec::new(); -# sign(&mut signed_message, MESSAGE, &key).unwrap(); +# sign(p, &mut signed_message, MESSAGE, &key).unwrap(); # # // Verify the message. # let mut plaintext = Vec::new(); -# verify(&mut plaintext, &signed_message, &key).unwrap(); +# verify(p, &mut plaintext, &signed_message, &key).unwrap(); # # assert_eq!(MESSAGE.as_bytes(), &plaintext[..]); # } @@ -194,11 +206,14 @@ fn generate() -> openpgp::Result<openpgp::Cert> { } # # /// Signs the given message. -# fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) -# -> openpgp::Result<()> { +# fn sign(policy: &dyn Policy, +# sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) +# -> openpgp::Result<()> +# { # // Get the keypair to do the signing from the Cert. -# let keypair = tsk.keys().policy(None).alive().revoked(false).for_signing().nth(0).unwrap(). -# key().clone().mark_parts_secret().unwrap().into_keypair()?; +# let keypair = tsk.keys().set_policy(policy, None) +# .alive().revoked(false).for_signing().nth(0).unwrap() +# .key().clone().mark_parts_secret().unwrap().into_keypair()?; # # // Start streaming an OpenPGP message. # let message = Message::new(sink); @@ -220,7 +235,8 @@ fn generate() -> openpgp::Result<openpgp::Cert> { # } # # /// Verifies the given message. -# fn verify(sink: &mut Write, signed_message: &[u8], sender: &openpgp::Cert) +# fn verify(policy: &dyn Policy, +# sink: &mut Write, signed_message: &[u8], sender: &openpgp::Cert) # -> openpgp::Result<()> { # // Make a helper that that feeds the sender's public key to the # // verifier. @@ -229,7 +245,7 @@ fn generate() -> openpgp::Result<openpgp::Cert> { # }; # # // Now, create a verifier with a helper using the given Certs. -# let mut verifier = Verifier::from_bytes(signed_message, helper, None)?; +# let mut verifier = Verifier::from_bytes(policy, signed_message, helper, None)?; # # // Verify the data. # io::copy(&mut verifier, sink)?; @@ -309,20 +325,24 @@ implements [`io::Write`], and we simply write the plaintext to it. # use openpgp::serialize::stream::*; # use openpgp::packet::prelude::*; # use openpgp::parse::stream::*; +# use openpgp::policy::Policy; +# use openpgp::policy::StandardPolicy as P; # # const MESSAGE: &'static str = "дружба"; # # fn main() { +# let p = &P::new(); +# # // Generate a key. # let key = generate().unwrap(); # # // Sign the message. # let mut signed_message = Vec::new(); -# sign(&mut signed_message, MESSAGE, &key).unwrap(); +# sign(p, &mut signed_message, MESSAGE, &key).unwrap(); # # // Verify the message. # let mut plaintext = Vec::new(); -# verify(&mut plaintext, &signed_message, &key).unwrap(); +# verify(p, &mut plaintext, &signed_message, &key).unwrap(); # # assert_eq!(MESSAGE.as_bytes(), &plaintext[..]); # } @@ -340,11 +360,14 @@ implements [`io::Write`], and we simply write the plaintext to it. # } # /// Signs the given message. -fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) - -> openpgp::Result<()> { +fn sign(policy: &dyn Policy, + sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) + -> openpgp::Result<()> +{ // Get the keypair to do the signing from the Cert. - let keypair = tsk.keys().policy(None).alive().revoked(false).for_signing().nth(0).unwrap(). - key().clone().mark_parts_secret().unwrap().into_keypair()?; + let keypair = tsk.keys().set_policy(policy, None) + .alive().revoked(false).for_signing().nth(0).unwrap() + .key().clone().mark_parts_secret().unwrap().into_keypair()?; // Start streaming an OpenPGP message. let message = Message::new(sink); @@ -366,7 +389,8 @@ fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) } # # /// Verifies the given message. -# fn verify(sink: &mut Write, signed_message: &[u8], sender: &openpgp::Cert) +# fn verify(policy: &dyn Policy, +# sink: &mut Write, signed_message: &[u8], sender: &openpgp::Cert) # -> openpgp::Result<()> { # // Make a helper that that feeds the sender's public key to the # // verifier. @@ -375,7 +399,7 @@ fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) # }; # # // Now, create a verifier with a helper using the given Certs. -# let mut verifier = Verifier::from_bytes(signed_message, helper, None)?; +# let mut verifier = Verifier::from_bytes(policy, signed_message, helper, None)?; # # // Verify the data. # io::copy(&mut verifier, sink)?; @@ -466,20 +490,24 @@ Verified data can be read from this using [`io::Read`]. # use openpgp::serialize::stream::*; # use openpgp::packet::prelude::*; # use openpgp::parse::stream::*; +# use openpgp::policy::Policy; +# use openpgp::policy::StandardPolicy as P; # # const MESSAGE: &'static str = "дружба"; # # fn main() { +# let p = &P::new(); +# # // Generate a key. # let key = generate().unwrap(); # # // Sign the message. # let mut signed_message = Vec::new(); -# sign(&mut signed_message, MESSAGE, &key).unwrap(); +# sign(p, &mut signed_message, MESSAGE, &key).unwrap(); # # // Verify the message. # let mut plaintext = Vec::new(); -# verify(&mut plaintext, &signed_message, &key).unwrap(); +# verify(p, &mut plaintext, &signed_message, &key).unwrap(); # # assert_eq!(MESSAGE.as_bytes(), &plaintext[..]); # } @@ -497,11 +525,14 @@ Verified data can be read from this using [`io::Read`]. # } # # /// Signs the given message. -# fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) -# -> openpgp::Result<()> { +# fn sign(policy: &dyn Policy, +# sink: &mut Write, plaintext: &str, tsk: &openpgp::Cert) +# -> openpgp::Result<()> +# { # // Get the keypair to do the signing from the Cert. -# let keypair = tsk.keys().policy(None).alive().revoked(false).for_signing().nth(0).unwrap(). -# key().clone().mark_parts_secret().unwrap().into_keypair()?; +# let keypair = tsk.keys().set_policy(policy, None) +# .alive().revoked(false).for_signing().nth(0).unwrap() +# .key().clone().mark_parts_secret().unwrap().into_keypair()?; # # // Start streaming an OpenPGP message. # let message = Message::new(sink); @@ -523,7 +554,8 @@ Verified data can be read from this using [`io::Read`]. # } # /// Verifies the given message. -fn verify(sink: &mut Write, signed_message: &[u8], sender: &openpgp::Cert) +fn verify(policy: &dyn Policy, + sink: &mut Write, signed_message: &[u8], sender: &openpgp::Cert) -> openpgp::Result<()> { // Make a helper that that feeds the sender's public key to the // verifier. @@ -532,7 +564,7 @@ fn verify(sink: &mut Write, signed_message: &[u8], sender: &openpgp::Cert) }; // Now, create a verifier with a helper using the given Certs. - let mut verifier = Verifier::from_bytes(signed_message, helper, None)?; + let mut verifier = Verifier::from_bytes(policy, signed_message, helper, None)?; // Verify the data. io::copy(&mut verifier, sink)?; diff --git a/guide/src/chapter_02.md b/guide/src/chapter_02.md index 697f93cf..6f18c59c 100644 --- a/guide/src/chapter_02.md +++ b/guide/src/chapter_02.md @@ -16,20 +16,24 @@ use openpgp::crypto::SessionKey; use openpgp::types::SymmetricAlgorithm; use openpgp::serialize::stream::*; use openpgp::parse::stream::*; +use openpgp::policy::Policy; +use openpgp::policy::StandardPolicy as P; const MESSAGE: &'static str = "дружба"; fn main() { + let p = &P::new(); + // Generate a key. let key = generate().unwrap(); // Encrypt the message. let mut ciphertext = Vec::new(); - encrypt(&mut ciphertext, MESSAGE, &key).unwrap(); + encrypt(p, &mut ciphertext, MESSAGE, &key).unwrap(); // Decrypt the message. let mut plaintext = Vec::new(); - decrypt(&mut plaintext, &ciphertext, &key).unwrap(); + decrypt(p, &mut plaintext, &ciphertext, &key).unwrap(); assert_eq!(MESSAGE.as_bytes(), &plaintext[..]); } @@ -47,11 +51,12 @@ fn main() { # } # # /// Encrypts the given message. -# fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::Cert) +# fn encrypt(policy: &dyn Policy, +# sink: &mut Write, plaintext: &str, recipient: &openpgp::Cert) # -> openpgp::Result<()> { # // Build a vector of recipients to hand to Encryptor. # let mut recipients = -# recipient.keys().policy(None).alive().revoked(false) +# recipient.keys().set_policy(policy, None).alive().revoked(false) # .for_transport_encryption() # .map(|ka| ka.key().into()) # .collect::<Vec<_>>(); @@ -81,16 +86,18 @@ fn main() { # } # # /// Decrypts the given message. -# fn decrypt(sink: &mut Write, ciphertext: &[u8], recipient: &openpgp::Cert) +# fn decrypt(policy: &dyn Policy, +# sink: &mut Write, ciphertext: &[u8], recipient: &openpgp::Cert) # -> openpgp::Result<()> { # // Make a helper that that feeds the recipient's secret key to the # // decryptor. # let helper = Helper { +# policy: policy, # secret: recipient, # }; # # // Now, create a decryptor with a helper using the given Certs. -# let mut decryptor = Decryptor::from_bytes(ciphertext, helper, None)?; +# let mut decryptor = Decryptor::from_bytes(policy, ciphertext, helper, None)?; # # // Decrypt the data. # io::copy(&mut decryptor, sink)?; @@ -99,6 +106,7 @@ fn main() { # } # # struct Helper<'a> { +# policy: &'a dyn Policy, # secret: &'a openpgp::Cert, # } # @@ -125,7 +133,7 @@ fn main() { # where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> # { # // The encryption key is the first and only subkey. -# let key = self.secret.keys().policy(None) +# let key = self.secret.keys().set_policy(self.policy, None) # .for_transport_encryption().nth(0).unwrap().key().clone(); # # // The secret key is not encrypted. @@ -156,20 +164,24 @@ create it: # use openpgp::types::SymmetricAlgorithm; # use openpgp::serialize::stream::*; # use openpgp::parse::stream::*; +# use openpgp::policy::Policy; +# use openpgp::policy::StandardPolicy as P; # # const MESSAGE: &'static str = "дружба"; # # fn main() { +# let p = &P::new(); +# # // Generate a key. # let key = generate().unwrap(); # # // Encrypt the message. # let mut ciphertext = Vec::new(); -# encrypt(&mut ciphertext, MESSAGE, &key).unwrap(); +# encrypt(p, &mut ciphertext, MESSAGE, &key).unwrap(); # # // Decrypt the message. # let mut plaintext = Vec::new(); -# decrypt(&mut plaintext, &ciphertext, &key).unwrap(); +# decrypt(p, &mut plaintext, &ciphertext, &key).unwrap(); # # assert_eq!(MESSAGE.as_bytes(), &plaintext[..]); # } @@ -187,11 +199,12 @@ fn generate() -> openpgp::Result<openpgp::Cert> { } # # /// Encrypts the given message. -# fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::Cert) +# fn encrypt(policy: &dyn Policy, +# sink: &mut Write, plaintext: &str, recipient: &openpgp::Cert) # -> openpgp::Result<()> { # // Build a vector of recipients to hand to Encryptor. # let mut recipients = -# recipient.keys().policy(None).alive().revoked(false) +# recipient.keys().set_policy(policy, None).alive().revoked(false) # .for_transport_encryption() # .map(|ka| ka.key().into()) # .collect::<Vec<_>>(); @@ -221,16 +234,18 @@ fn generate() -> openpgp::Result<openpgp::Cert> { # } # # /// Decrypts the given message. -# fn decrypt(sink: &mut Write, ciphertext: &[u8], recipient: &openpgp::Cert) +# fn decrypt(policy: &dyn Policy, +# sink: &mut Write, ciphertext: &[u8], recipient: &openpgp::Cert) # -> openpgp::Result<()> { # // Make a helper that that feeds the recipient's secret key to the # // decryptor. # let helper = Helper { +# policy: policy, # secret: recipient, # }; # # // Now, create a decryptor with a helper using the given Certs. -# let mut decryptor = Decryptor::from_bytes(ciphertext, helper, None)?; +# let mut decryptor = Decryptor::from_bytes(policy, ciphertext, helper, None)?; # # // Decrypt the data. # io::copy(&mut decryptor, sink)?; @@ -239,6 +254,7 @@ fn generate() -> openpgp::Result<openpgp::Cert> { # } # # struct Helper<'a> { +# policy: &'a dyn Policy, # secret: &'a openpgp::Cert, # } # @@ -265,7 +281,7 @@ fn generate() -> openpgp::Result<openpgp::Cert> { # where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> # { # // The encryption key is the first and only subkey. -# let key = self.secret.keys().policy(None) +# let key = self.secret.keys().set_policy(self.policy, None) # .for_transport_encryption().nth(0).unwrap().key().clone(); # # // The secret key is not encrypted. @@ -296,20 +312,24 @@ implements [`io::Write`], and we simply write the plaintext to it. # use openpgp::types::SymmetricAlgorithm; # use openpgp::serialize::stream::*; # use openpgp::parse::stream::*; +# use openpgp::policy::Policy; +# use openpgp::policy::StandardPolicy as P; # # const MESSAGE: &'static str = "дружба"; # # fn main() { +# let p = &P::new(); +# # // Generate a key. # let key = generate().unwrap(); # # // Encrypt the message. # let mut ciphertext = Vec::new(); -# encrypt(&mut ciphertext, MESSAGE, &key).unwrap(); +# encrypt(p, &mut ciphertext, MESSAGE, &key).unwrap(); # # // Decrypt the message. # let mut plaintext = Vec::new(); -# decrypt(&mut plaintext, &ciphertext, &key).unwrap(); +# decrypt(p, &mut plaintext, &ciphertext, &key).unwrap(); # # assert_eq!(MESSAGE.as_bytes(), &plaintext[..]); # } @@ -327,11 +347,12 @@ implements [`io::Write`], and we simply write the plaintext to it. # } # /// Encrypts the given message. -fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::Cert) +fn encrypt(policy: &dyn Policy, + sink: &mut Write, plaintext: &str, recipient: &openpgp::Cert) -> openpgp::Result<()> { // Build a vector of recipients to hand to Encryptor. let mut recipients = - recipient.keys().policy(None).alive().revoked(false) + recipient.keys().set_policy(policy, None).alive().revoked(false) .for_transport_encryption() .map(|ka| ka.key().into()) .collect::<Vec<_>>(); @@ -361,16 +382,18 @@ fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::Cert) } # # /// Decrypts the given message. -# fn decrypt(sink: &mut Write, ciphertext: &[u8], recipient: &openpgp::Cert) +# fn decrypt(policy: &dyn Policy, +# sink: &mut Write, ciphertext: &[u8], recipient: &openpgp::Cert) # -> openpgp::Result<()> { # // Make a helper that that feeds the recipient's secret key to the # // decryptor. # let helper = Helper { +# policy: policy, # secret: recipient, # }; # # // Now, create a decryptor with a helper using the given Certs. -# let mut decryptor = Decryptor::from_bytes(ciphertext, helper, None)?; +# let mut decryptor = Decryptor::from_bytes(policy, ciphertext, helper, None)?; # # // Decrypt the data. # io::copy(&mut decryptor, sink)?; @@ -379,6 +402,7 @@ fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::Cert) # } # # struct Helper<'a> { +# policy: &'a dyn Policy, # secret: &'a openpgp::Cert, # } # @@ -405,7 +429,7 @@ fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::Cert) # where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> # { # // The encryption key is the first and only subkey. -# let key = self.secret.keys().policy(None) +# let key = self.secret.keys().set_policy(self.policy, None) # .for_transport_encryption().nth(0).unwrap().key().clone(); # # // The secret key is not encrypted. @@ -450,20 +474,24 @@ Decrypted data can be read from this using [`io::Read`]. # use openpgp::types::SymmetricAlgorithm; # use openpgp::serialize::stream::*; # use openpgp::parse::stream::*; +# use openpgp::policy::Policy; +# use openpgp::policy::StandardPolicy as P; # # const MESSAGE: &'static str = "дружба"; # # fn main() { +# let p = &P::new(); +# # // Generate a key. # let key = generate().unwrap(); # # // Encrypt the message. # let mut ciphertext = Vec::new(); -# encrypt(&mut ciphertext, MESSAGE, &key).unwrap(); +# encrypt(p, &mut ciphertext, MESSAGE, &key).unwrap(); # # // Decrypt the message. # let mut plaintext = Vec::new(); -# decrypt(&mut plaintext, &ciphertext, &key).unwrap(); +# decrypt(p, &mut plaintext, &ciphertext, &key).unwrap(); # # assert_eq!(MESSAGE.as_bytes(), &plaintext[..]); # } @@ -481,11 +509,12 @@ Decrypted data can be read from this using [`io::Read`]. # } # # /// Encrypts the given message. -# fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::Cert) +# fn encrypt(policy: &dyn Policy, +# sink: &mut Write, plaintext: &str, recipient: &openpgp::Cert) # -> openpgp::Result<()> { # // Build a vector of recipients to hand to Encryptor. # let mut recipients = -# recipient.keys().policy(None).alive().revoked(false) +# recipient.keys().set_policy(policy, None).alive().revoked(false) # .for_transport_encryption() # .map(|ka| ka.key().into()) # .collect::<Vec<_>>(); @@ -515,16 +544,18 @@ Decrypted data can be read from this using [`io::Read`]. # } # /// Decrypts the given message. -fn decrypt(sink: &mut Write, ciphertext: &[u8], recipient: &openpgp::Cert) +fn decrypt(policy: &dyn Policy, + sink: &mut Write, ciphertext: &[u8], recipient: &openpgp::Cert) -> openpgp::Result<()> { // Make a helper that that feeds the recipient's secret key to the // decryptor. let helper = Helper { + policy: policy, secret: recipient, }; // Now, create a decryptor with a helper using the given Certs. - let mut decryptor = Decryptor::from_bytes(ciphertext, helper, None)?; + let mut decryptor = Decryptor::from_bytes(policy, ciphertext, helper, None)?; // Decrypt the data. io::copy(&mut decryptor, sink)?; @@ -533,6 +564,7 @@ fn decrypt(sink: &mut Write, ciphertext: &[u8], recipient: &openpgp::Cert) } struct Helper<'a> { + policy: &'a dyn Policy, secret: &'a openpgp::Cert, } @@ -558,7 +590,7 @@ impl<'a> DecryptionHelper for Helper<'a> { -> openpgp::Result<Option<openpgp::Fingerprint>> where D: FnMut(SymmetricAlgorithm, &SessionKey) -> openpgp::Result<()> { - let key = self.secret.keys().policy(None) + let key = self.secret.keys().set_policy(self.policy, None) .for_transport_encryption().nth(0).unwrap().key().clone(); // The secret key is not encrypted. |