Skip to content

Commit

Permalink
sec1: use base16ct and serdect crates
Browse files Browse the repository at this point in the history
Uses these crates to impl hex encoding/decoding and serde support
  • Loading branch information
tarcieri committed May 7, 2022
1 parent d053d25 commit 9e02e0a
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 85 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions sec1/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ edition = "2021"
rust-version = "1.57"

[dependencies]
base16ct = { version = "0.1.1", optional = true, default-features = false, path = "../base16ct" }
der = { version = "=0.6.0-pre.4", optional = true, features = ["oid"], path = "../der" }
generic-array = { version = "0.14.4", optional = true, default-features = false }
pkcs8 = { version = "=0.9.0-pre.3", optional = true, default-features = false, path = "../pkcs8" }
serde = { version = "1.0.16", optional = true, default-features = false }
serdect = { version = "0.1", optional = true, default-features = false, features = ["alloc"], path = "../serdect" }
subtle = { version = "2", optional = true, default-features = false }
zeroize = { version = "1", optional = true, default-features = false }

Expand All @@ -31,7 +32,8 @@ tempfile = "3"
default = ["der", "point"]
alloc = ["der/alloc", "pkcs8/alloc", "zeroize/alloc"]
pem = ["alloc", "der/pem", "pkcs8/pem"]
point = ["generic-array"]
point = ["base16ct", "generic-array"]
serde = ["serdect"]
std = ["der/std", "alloc"]

[package.metadata.docs.rs]
Expand Down
3 changes: 3 additions & 0 deletions sec1/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ pub use pkcs8;
#[cfg(feature = "pkcs8")]
use pkcs8::ObjectIdentifier;

#[cfg(all(doc, feature = "serde"))]
use serdect::serde;

/// Algorithm [`ObjectIdentifier`] for elliptic curve public key cryptography
/// (`id-ecPublicKey`).
///
Expand Down
90 changes: 11 additions & 79 deletions sec1/src/point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//! [SEC1: Elliptic Curve Cryptography]: https://www.secg.org/sec1-v2.pdf

use crate::{Error, Result};
use base16ct::HexDisplay;
use core::{
cmp::Ordering,
fmt::{self, Debug},
Expand All @@ -21,7 +22,7 @@ use generic_array::{
use alloc::boxed::Box;

#[cfg(feature = "serde")]
use serde::{de, ser, Deserialize, Serialize};
use serdect::serde::{de, ser, Deserialize, Serialize};

#[cfg(feature = "subtle")]
use subtle::{Choice, ConditionallySelectable};
Expand Down Expand Up @@ -348,10 +349,7 @@ where
Size: ModulusSize,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for byte in self.as_bytes() {
write!(f, "{:02x}", byte)?;
}
Ok(())
write!(f, "{:x}", HexDisplay(self.as_bytes()))
}
}

Expand All @@ -360,10 +358,7 @@ where
Size: ModulusSize,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for byte in self.as_bytes() {
write!(f, "{:02X}", byte)?;
}
Ok(())
write!(f, "{:X}", HexDisplay(self.as_bytes()))
}
}

Expand All @@ -378,41 +373,10 @@ where
type Err = Error;

fn from_str(hex: &str) -> Result<Self> {
let mut buffer = GenericArray::<u8, Size::UncompressedPointSize>::default();
let decoded_len = hex.as_bytes().len() / 2;

if hex.as_bytes().len() % 2 != 0 || decoded_len > buffer.len() {
return Err(Error::PointEncoding);
}

let mut upper_case = None;

// Ensure all characters are valid and case is not mixed
for &byte in hex.as_bytes() {
match byte {
b'0'..=b'9' => (),
b'a'..=b'z' => match upper_case {
Some(true) => return Err(Error::PointEncoding),
Some(false) => (),
None => upper_case = Some(false),
},
b'A'..=b'Z' => match upper_case {
Some(true) => (),
Some(false) => return Err(Error::PointEncoding),
None => upper_case = Some(true),
},
_ => return Err(Error::PointEncoding),
}
}

for (digit, byte) in hex.as_bytes().chunks_exact(2).zip(buffer.iter_mut()) {
*byte = str::from_utf8(digit)
.ok()
.and_then(|s| u8::from_str_radix(s, 16).ok())
.ok_or(Error::PointEncoding)?;
}

Self::from_bytes(&buffer[..decoded_len])
let mut buf = GenericArray::<u8, Size::UncompressedPointSize>::default();
base16ct::mixed::decode(hex, &mut buf)
.map_err(|_| Error::PointEncoding)
.and_then(Self::from_bytes)
}
}

Expand All @@ -422,25 +386,11 @@ impl<Size> Serialize for EncodedPoint<Size>
where
Size: ModulusSize,
{
#[cfg(not(feature = "alloc"))]
fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
self.as_bytes().serialize(serializer)
}

#[cfg(feature = "alloc")]
fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
use alloc::string::ToString;
if serializer.is_human_readable() {
self.to_string().serialize(serializer)
} else {
self.as_bytes().serialize(serializer)
}
serdect::slice::serialize_hex_upper_or_bin(&self.as_bytes(), serializer)
}
}

Expand All @@ -450,30 +400,12 @@ impl<'de, Size> Deserialize<'de> for EncodedPoint<Size>
where
Size: ModulusSize,
{
#[cfg(not(feature = "alloc"))]
fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
use de::Error;
<&[u8]>::deserialize(deserializer)
.and_then(|slice| Self::from_bytes(slice).map_err(D::Error::custom))
}

#[cfg(feature = "alloc")]
fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
use de::Error;
if deserializer.is_human_readable() {
<&str>::deserialize(deserializer)?
.parse()
.map_err(D::Error::custom)
} else {
<&[u8]>::deserialize(deserializer)
.and_then(|bytes| Self::from_bytes(bytes).map_err(D::Error::custom))
}
let bytes = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?;
Self::from_bytes(&bytes).map_err(de::Error::custom)
}
}

Expand Down
4 changes: 2 additions & 2 deletions serdect/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ edition = "2021"
rust-version = "1.56"

[dependencies]
base16ct = { version = "0.1.1", default-features = false }
serde = { version = "1", default-features = false }
base16ct = { version = "0.1.1", default-features = false, path = "../base16ct" }
serde = { version = "1.0.96", default-features = false }

# optional features
zeroize = { version = "1", optional = true, default-features = false }
Expand Down

0 comments on commit 9e02e0a

Please sign in to comment.