Skip to content

Commit

Permalink
Merge pull request #39 from str4d/basic-errors
Browse files Browse the repository at this point in the history
Basic errors
  • Loading branch information
str4d authored Oct 12, 2018
2 parents e95eef7 + b42b481 commit 2547f72
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 143 deletions.
2 changes: 1 addition & 1 deletion src/crypto/dsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub struct DsaPublicKey {
impl DsaSignature {
pub fn from_bytes(data: &[u8]) -> Result<DsaSignature, super::Error> {
if data.len() < 40 {
return Err(super::Error::Dsa);
return Err(super::Error::InvalidSignature);
}

let mut rbar = [0u8; 20];
Expand Down
20 changes: 9 additions & 11 deletions src/crypto/elgamal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rand::{OsRng, Rng};
use sha2::{Digest, Sha256};
use std::ops::{Mul, Rem, Sub};

use super::{math::rectify, PrivateKey, PublicKey};
use super::{math::rectify, Error, PrivateKey, PublicKey};
use constants::{ELGAMAL_G, ELGAMAL_P, ELGAMAL_PM1, ELGAMAL_PM2};

fn gen_gamma_k() -> (BigUint, BigUint) {
Expand Down Expand Up @@ -70,12 +70,11 @@ impl<'a> From<&'a PublicKey> for Encryptor {

impl Encryptor {
/// Basic ElGamal encryption, following algorithm 8.18 1).
// TODO: Errors
fn encrypt_basic(&self, msg: &[u8]) -> Result<(BigUint, BigUint), ()> {
fn encrypt_basic(&self, msg: &[u8]) -> Result<(BigUint, BigUint), Error> {
// Represent the message as an integer m in the range {0, 1, ..., p - 1}
let m = BigUint::from_bytes_be(msg);
if m > *ELGAMAL_PM1 {
return Err(());
return Err(Error::InvalidMessage);
}

// Select a random integer k, 1 <= k <= p - 2
Expand All @@ -90,11 +89,10 @@ impl Encryptor {
}

/// ElGamal encryption using I2P's message and ciphertext encoding schemes.
// TODO: Errors
pub fn encrypt(&self, msg: &[u8]) -> Result<[u8; 514], ()> {
pub fn encrypt(&self, msg: &[u8]) -> Result<[u8; 514], Error> {
// Message must be no more than 222 bytes
if msg.len() > 222 {
return Err(());
return Err(Error::InvalidMessage);
}

let mut rng = OsRng::new().expect("should be able to construct RNG");
Expand Down Expand Up @@ -149,10 +147,10 @@ impl Decryptor {

/// ElGamal decryption using I2P's message and ciphertext encoding schemes.
// TODO: Errors
pub fn decrypt(&self, ct: &[u8]) -> Result<Vec<u8>, ()> {
pub fn decrypt(&self, ct: &[u8]) -> Result<Vec<u8>, Error> {
// Ciphertext must be 514 bytes
if ct.len() != 514 {
return Err(());
return Err(Error::InvalidCiphertext);
}

// ElGamal ciphertext:
Expand All @@ -164,7 +162,7 @@ impl Decryptor {
let data = self.decrypt_basic((gamma, delta));
if data.len() < 33 {
// Decrypted data is too small
return Err(());
return Err(Error::InvalidCiphertext);
}

// ElGamal plaintext:
Expand All @@ -175,7 +173,7 @@ impl Decryptor {
if hash.as_slice() == &data[1..33] {
Ok(msg)
} else {
Err(())
Err(Error::InvalidCiphertext)
}
}
}
Expand Down
103 changes: 53 additions & 50 deletions src/crypto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
use aes::{self, block_cipher_trait::generic_array::GenericArray as AesGenericArray};
use block_modes::{block_padding::ZeroPadding, BlockMode, BlockModeIv, Cbc};
use nom::Err;
use ring::{self, signature as ring_signature};
use ring::signature as ring_signature;
use signatory::{
curve::{NistP256, NistP384, WeierstrassCurve},
ecdsa::FixedSignature,
ed25519,
error::Error as SignatoryError,
generic_array::{typenum::Unsigned, GenericArray as SignatoryGenericArray},
public_key, sign, verify, verify_sha256, verify_sha384, EcdsaPublicKey, Ed25519PublicKey,
Ed25519Seed, Ed25519Signature, Signature as SignatorySignature,
Expand All @@ -31,24 +30,28 @@ pub(crate) mod math;
pub(crate) const AES_BLOCK_SIZE: usize = 16;

/// Cryptographic errors
#[derive(Debug)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Error {
InvalidCiphertext,
InvalidKey,
InvalidMessage,
InvalidSignature,
NoSignature,
SigningFailed,
TypeMismatch,
Dsa,
Ring(ring::error::Unspecified),
Signatory(SignatoryError),
}

impl From<ring::error::Unspecified> for Error {
fn from(e: ring::error::Unspecified) -> Self {
Error::Ring(e)
}
}

impl From<SignatoryError> for Error {
fn from(e: SignatoryError) -> Self {
Error::Signatory(e)
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::InvalidCiphertext => "Invalid ciphertext".fmt(f),
Error::InvalidKey => "Invalid cryptographic key".fmt(f),
Error::InvalidMessage => "Invalid message".fmt(f),
Error::InvalidSignature => "Bad signature".fmt(f),
Error::NoSignature => "No signature".fmt(f),
Error::SigningFailed => "Failed to create a signature".fmt(f),
Error::TypeMismatch => "Signature type doesn't match key type".fmt(f),
}
}
}

Expand Down Expand Up @@ -274,9 +277,9 @@ impl SigningPublicKey {
SigType::Rsa2048Sha256 | SigType::Rsa3072Sha384 | SigType::Rsa4096Sha512 => {
panic!("Online verifying not supported")
}
SigType::Ed25519 => Ok(SigningPublicKey::Ed25519(Ed25519PublicKey::from_bytes(
data,
)?)),
SigType::Ed25519 => Ok(SigningPublicKey::Ed25519(
Ed25519PublicKey::from_bytes(data).map_err(|_| Error::InvalidKey)?,
)),
}
}

Expand All @@ -286,9 +289,9 @@ impl SigningPublicKey {
SigningPrivateKey::EcdsaSha256P256 => unimplemented!(),
SigningPrivateKey::EcdsaSha384P384 => unimplemented!(),
SigningPrivateKey::EcdsaSha512P521 => unimplemented!(),
SigningPrivateKey::Ed25519(ref seed) => Ok(SigningPublicKey::Ed25519(public_key(
&Ed25519Signer::from(seed),
)?)),
SigningPrivateKey::Ed25519(ref seed) => Ok(SigningPublicKey::Ed25519(
public_key(&Ed25519Signer::from(seed)).map_err(|_| Error::InvalidKey)?,
)),
}
}

Expand All @@ -308,23 +311,22 @@ impl SigningPublicKey {
if pk.verify(message, s) {
Ok(())
} else {
Err(Error::Dsa)
Err(Error::InvalidSignature)
}
}
(&SigningPublicKey::EcdsaSha256P256(ref pk), &Signature::EcdsaSha256P256(ref s)) => {
verify_sha256(&P256Verifier::from(pk), message, s).map_err(|e| e.into())
verify_sha256(&P256Verifier::from(pk), message, s)
.map_err(|_| Error::InvalidSignature)
}
(&SigningPublicKey::EcdsaSha384P384(ref pk), &Signature::EcdsaSha384P384(ref s)) => {
verify_sha384(&P384Verifier::from(pk), message, s).map_err(|e| e.into())
verify_sha384(&P384Verifier::from(pk), message, s)
.map_err(|_| Error::InvalidSignature)
}
(&SigningPublicKey::EcdsaSha512P521, &Signature::EcdsaSha512P521) => unimplemented!(),
(&SigningPublicKey::Ed25519(ref pk), &Signature::Ed25519(ref s)) => {
verify(&Ed25519Verifier::from(pk), message, s).map_err(|e| e.into())
}
_ => {
println!("Signature type doesn't match key type");
Err(Error::TypeMismatch)
verify(&Ed25519Verifier::from(pk), message, s).map_err(|_| Error::InvalidSignature)
}
_ => Err(Error::TypeMismatch),
}
}
}
Expand Down Expand Up @@ -365,7 +367,9 @@ impl SigningPrivateKey {
SigType::Rsa2048Sha256 | SigType::Rsa3072Sha384 | SigType::Rsa4096Sha512 => {
panic!("Online signing not supported")
}
SigType::Ed25519 => Ok(SigningPrivateKey::Ed25519(Ed25519Seed::from_bytes(data)?)),
SigType::Ed25519 => Ok(SigningPrivateKey::Ed25519(
Ed25519Seed::from_bytes(data).map_err(|_| Error::InvalidKey)?,
)),
}
}

Expand All @@ -385,9 +389,9 @@ impl SigningPrivateKey {
SigningPrivateKey::EcdsaSha256P256 => unimplemented!(),
SigningPrivateKey::EcdsaSha384P384 => unimplemented!(),
SigningPrivateKey::EcdsaSha512P521 => unimplemented!(),
SigningPrivateKey::Ed25519(ref seed) => {
Ok(Signature::Ed25519(sign(&Ed25519Signer::from(seed), msg)?))
}
SigningPrivateKey::Ed25519(ref seed) => Ok(Signature::Ed25519(
sign(&Ed25519Signer::from(seed), msg).map_err(|_| Error::SigningFailed)?,
)),
}
}
}
Expand Down Expand Up @@ -436,33 +440,30 @@ impl OfflineSigningPublicKey {
pub fn verify(&self, message: &[u8], signature: &Signature) -> Result<(), Error> {
match (self, signature) {
(&OfflineSigningPublicKey::Rsa2048Sha256(ref pk), &Signature::Rsa2048Sha256(ref s)) => {
Ok(ring_signature::verify(
ring_signature::verify(
&ring_signature::RSA_PKCS1_2048_8192_SHA256_RAW,
untrusted::Input::from(pk),
untrusted::Input::from(message),
untrusted::Input::from(s),
)?)
).map_err(|_| Error::InvalidSignature)
}
(&OfflineSigningPublicKey::Rsa3072Sha384(ref pk), &Signature::Rsa3072Sha384(ref s)) => {
Ok(ring_signature::verify(
ring_signature::verify(
&ring_signature::RSA_PKCS1_3072_8192_SHA384_RAW,
untrusted::Input::from(pk),
untrusted::Input::from(message),
untrusted::Input::from(s),
)?)
).map_err(|_| Error::InvalidSignature)
}
(&OfflineSigningPublicKey::Rsa4096Sha512(ref pk), &Signature::Rsa4096Sha512(ref s)) => {
Ok(ring_signature::verify(
ring_signature::verify(
&ring_signature::RSA_PKCS1_4096_8192_SHA512_RAW,
untrusted::Input::from(pk),
untrusted::Input::from(message),
untrusted::Input::from(s),
)?)
}
_ => {
println!("Signature type doesn't match key type");
Err(Error::TypeMismatch)
).map_err(|_| Error::InvalidSignature)
}
_ => Err(Error::TypeMismatch),
}
}
}
Expand All @@ -485,13 +486,15 @@ impl Signature {
pub fn from_bytes(sig_type: SigType, data: &[u8]) -> Result<Self, Error> {
match sig_type {
SigType::DsaSha1 => Ok(Signature::DsaSha1(dsa::DsaSignature::from_bytes(data)?)),
SigType::EcdsaSha256P256 => Ok(Signature::EcdsaSha256P256(FixedSignature::from_bytes(
data,
)?)),
SigType::EcdsaSha384P384 => Ok(Signature::EcdsaSha384P384(FixedSignature::from_bytes(
data,
)?)),
SigType::Ed25519 => Ok(Signature::Ed25519(Ed25519Signature::from_bytes(data)?)),
SigType::EcdsaSha256P256 => Ok(Signature::EcdsaSha256P256(
FixedSignature::from_bytes(data).map_err(|_| Error::InvalidSignature)?,
)),
SigType::EcdsaSha384P384 => Ok(Signature::EcdsaSha384P384(
FixedSignature::from_bytes(data).map_err(|_| Error::InvalidSignature)?,
)),
SigType::Ed25519 => Ok(Signature::Ed25519(
Ed25519Signature::from_bytes(data).map_err(|_| Error::InvalidSignature)?,
)),
SigType::EcdsaSha512P521
| SigType::Rsa2048Sha256
| SigType::Rsa3072Sha384
Expand Down
2 changes: 1 addition & 1 deletion src/data/frame.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use cookie_factory::*;
use itertools::Itertools;
use nom::{be_u16, be_u32, be_u64, be_u8, Err, ErrorKind};
use nom::{be_u16, be_u32, be_u64, be_u8, Err, ErrorKind, IResult};

use super::*;
use constants;
Expand Down
Loading

0 comments on commit 2547f72

Please sign in to comment.