#![warn(missing_docs)]
extern crate lalrpop_util;
#[macro_use]
extern crate failure;
extern crate buffered_reader;
extern crate memsec;
extern crate nettle;
#[cfg(feature = "compression-deflate")]
extern crate flate2;
#[cfg(feature = "compression-bzip2")]
extern crate bzip2;
#[cfg(test)]
#[macro_use]
extern crate quickcheck;
#[cfg(not(test))]
extern crate quickcheck;
extern crate rand;
extern crate time;
#[macro_use]
mod macros;
#[allow(unused_macros)]
macro_rules! assert_match {
( $error: pat = $expr:expr, $fmt:expr, $($pargs:expr),* ) => {
let x = $expr;
if let $error = x {
} else {
let extra = format!($fmt, $($pargs),*);
panic!("Expected {}, got {:?}{}{}",
stringify!($error), x,
if $fmt.len() > 0 { ": " } else { "." }, extra);
}
};
( $error: pat = $expr: expr, $fmt:expr ) => {
assert_match!($error = $expr, $fmt, );
};
( $error: pat = $expr: expr ) => {
assert_match!($error = $expr, "");
};
}
#[macro_use]
pub mod armor;
pub mod autocrypt;
pub mod conversions;
pub mod crypto;
pub mod packet;
use packet::{BodyLength, Header, Container};
use packet::ctb::{CTB, CTBOld, CTBNew};
pub mod parse;
pub mod tpk;
pub mod serialize;
mod packet_pile;
pub mod message;
pub mod constants;
use constants::{
PublicKeyAlgorithm,
SymmetricAlgorithm,
HashAlgorithm,
SignatureType,
};
mod fingerprint;
mod keyid;
mod tsk;
pub use tsk::TSK;
#[cfg(test)]
use std::path::PathBuf;
#[cfg(test)]
fn path_to(artifact: &str) -> PathBuf {
[env!("CARGO_MANIFEST_DIR"), "tests", "data", "messages", artifact]
.iter().collect()
}
pub type Result<T> = ::std::result::Result<T, failure::Error>;
#[derive(Fail, Debug, Clone)]
pub enum Error {
#[fail(display = "Invalid argument: {}", _0)]
InvalidArgument(String),
#[fail(display = "Invalid operation: {}", _0)]
InvalidOperation(String),
#[fail(display = "Malformed packet: {}", _0)]
MalformedPacket(String),
#[fail(display = "Unsupported packet type. Tag: {}", _0)]
UnsupportedPacketType(packet::Tag),
#[fail(display = "Unsupported hash algorithm: {}", _0)]
UnsupportedHashAlgorithm(HashAlgorithm),
#[fail(display = "Unsupported public key algorithm: {}", _0)]
UnsupportedPublicKeyAlgorithm(PublicKeyAlgorithm),
#[fail(display = "Unsupported elliptic curve: {}", _0)]
UnsupportedEllipticCurve(constants::Curve),
#[fail(display = "Unsupported symmetric algorithm: {}", _0)]
UnsupportedSymmetricAlgorithm(SymmetricAlgorithm),
#[fail(display = "Unsupported AEAD algorithm: {}", _0)]
UnsupportedAEADAlgorithm(constants::AEADAlgorithm),
#[fail(display = "Unsupported signature type: {}", _0)]
UnsupportedSignatureType(SignatureType),
#[fail(display = "Invalid password")]
InvalidPassword,
#[fail(display = "Invalid session key: {}", _0)]
InvalidSessionKey(String),
#[fail(display = "Missing session key: {}", _0)]
MissingSessionKey(String),
#[fail(display = "Malformed MPI: {}", _0)]
MalformedMPI(String),
#[fail(display = "Bad signature: {}", _0)]
BadSignature(String),
#[fail(display = "Message has been manipulated")]
ManipulatedMessage,
#[fail(display = "Malformed Message: {}", _0)]
MalformedMessage(String),
#[fail(display = "Malformed TPK: {}", _0)]
MalformedTPK(String),
#[fail(display = "Unsupported TPK: {}", _0)]
UnsupportedTPK(String),
#[fail(display = "Index out of range")]
IndexOutOfRange,
}
#[derive(Debug)]
#[derive(PartialEq, Eq, Hash, Clone)]
pub enum Packet {
Unknown(packet::Unknown),
Signature(packet::Signature),
OnePassSig(packet::OnePassSig),
PublicKey(packet::Key),
PublicSubkey(packet::Key),
SecretKey(packet::Key),
SecretSubkey(packet::Key),
UserID(packet::UserID),
UserAttribute(packet::UserAttribute),
Literal(packet::Literal),
CompressedData(packet::CompressedData),
PKESK(packet::PKESK),
SKESK(packet::SKESK),
SEIP(packet::SEIP),
MDC(packet::MDC),
AED(packet::AED),
}
impl Packet {
pub fn tag(&self) -> packet::Tag {
use packet::Tag;
match self {
&Packet::Unknown(ref packet) => packet.tag(),
&Packet::Signature(_) => Tag::Signature,
&Packet::OnePassSig(_) => Tag::OnePassSig,
&Packet::PublicKey(_) => Tag::PublicKey,
&Packet::PublicSubkey(_) => Tag::PublicSubkey,
&Packet::SecretKey(_) => Tag::SecretKey,
&Packet::SecretSubkey(_) => Tag::SecretSubkey,
&Packet::UserID(_) => Tag::UserID,
&Packet::UserAttribute(_) => Tag::UserAttribute,
&Packet::Literal(_) => Tag::Literal,
&Packet::CompressedData(_) => Tag::CompressedData,
&Packet::PKESK(_) => Tag::PKESK,
&Packet::SKESK(_) => Tag::SKESK,
&Packet::SEIP(_) => Tag::SEIP,
&Packet::MDC(_) => Tag::MDC,
&Packet::AED(_) => Tag::AED,
}
}
pub fn kind(&self) -> Option<packet::Tag> {
use packet::Tag;
match self {
&Packet::Unknown(_) => None,
&Packet::Signature(_) => Some(Tag::Signature),
&Packet::OnePassSig(_) => Some(Tag::OnePassSig),
&Packet::PublicKey(_) => Some(Tag::PublicKey),
&Packet::PublicSubkey(_) => Some(Tag::PublicSubkey),
&Packet::SecretKey(_) => Some(Tag::SecretKey),
&Packet::SecretSubkey(_) => Some(Tag::SecretSubkey),
&Packet::UserID(_) => Some(Tag::UserID),
&Packet::UserAttribute(_) => Some(Tag::UserAttribute),
&Packet::Literal(_) => Some(Tag::Literal),
&Packet::CompressedData(_) => Some(Tag::CompressedData),
&Packet::PKESK(_) => Some(Tag::PKESK),
&Packet::SKESK(_) => Some(Tag::SKESK),
&Packet::SEIP(_) => Some(Tag::SEIP),
&Packet::MDC(_) => Some(Tag::MDC),
&Packet::AED(_) => Some(Tag::AED),
}
}
}
#[derive(PartialEq, Clone)]
pub struct PacketPile {
top_level: Container,
}
#[derive(Debug, Clone, PartialEq)]
pub struct TPK {
primary: packet::Key,
primary_selfsigs: Vec<packet::Signature>,
primary_certifications: Vec<packet::Signature>,
primary_self_revocations: Vec<packet::Signature>,
primary_other_revocations: Vec<packet::Signature>,
userids: Vec<tpk::UserIDBinding>,
user_attributes: Vec<tpk::UserAttributeBinding>,
subkeys: Vec<tpk::SubkeyBinding>,
unknowns: Vec<tpk::UnknownBinding>,
bad: Vec<packet::Signature>,
}
pub struct Message {
pile: PacketPile,
}
#[derive(PartialEq, Eq, Clone, Hash)]
pub enum Fingerprint {
V4([u8;20]),
Invalid(Box<[u8]>)
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
pub enum KeyID {
V4([u8;8]),
Invalid(Box<[u8]>)
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RevocationStatus<'a> {
Revoked(&'a [packet::Signature]),
CouldBe(&'a [packet::Signature]),
NotAsFarAsWeKnow,
}