summaryrefslogtreecommitdiffstats
path: root/openpgp/examples/generate-encrypt-decrypt.rs
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2018-12-07 12:02:01 +0100
committerJustus Winter <justus@sequoia-pgp.org>2018-12-07 12:02:42 +0100
commit75ac3d4e5ba2a84b2550aa0d3a3e04c13d672465 (patch)
tree897d3ec665329e2c7eb2774f3f75d06a032ebb63 /openpgp/examples/generate-encrypt-decrypt.rs
parent22fe5f5fa08b7d98a05a9394320d7984083cd62f (diff)
openpgp: Add new example.
Diffstat (limited to 'openpgp/examples/generate-encrypt-decrypt.rs')
-rw-r--r--openpgp/examples/generate-encrypt-decrypt.rs127
1 files changed, 127 insertions, 0 deletions
diff --git a/openpgp/examples/generate-encrypt-decrypt.rs b/openpgp/examples/generate-encrypt-decrypt.rs
new file mode 100644
index 00000000..64b6cfab
--- /dev/null
+++ b/openpgp/examples/generate-encrypt-decrypt.rs
@@ -0,0 +1,127 @@
+/// Generates a key, then encrypts and decrypts a message.
+
+use std::io::{self, Write};
+
+extern crate sequoia_openpgp as openpgp;
+use openpgp::serialize::stream::*;
+use openpgp::parse::stream::*;
+
+const MESSAGE: &'static str = "дружба";
+
+fn main() {
+ // Generate a key.
+ let key = generate().unwrap();
+
+ // Encrypt the message.
+ let mut ciphertext = Vec::new();
+ encrypt(&mut ciphertext, MESSAGE, &key).unwrap();
+
+ // Decrypt the message.
+ let mut plaintext = Vec::new();
+ decrypt(&mut plaintext, &ciphertext, &key).unwrap();
+
+ assert_eq!(MESSAGE.as_bytes(), &plaintext[..]);
+}
+
+/// Generates an encryption-capable key.
+fn generate() -> openpgp::Result<openpgp::TPK> {
+ let (tpk, _revocation) = openpgp::tpk::TPKBuilder::default()
+ .add_userid("someone@example.org")
+ .add_encryption_subkey()
+ .generate()?;
+
+ // Save the revocation certificate somewhere.
+
+ Ok(tpk)
+}
+
+/// Encrypts the given message.
+fn encrypt(sink: &mut Write, plaintext: &str, recipient: &openpgp::TPK)
+ -> openpgp::Result<()> {
+ // Start streaming an OpenPGP message.
+ let message = Message::new(sink);
+
+ // We want to encrypt a literal data packet.
+ let encryptor = Encryptor::new(message,
+ &[], // No symmetric encryption.
+ &[recipient],
+ EncryptionMode::ForTransport)?;
+
+ // Emit a literal data packet.
+ let mut literal_writer = LiteralWriter::new(
+ encryptor, openpgp::constants::DataFormat::Binary, None, None)?;
+
+ // Encrypt the data.
+ literal_writer.write_all(plaintext.as_bytes())?;
+
+ // Finalize the OpenPGP message to make sure that all data is
+ // written.
+ literal_writer.finalize()?;
+
+ Ok(())
+}
+
+/// Decrypts the given message.
+fn decrypt(sink: &mut Write, ciphertext: &[u8], recipient: &openpgp::TPK)
+ -> openpgp::Result<()> {
+ // Make a helper that that feeds the recipient's secret key to the
+ // decryptor.
+ let helper = Helper {
+ secret: recipient,
+ };
+
+ // Now, create a decryptor with a helper using the given TPKs.
+ let mut decryptor = Decryptor::from_bytes(ciphertext, helper)?;
+
+ // Decrypt the data.
+ io::copy(&mut decryptor, sink)?;
+
+ Ok(())
+}
+
+struct Helper<'a> {
+ secret: &'a openpgp::TPK,
+}
+
+impl<'a> VerificationHelper for Helper<'a> {
+ fn get_public_keys(&mut self, _ids: &[openpgp::KeyID])
+ -> openpgp::Result<Vec<openpgp::TPK>> {
+ // Return public keys for signature verification here.
+ Ok(Vec::new())
+ }
+
+ fn check(&mut self, _sigs: Vec<Vec<VerificationResult>>)
+ -> openpgp::Result<()> {
+ // Implement your signature verification policy here.
+ Ok(())
+ }
+}
+
+impl<'a> DecryptionHelper for Helper<'a> {
+ fn get_secret(&mut self,
+ _pkesks: &[&openpgp::packet::PKESK],
+ _skesks: &[&openpgp::packet::SKESK])
+ -> openpgp::Result<Option<Secret>>
+ {
+ // The encryption key is the first and only subkey.
+ let key = self.secret.subkeys().nth(0)
+ .map(|binding| binding.subkey().clone())
+ .unwrap();
+
+ // The secret key is not encrypted.
+ let secret =
+ if let Some(openpgp::SecretKey::Unencrypted {
+ ref mpis,
+ }) = key.secret() {
+ mpis.clone()
+ } else {
+ unreachable!()
+ };
+
+ Ok(Some(Secret::Asymmetric {
+ identity: self.secret.fingerprint(),
+ key: key,
+ secret: secret,
+ }))
+ }
+}