From 274a2958348dbe1e7102e2a76e07edc33078938d Mon Sep 17 00:00:00 2001 From: Weiliang Li Date: Tue, 5 Jan 2021 15:03:09 +0900 Subject: [PATCH] Revamp error handling (#63) * revamp encapsulate error * revamp hkdf error * update license * update dep --- Cargo.toml | 10 +++++----- LICENSE | 2 +- src/lib.rs | 4 ++-- src/utils.rs | 19 ++++++++++--------- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ff0fec5..8cd9274 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ecies" -version = "0.2.0" +version = "0.2.1" # docs authors = ["Weiliang Li "] description = "Elliptic Curve Integrated Encryption Scheme for secp256k1 in Rust" @@ -25,11 +25,11 @@ libsecp256k1 = "0.3.5" sha2 = "0.9.2" # openssl aes -openssl = {version = "0.10.31", optional = true} +openssl = {version = "0.10.32", optional = true} # pure rust aes aes-gcm = {version = "0.8.0", optional = true} -typenum = {version = "1.12", optional = true} +typenum = {version = "1.12.0", optional = true} [target.'cfg(target_arch = "wasm32")'.dependencies] rand = {version = "0.7.3", features = ["wasm-bindgen"]} @@ -50,8 +50,8 @@ wasm-bindgen-test = "0.3.19" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] futures-util = "0.3.8" -reqwest = "0.10.9" -tokio = "0.2.22" +reqwest = "0.10.10" +tokio = "0.2.24" [[bench]] harness = false diff --git a/LICENSE b/LICENSE index 5dbf7e6..03ac992 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019-2020 Weiliang Li +Copyright (c) 2019-2021 Weiliang Li Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/lib.rs b/src/lib.rs index 154d5d9..faded0b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,7 +76,7 @@ pub fn encrypt(receiver_pub: &[u8], msg: &[u8]) -> Result, SecpError> { let receiver_pk = PublicKey::parse_slice(receiver_pub, None)?; let (ephemeral_sk, ephemeral_pk) = generate_keypair(); - let aes_key = encapsulate(&ephemeral_sk, &receiver_pk); + let aes_key = encapsulate(&ephemeral_sk, &receiver_pk)?; let encrypted = aes_encrypt(&aes_key, msg).ok_or(SecpError::InvalidMessage)?; let mut cipher_text = Vec::with_capacity(FULL_PUBLIC_KEY_SIZE + encrypted.len()); @@ -102,7 +102,7 @@ pub fn decrypt(receiver_sec: &[u8], msg: &[u8]) -> Result, SecpError> { let ephemeral_pk = PublicKey::parse_slice(&msg[..FULL_PUBLIC_KEY_SIZE], None)?; let encrypted = &msg[FULL_PUBLIC_KEY_SIZE..]; - let aes_key = decapsulate(&ephemeral_pk, &receiver_sk); + let aes_key = decapsulate(&ephemeral_pk, &receiver_sk)?; aes_decrypt(&aes_key, encrypted).ok_or(SecpError::InvalidMessage) } diff --git a/src/utils.rs b/src/utils.rs index 2e13956..17d9604 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,6 @@ use hkdf::Hkdf; use rand::thread_rng; -use secp256k1::{util::FULL_PUBLIC_KEY_SIZE, PublicKey, SecretKey}; +use secp256k1::{util::FULL_PUBLIC_KEY_SIZE, Error as SecpError, PublicKey, SecretKey}; use sha2::Sha256; use crate::consts::EMPTY_BYTES; @@ -19,9 +19,9 @@ pub fn generate_keypair() -> (SecretKey, PublicKey) { } /// Calculate a shared AES key of our secret key and peer's public key by hkdf -pub fn encapsulate(sk: &SecretKey, peer_pk: &PublicKey) -> AesKey { +pub fn encapsulate(sk: &SecretKey, peer_pk: &PublicKey) -> Result { let mut shared_point = peer_pk.clone(); - shared_point.tweak_mul_assign(&sk).unwrap(); + shared_point.tweak_mul_assign(&sk)?; let mut master = Vec::with_capacity(FULL_PUBLIC_KEY_SIZE * 2); master.extend(PublicKey::from_secret_key(&sk).serialize().iter()); @@ -31,9 +31,9 @@ pub fn encapsulate(sk: &SecretKey, peer_pk: &PublicKey) -> AesKey { } /// Calculate a shared AES key of our public key and peer's secret key by hkdf -pub fn decapsulate(pk: &PublicKey, peer_sk: &SecretKey) -> AesKey { +pub fn decapsulate(pk: &PublicKey, peer_sk: &SecretKey) -> Result { let mut shared_point = pk.clone(); - shared_point.tweak_mul_assign(&peer_sk).unwrap(); + shared_point.tweak_mul_assign(&peer_sk)?; let mut master = Vec::with_capacity(FULL_PUBLIC_KEY_SIZE * 2); master.extend(pk.serialize().iter()); @@ -43,11 +43,12 @@ pub fn decapsulate(pk: &PublicKey, peer_sk: &SecretKey) -> AesKey { } // private below -fn hkdf_sha256(master: &[u8]) -> AesKey { +fn hkdf_sha256(master: &[u8]) -> Result { let h = Hkdf::::new(None, master); let mut out = [0u8; 32]; - h.expand(&EMPTY_BYTES, &mut out).unwrap(); - out + h.expand(&EMPTY_BYTES, &mut out) + .map_err(|_| SecpError::InvalidInputLength)?; + Ok(out) } #[cfg(test)] @@ -176,7 +177,7 @@ pub(crate) mod tests { assert_eq!(encapsulate(&sk2, &pk3), decapsulate(&pk2, &sk3)); assert_eq!( - encapsulate(&sk2, &pk3).to_vec(), + encapsulate(&sk2, &pk3).map(|v| v.to_vec()).unwrap(), decode_hex("6f982d63e8590c9d9b5b4c1959ff80315d772edd8f60287c9361d548d5200f82") ); }