Skip to content

Commit

Permalink
Switch error handling to error_chain part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
Phaiax committed Jun 21, 2017
1 parent f4914d9 commit ddbda2b
Show file tree
Hide file tree
Showing 11 changed files with 375 additions and 152 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ fast_math = ['ramp']
serde = "1.0"
serde_derive = "1.0"
serde_bytes = "0.10"
error-chain = "*"
rmp = "*"
rmp-serde = "*"
rmpv = "*"
Expand Down
2 changes: 1 addition & 1 deletion examples/keybase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ extern crate rsaltpack;
fn main() {

// Stakeholders
use rsaltpack::key::{EncryptionKeyPair, KeybaseFormat, EncryptionPublicKey};
use rsaltpack::key::{EncryptionKeyPair, KeybaseKeyFormat, EncryptionPublicKey};
let sender = EncryptionKeyPair::gen();


Expand Down
15 changes: 8 additions & 7 deletions src/armor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@
//! Use the funciton [armor()](fn.armor.html) to armor a the binary data
//! at once. Header and footer will be written immediatly.
//use ramp::Int;
use std::io::Write;
use util::Consumable;
use std::fmt;
use std::cmp;

use util::Consumable;
use base62::b32bytes_to_base62_formatted;

pub use ::SaltpackMessageType;
use errors::*;

/// This function does the same as [ArmoringStream](struct.ArmoringStream.html),
/// but in one rush.
Expand All @@ -36,7 +37,7 @@ pub use ::SaltpackMessageType;
pub fn armor(binary_in : &mut [u8],
vendorstring: &str,
messagetype: SaltpackMessageType)
-> Result<String, String> {
-> Result<String> {
let mut armoring_stream = try!(ArmoringStream::new(vendorstring, messagetype));
let mut out = vec![0u8; armoring_stream.predict_armored_len(binary_in.len())];
let (_, written) = armoring_stream.armor(&binary_in[..], true, &mut out[..]).unwrap();
Expand All @@ -47,13 +48,13 @@ pub fn armor(binary_in : &mut [u8],

/// Check if a vendor string is valid. The vendor string must only contain
/// these characters: Regex: [a-zA-Z0-9]*
pub fn valid_vendor(vendor : &str) -> Result<(), String> {
pub fn valid_vendor(vendor : &str) -> Result<()> {
fn in_(c : char, first : char, last : char) -> bool {
first <= c && c <= last
}
for c in vendor.chars() {
if ! (in_(c, 'a', 'z') || in_(c, 'A', 'Z') || in_(c, '0', '9')) {
return Err(format!("Invalid char {} in vendor string {}.", c, vendor));
bail!(ErrorKind::BadVendorString(c, vendor.into()));
}
}
Ok(())
Expand Down Expand Up @@ -125,7 +126,7 @@ impl ArmoringStream {
/// Create a new streaming interface
pub fn new(vendorstring: &str,
messagetype: SaltpackMessageType)
-> Result<ArmoringStream, String> {
-> Result<ArmoringStream> {
try!(valid_vendor(vendorstring));
Ok(ArmoringStream{
state : ArmoringStreamState::AtHeader{
Expand Down Expand Up @@ -156,7 +157,7 @@ impl ArmoringStream {
mut binary_in : &[u8],
last_bytes : bool,
mut armored_out : &mut[u8])
-> Result<(usize, usize), String> {
-> Result<(usize, usize)> {

let binary_in_len = binary_in.len();
let armored_out_len = armored_out.len();
Expand Down
8 changes: 5 additions & 3 deletions src/base62_num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::iter::repeat;

use armor::{SPACE_EVERY, NEWLINE_EVERY, BUF_SIZE, CHARS_PER_BLOCK, BYTES_PER_BLOCK};

use errors::*;

/// This function converts a zero based digit in base 62 to its ascii equivalent.
#[inline]
pub fn alphabet(i : u8) -> u8 {
Expand Down Expand Up @@ -189,12 +191,12 @@ pub fn b32bytes_to_base62_formatted(raw_in : &[u8],
/// Returns the number of bytes written.
/// [`CHARS_PER_BLOCK`]: ../armor/constant.CHARS_PER_BLOCK.html
/// [`BYTES_PER_BLOCK`]: ../armor/constant.BYTES_PER_BLOCK.html
pub fn decode_base62_block(base62 : &[u8], mut out_buffer : &mut[u8]) -> Result<usize, String> {
pub fn decode_base62_block(base62 : &[u8], mut out_buffer : &mut[u8]) -> Result<usize> {
use std::io::Write;

let (needed_output_len, valid) = BYTEBLOCKSIZE_BY_CHARBLOCKSIZE[base62.len()];
if valid == Invalid {
return Err("Error while decoding base62: Invalid block size.".to_string())
bail!(ErrorKind::BadArmor);
}

assert!(out_buffer.len() >= needed_output_len);
Expand All @@ -216,7 +218,7 @@ pub fn decode_base62_block(base62 : &[u8], mut out_buffer : &mut[u8]) -> Result<

/// Decodes stripped (only ascii, no whitespace) base62 coded data into its raw representation
/// Reuses the ascii_input as buffer, that means the data is unusable afterwards.
pub fn decode_base62<'a>(ascii_input : &mut [u8]) -> Result<Vec<u8>, String> {
pub fn decode_base62<'a>(ascii_input : &mut [u8]) -> Result<Vec<u8>> {
// base62 efficiency is 75%, so we can assume maximum raw data length.
// (+rounding +last non full block needs still place of a full block (max 32))
let max_output_size = ascii_input.len() * 3 / 4 + 1 + 32;
Expand Down
3 changes: 2 additions & 1 deletion src/dearmor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use ::SaltpackMessageType;
use util::Consumable;
use util::TryInto;
use base62::decode_base62;
use errors::*;

/// Removes all chars that can not occur within saltpacks.
/// (keeps [A-Za-z0-9.])
Expand Down Expand Up @@ -101,7 +102,7 @@ pub struct Dearmored {
/// Returns no more than `max` dearmored saltpacks.
///
/// [`Dearmored`]: struct.Dearmored.html
pub fn dearmor(text : Stripped, max : usize) -> Result<Vec<Dearmored>, String> {
pub fn dearmor(text : Stripped, max : usize) -> Result<Vec<Dearmored>> {
let mut saltpacks = Vec::<Dearmored>::with_capacity(min(3, max));

let mut text : Vec<u8> = text.0; // mut for inplace editing in decode_base62
Expand Down
11 changes: 6 additions & 5 deletions src/encrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ use rmp_serde::Serializer;

use ::armor;
use ::util;
use errors::*;

use std::mem::size_of;
use std::io::{Read, Write};
Expand Down Expand Up @@ -169,7 +170,7 @@ pub fn encrypt_to_binary(sender : Option<&EncryptionKeyPair>,
pub fn encrypt_and_armor(sender : Option<&EncryptionKeyPair>,
recipients : &Vec<EncryptionPublicKey>,
payload : &[u8],
vendor : &str) -> Result<String, String> {
vendor : &str) -> Result<String> {
let mut saltpack = Saltpack::encrypt(sender, recipients);
saltpack.write_all(payload).unwrap();
saltpack.flush().unwrap();
Expand Down Expand Up @@ -238,7 +239,7 @@ impl Saltpack {
/// ```
///
/// Returns Err if vendor contains chars other than `[a-zA-Z0-9]`.
pub fn armor(self, vendor : &str) -> Result<ArmoredSaltpack, String> {
pub fn armor(self, vendor : &str) -> Result<ArmoredSaltpack> {
ArmoredSaltpack::new(self, vendor)
}

Expand Down Expand Up @@ -534,7 +535,7 @@ impl Read for ArmoredSaltpack {
let front = self.saltpack.output_buffer.front().unwrap();
match self.armoring_stream.armor(&front[br..], self.saltpack.last_bytes(), &mut buffer) {
Ok(a) => a,
Err(msg) => { return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, msg)); }
Err(msg) => { return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, msg.description())); }
}
};
bytes_read += written_into_buffer;
Expand All @@ -555,7 +556,7 @@ impl Read for ArmoredSaltpack {
let (_, written_into_buffer) = {
match self.armoring_stream.armor(&[], true, &mut buffer) {
Ok(a) => a,
Err(msg) => { return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, msg)); }
Err(msg) => { return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, msg.description())); }
}
};
buffer.consume(written_into_buffer);
Expand All @@ -569,7 +570,7 @@ impl Read for ArmoredSaltpack {

impl ArmoredSaltpack {

pub fn new(saltpack : Saltpack, vendor : &str) -> Result<ArmoredSaltpack, String> {
pub fn new(saltpack : Saltpack, vendor : &str) -> Result<ArmoredSaltpack> {
Ok(ArmoredSaltpack {
saltpack : saltpack,
armoring_stream : try!(armor::ArmoringStream::new(vendor, SaltpackMessageType::ENCRYPTEDMESSAGE)),
Expand Down
60 changes: 60 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@


error_chain!{

errors {
#[doc="The base62 encoding of the armored saltpack is corrupted."]
BadArmor {
description("The base62 encoding of the armored saltpack is corrupted.")
}
#[doc="Invalid char in vendor string. Data: (invalid_char, received_vendor_string)"]
BadVendorString(c : char, vendor: String) {
description("Invalid char in vendor string. (BEGIN _ SALTPACK ...)")
display("Invalid char {} in vendor string {}.", c, vendor)
}
#[doc="String has wrong length. Data: (received_len)"]
KeybaseKeyWrongLength(length : usize) {
description("String has wrong length. \
Keybase formated keys have a length of 70 chars.")
display("String has wrong length. \
Expected 70 chars but got {} chars.", length)
}
#[doc="Given string is not a keybase public key."]
KeybaseKeyNotAPublicKey {
description("Given string is not a keybase public key. \
Keybase formated keys end with `0a`.")
}
#[doc="Unsupported keybase key version. Data: (received_version)"]
KeybaseKeyUnsupportedVersion(v: String) {
description("Unsupported keybase key version.")
display("Unsupported keybase key version. Got version {}.", v)
}
#[doc="Given key is not a encryption key"]
KeybaseKeyNotAnEncryptionKey {
description("Given key is not an encryption key. \
Keybase encryption keys start with `0121`.")
}
#[doc="Given key is not a signing key"]
KeybaseKeyNotASigningKey {
description("Given key is not a signing key. \
Keybase signing keys start with `0120`.")
}
#[doc = "Wrong Length. Data: (keytype, received_len, expected_len)"]
RawHexEncodedKeyWrongLength(type_: String, got: usize, expected: usize) {
description("Hex encoded key has wrong length.")
display("Hex encoded {} key has wrong length. \
Expected {} chars but got {} chars.", type_, expected, got)
}
#[doc = "Error while decoding hex encoded string."]
CouldNotDecodeHex {
description("Error while decoding hex encoded string. Only ascii numerals and chars from a-f are allowed.")
}
}
foreign_links {

Utf8Error(::std::str::Utf8Error) #[doc = "Foreign error: std::str::Utf8Error"];

ParseIntError(::std::num::ParseIntError) #[doc = "Foreign error: std::num::ParseIntError"];
}
}

Loading

0 comments on commit ddbda2b

Please sign in to comment.