//! Autocrypt.
//!
//! This module deals with Autocrypt encoded (see the [Autocrypt Spec]).
//!
//! [Autocrypt Spec]: https://autocrypt.org/level1.html#openpgp-based-key-data
//!
//! # Scope
//!
//! This implements encoding and decoding of Autocrypt headers. Note:
//! Autocrypt is more than just headers; it requires tight integration
//! with the MUA.
extern crate base64;
use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::path::Path;
use std::fs::File;
use std::str;
use armor;
use Error;
use Result;
use Packet;
use packet::SKESK;
use TPK;
use TSK;
use parse::{
Parse,
PacketParserResult, PacketParser,
};
use serialize::Serialize;
use serialize::stream::{
Message, LiteralWriter, Encryptor, EncryptionMode,
};
use constants::DataFormat;
use crypto::Password;
/// Version of Autocrypt to use. `Autocrypt::default()` always returns the
/// latest version.
pub enum Autocrypt {
/// Autocrypt <= 1.0.1
V1,
}
impl Default for Autocrypt {
fn default() -> Self { Autocrypt::V1 }
}
/// An autocrypt header attribute.
#[derive(Debug, PartialEq)]
pub struct Attribute {
/// Whether the attribute is critical.
pub critical: bool,
/// The attribute's name.
///
/// If the attribute is not critical, the leading underscore has
/// been stripped.
pub key: String,
/// The attribute's value.
pub value: String,
}
/// Whether the data comes from an "Autocrypt" or "Autocrypt-Gossip"
/// header.
#[derive(Debug, PartialEq)]
pub enum AutocryptHeaderType {
/// An "Autocrypt" header.
Sender,
/// An "Autocrypt-Gossip" header.
Gossip,
}
/// A parsed Autocrypt header.
#[derive(Debug, PartialEq)]
pub struct AutocryptHeader {
/// Whether this is an "Autocrypt" or "Autocrypt-Gossip" header.
pub header_type: AutocryptHeaderType,
/// The parsed key data.
pub key: Option<TPK>,
/// All attributes.
pub attributes: Vec<Attribute>,
}
impl AutocryptHeader {
fn empty(header_type: AutocryptHeaderType) -> Self {
AutocryptHeader {
header_type: header_type,
key: None,
attributes: Vec::new(),
}
}
/// Looks up an attribute.
pub fn get(&self, key: &str) -> Option<&Attribute> {
for a in &self.attributes {
if a.key == key {
return Some(a);