Skip to content

Commit fc67af8

Browse files
committed
Allow serde without alloc
1 parent cc3b499 commit fc67af8

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
@@ -34,6 +34,7 @@ pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] }
3434
pkcs8 = { version = "0.11.0-rc.6", optional = true, default-features = false }
3535
sec1 = { version = "0.8.0-rc.8", optional = true, features = ["subtle", "zeroize"] }
3636
serdect = { version = "0.3", optional = true, default-features = false, features = ["alloc"] }
37+
der = { version = "0.8.0-rc.8", default-features = false }
3738

3839
[dev-dependencies]
3940
hex-literal = "1"
@@ -64,7 +65,7 @@ ecdh = ["arithmetic", "digest", "dep:hkdf"]
6465
group = ["dep:group", "ff"]
6566
pkcs8 = ["dep:pkcs8", "sec1"]
6667
pem = ["dep:pem-rfc7468", "alloc", "arithmetic", "pkcs8/pem", "sec1/pem"]
67-
serde = ["dep:serdect", "alloc", "pkcs8", "sec1/serde"]
68+
serde = ["dep:serdect", "pkcs8", "sec1/serde"]
6869

6970
[package.metadata.docs.rs]
7071
features = ["bits", "ecdh", "pem", "std"]

elliptic-curve/src/public_key.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,28 @@ where
425425
}
426426
}
427427

428+
#[cfg(feature = "serde")]
429+
impl<C> PublicKey<C>
430+
where
431+
C: AssociatedOid + CurveArithmetic,
432+
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
433+
FieldBytesSize<C>: ModulusSize,
434+
{
435+
/// Encode this [`PublicKey`] as der bytes, placing the result in `output`. This function
436+
/// returns a slice containing the encoded DER bytes.
437+
fn encode_as_der<'buf>(&self, output: &'buf mut [u8]) -> der::Result<&'buf [u8]> {
438+
let public_key_bytes = self.to_encoded_point(false);
439+
let subject_public_key = der::asn1::BitStringRef::new(0, public_key_bytes.as_bytes())?;
440+
441+
let spki = pkcs8::SubjectPublicKeyInfo {
442+
algorithm: Self::ALGORITHM_IDENTIFIER,
443+
subject_public_key,
444+
};
445+
446+
der::Encode::encode_to_slice(&spki, output)
447+
}
448+
}
449+
428450
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
429451
impl<C> EncodePublicKey for PublicKey<C>
430452
where
@@ -436,6 +458,7 @@ where
436458
let public_key_bytes = self.to_encoded_point(false);
437459
let subject_public_key = der::asn1::BitStringRef::new(0, public_key_bytes.as_bytes())?;
438460

461+
// TODO: use `encode_as_der` here?
439462
pkcs8::SubjectPublicKeyInfo {
440463
algorithm: Self::ALGORITHM_IDENTIFIER,
441464
subject_public_key,
@@ -483,7 +506,11 @@ where
483506
where
484507
S: ser::Serializer,
485508
{
486-
let der = self.to_public_key_der().map_err(ser::Error::custom)?;
509+
// TODO: can we determine DER encoding length up-front? Using `MockCurve` gives
510+
// 91 bytes of output, but it feels like that depends on the curve that is being
511+
// used here.
512+
let mut buf = [0u8; 91];
513+
let der = self.encode_as_der(&mut buf).map_err(ser::Error::custom)?;
487514
serdect::slice::serialize_hex_upper_or_bin(&der, serializer)
488515
}
489516
}

0 commit comments

Comments
 (0)