Skip to content

Commit b562e4c

Browse files
committed
Allow serde without alloc
1 parent 04771a8 commit b562e4c

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

elliptic-curve/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pkcs8 = { version = "0.11.0-rc.6", optional = true, default-features = false }
3636
sec1 = { version = "0.8.0-rc.8", optional = true, features = ["subtle", "zeroize"] }
3737
serdect = { version = "0.3", optional = true, default-features = false, features = ["alloc"] }
3838
serde_json = { version = "1.0.121", optional = true, default-features = false, features = ["alloc"] }
39+
der = { version = "0.8.0-rc.8", default-features = false }
3940

4041
[dev-dependencies]
4142
hex-literal = "1"
@@ -67,7 +68,7 @@ group = ["dep:group", "ff"]
6768
jwk = ["dep:base64ct", "dep:serde_json", "alloc", "serde", "zeroize/alloc"]
6869
pkcs8 = ["dep:pkcs8", "sec1"]
6970
pem = ["dep:pem-rfc7468", "alloc", "arithmetic", "pkcs8/pem", "sec1/pem"]
70-
serde = ["dep:serdect", "alloc", "pkcs8", "sec1/serde"]
71+
serde = ["dep:serdect", "pkcs8", "sec1/serde"]
7172

7273
[package.metadata.docs.rs]
7374
features = ["bits", "ecdh", "jwk", "pem", "std"]

elliptic-curve/src/public_key.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,28 @@ where
474474
}
475475
}
476476

477+
#[cfg(feature = "serde")]
478+
impl<C> PublicKey<C>
479+
where
480+
C: AssociatedOid + CurveArithmetic,
481+
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
482+
FieldBytesSize<C>: ModulusSize,
483+
{
484+
/// Encode this [`PublicKey`] as der bytes, placing the result in `output`. This function
485+
/// returns a slice containing the encoded DER bytes.
486+
fn encode_as_der<'buf>(&self, output: &'buf mut [u8]) -> der::Result<&'buf [u8]> {
487+
let public_key_bytes = self.to_encoded_point(false);
488+
let subject_public_key = der::asn1::BitStringRef::new(0, public_key_bytes.as_bytes())?;
489+
490+
let spki = pkcs8::SubjectPublicKeyInfo {
491+
algorithm: Self::ALGORITHM_IDENTIFIER,
492+
subject_public_key,
493+
};
494+
495+
der::Encode::encode_to_slice(&spki, output)
496+
}
497+
}
498+
477499
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
478500
impl<C> EncodePublicKey for PublicKey<C>
479501
where
@@ -485,6 +507,7 @@ where
485507
let public_key_bytes = self.to_encoded_point(false);
486508
let subject_public_key = der::asn1::BitStringRef::new(0, public_key_bytes.as_bytes())?;
487509

510+
// TODO: use `encode_as_der` here?
488511
pkcs8::SubjectPublicKeyInfo {
489512
algorithm: Self::ALGORITHM_IDENTIFIER,
490513
subject_public_key,
@@ -532,7 +555,11 @@ where
532555
where
533556
S: ser::Serializer,
534557
{
535-
let der = self.to_public_key_der().map_err(ser::Error::custom)?;
558+
// TODO: can we determine DER encoding length up-front? Using `MockCurve` gives
559+
// 91 bytes of output, but it feels like that depends on the curve that is being
560+
// used here.
561+
let mut buf = [0u8; 91];
562+
let der = self.encode_as_der(&mut buf).map_err(ser::Error::custom)?;
536563
serdect::slice::serialize_hex_upper_or_bin(&der, serializer)
537564
}
538565
}

0 commit comments

Comments
 (0)