1#[cfg(not(feature = "std"))]
48use alloc::{string::String, vec::Vec};
49
50use base64ct::{Base64, Encoding};
51use der::{Decode, Encode};
52use serde::{Deserialize, Deserializer, Serialize, Serializer};
53
54pub fn serialize<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
64where
65 S: Serializer,
66 T: Encode,
67{
68 let der_bytes = value.to_der().map_err(serde::ser::Error::custom)?;
69 if serializer.is_human_readable() {
70 let encoded = Base64::encode_string(&der_bytes);
71 serializer.serialize_str(&encoded)
72 } else {
73 serializer.serialize_bytes(&der_bytes)
74 }
75}
76
77pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
88where
89 D: Deserializer<'de>,
90 T: for<'a> Decode<'a>,
91{
92 let der_bytes = if deserializer.is_human_readable() {
93 let s = String::deserialize(deserializer)?;
94 Base64::decode_vec(&s).map_err(serde::de::Error::custom)?
95 } else {
96 Vec::<u8>::deserialize(deserializer)?
97 };
98 T::from_der(&der_bytes).map_err(serde::de::Error::custom)
99}
100
101pub mod option {
105 use super::{Base64, Decode, Deserialize, Deserializer, Encode, Encoding, Serializer};
106 #[cfg(not(feature = "std"))]
107 use alloc::{string::String, vec::Vec};
108
109 pub fn serialize<S, T>(value: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
119 where
120 S: Serializer,
121 T: Encode,
122 {
123 match value {
124 Some(v) => {
125 let der_bytes = v.to_der().map_err(serde::ser::Error::custom)?;
126 if serializer.is_human_readable() {
127 let encoded = Base64::encode_string(&der_bytes);
128 serializer.serialize_some(&encoded)
129 } else {
130 serializer.serialize_some(&der_bytes)
131 }
132 }
133 None => serializer.serialize_none(),
134 }
135 }
136
137 pub fn deserialize<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
144 where
145 D: Deserializer<'de>,
146 T: for<'a> Decode<'a>,
147 {
148 if deserializer.is_human_readable() {
149 let opt = Option::<String>::deserialize(deserializer)?;
150 match opt {
151 Some(s) => {
152 let der_bytes = Base64::decode_vec(&s).map_err(serde::de::Error::custom)?;
153 let v = T::from_der(&der_bytes).map_err(serde::de::Error::custom)?;
154 Ok(Some(v))
155 }
156 None => Ok(None),
157 }
158 } else {
159 let opt = Option::<Vec<u8>>::deserialize(deserializer)?;
160 match opt {
161 Some(bytes) => {
162 let v = T::from_der(&bytes).map_err(serde::de::Error::custom)?;
163 Ok(Some(v))
164 }
165 None => Ok(None),
166 }
167 }
168 }
169}
170
171pub mod vec {
176 use super::{Base64, Decode, Deserialize, Deserializer, Encode, Encoding, Serializer};
177 use serde::ser::SerializeSeq;
178 #[cfg(not(feature = "std"))]
179 use alloc::{string::String, vec::Vec};
180
181 pub fn serialize<S, T>(values: &[T], serializer: S) -> Result<S::Ok, S::Error>
188 where
189 S: Serializer,
190 T: Encode,
191 {
192 let is_hr = serializer.is_human_readable();
193 let mut seq = serializer.serialize_seq(Some(values.len()))?;
194 for v in values {
195 let der_bytes = v.to_der().map_err(serde::ser::Error::custom)?;
196 if is_hr {
197 let encoded = Base64::encode_string(&der_bytes);
198 seq.serialize_element(&encoded)?;
199 } else {
200 seq.serialize_element(der_bytes.as_slice())?;
201 }
202 }
203 seq.end()
204 }
205
206 pub fn deserialize<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
214 where
215 D: Deserializer<'de>,
216 T: for<'a> Decode<'a>,
217 {
218 if deserializer.is_human_readable() {
219 let strs = Vec::<String>::deserialize(deserializer)?;
220 let mut out = Vec::with_capacity(strs.len());
221 for s in strs {
222 let der_bytes = Base64::decode_vec(&s).map_err(serde::de::Error::custom)?;
223 let v = T::from_der(&der_bytes).map_err(serde::de::Error::custom)?;
224 out.push(v);
225 }
226 Ok(out)
227 } else {
228 let byte_vecs = Vec::<Vec<u8>>::deserialize(deserializer)?;
229 let mut out = Vec::with_capacity(byte_vecs.len());
230 for bytes in byte_vecs {
231 let v = T::from_der(&bytes).map_err(serde::de::Error::custom)?;
232 out.push(v);
233 }
234 Ok(out)
235 }
236 }
237}
238
239pub mod option_vec {
245 use super::{Base64, Decode, Deserialize, Deserializer, Encode, Encoding, Serialize, Serializer};
246 use serde::ser::SerializeSeq;
247 #[cfg(not(feature = "std"))]
248 use alloc::{string::String, vec::Vec};
249
250 pub fn serialize<S, T>(value: &Option<Vec<T>>, serializer: S) -> Result<S::Ok, S::Error>
257 where
258 S: Serializer,
259 T: Encode,
260 {
261 match value {
262 Some(values) => {
263 let is_hr = serializer.is_human_readable();
264 let mut bytes_buf: Vec<Vec<u8>> = Vec::with_capacity(values.len());
265 let mut str_buf: Vec<String> = Vec::with_capacity(values.len());
266 for v in values {
267 let der_bytes = v.to_der().map_err(serde::ser::Error::custom)?;
268 if is_hr {
269 str_buf.push(Base64::encode_string(&der_bytes));
270 } else {
271 bytes_buf.push(der_bytes);
272 }
273 }
274 if is_hr {
275 serializer.serialize_some(&str_buf)
276 } else {
277 struct Bytes<'a>(&'a [Vec<u8>]);
281 impl<'a> Serialize for Bytes<'a> {
282 fn serialize<S2: Serializer>(&self, s: S2) -> Result<S2::Ok, S2::Error> {
283 let mut seq = s.serialize_seq(Some(self.0.len()))?;
284 for b in self.0 {
285 seq.serialize_element(b.as_slice())?;
286 }
287 seq.end()
288 }
289 }
290 serializer.serialize_some(&Bytes(&bytes_buf))
291 }
292 }
293 None => serializer.serialize_none(),
294 }
295 }
296
297 pub fn deserialize<'de, D, T>(deserializer: D) -> Result<Option<Vec<T>>, D::Error>
304 where
305 D: Deserializer<'de>,
306 T: for<'a> Decode<'a>,
307 {
308 if deserializer.is_human_readable() {
309 let opt = Option::<Vec<String>>::deserialize(deserializer)?;
310 match opt {
311 Some(strs) => {
312 let mut out = Vec::with_capacity(strs.len());
313 for s in strs {
314 let der_bytes =
315 Base64::decode_vec(&s).map_err(serde::de::Error::custom)?;
316 let v = T::from_der(&der_bytes).map_err(serde::de::Error::custom)?;
317 out.push(v);
318 }
319 Ok(Some(out))
320 }
321 None => Ok(None),
322 }
323 } else {
324 let opt = Option::<Vec<Vec<u8>>>::deserialize(deserializer)?;
325 match opt {
326 Some(byte_vecs) => {
327 let mut out = Vec::with_capacity(byte_vecs.len());
328 for bytes in byte_vecs {
329 let v = T::from_der(&bytes).map_err(serde::de::Error::custom)?;
330 out.push(v);
331 }
332 Ok(Some(out))
333 }
334 None => Ok(None),
335 }
336 }
337 }
338}
339
340#[cfg(test)]
341mod tests {
342 use super::*;
354 use der::asn1::ObjectIdentifier;
355
356 const ECDSA_WITH_SHA256_OID: &str = "1.2.840.10045.4.3.2";
357 const ECDSA_WITH_SHA256_DER: &[u8] =
360 &[0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02];
361 const ECDSA_WITH_SHA256_BASE64: &str = "BggqhkjOPQQDAg==";
366
367 #[test]
370 fn json_serialize_matches_hand_computed_base64() {
371 #[derive(Serialize)]
372 struct Wrapper {
373 #[serde(serialize_with = "super::serialize")]
374 oid: ObjectIdentifier,
375 }
376 let oid: ObjectIdentifier = ECDSA_WITH_SHA256_OID.parse().unwrap();
377 let w = Wrapper { oid };
378 let json = serde_json::to_string(&w).unwrap();
379 let expected = format!(r#"{{"oid":"{}"}}"#, ECDSA_WITH_SHA256_BASE64);
380 assert_eq!(json, expected);
381 }
382
383 #[test]
386 fn json_deserialize_matches_hand_constructed_value() {
387 #[derive(Deserialize)]
388 struct Wrapper {
389 #[serde(deserialize_with = "super::deserialize")]
390 oid: ObjectIdentifier,
391 }
392 let json = format!(r#"{{"oid":"{}"}}"#, ECDSA_WITH_SHA256_BASE64);
393 let w: Wrapper = serde_json::from_str(&json).unwrap();
394 let expected: ObjectIdentifier = ECDSA_WITH_SHA256_OID.parse().unwrap();
395 assert_eq!(w.oid, expected);
396 }
397
398 #[test]
402 fn json_round_trip_preserves_der_canonical_form() {
403 #[derive(Serialize, Deserialize)]
404 struct Wrapper {
405 #[serde(with = "super::super::serde_der")]
406 oid: ObjectIdentifier,
407 }
408 let oid: ObjectIdentifier = ECDSA_WITH_SHA256_OID.parse().unwrap();
409 let original_der = oid.to_der().unwrap();
410 assert_eq!(original_der.as_slice(), ECDSA_WITH_SHA256_DER);
411
412 let w = Wrapper { oid };
413 let json = serde_json::to_string(&w).unwrap();
414 let back: Wrapper = serde_json::from_str(&json).unwrap();
415 let recovered_der = back.oid.to_der().unwrap();
416 assert_eq!(recovered_der, original_der);
417 }
418
419 #[test]
424 fn binary_serializer_emits_raw_der_bytes_not_base64() {
425 use serde::ser::Impossible;
426
427 struct BytesCapture {
434 captured: Vec<u8>,
435 }
436 impl Serializer for &mut BytesCapture {
437 type Ok = ();
438 type Error = serde::de::value::Error;
439 type SerializeSeq = Impossible<(), Self::Error>;
440 type SerializeTuple = Impossible<(), Self::Error>;
441 type SerializeTupleStruct = Impossible<(), Self::Error>;
442 type SerializeTupleVariant = Impossible<(), Self::Error>;
443 type SerializeMap = Impossible<(), Self::Error>;
444 type SerializeStruct = Impossible<(), Self::Error>;
445 type SerializeStructVariant = Impossible<(), Self::Error>;
446
447 fn is_human_readable(&self) -> bool {
448 false
449 }
450 fn serialize_bytes(self, v: &[u8]) -> Result<(), Self::Error> {
451 self.captured.extend_from_slice(v);
452 Ok(())
453 }
454 fn serialize_bool(self, _: bool) -> Result<(), Self::Error> {
455 unreachable!()
456 }
457 fn serialize_i8(self, _: i8) -> Result<(), Self::Error> {
458 unreachable!()
459 }
460 fn serialize_i16(self, _: i16) -> Result<(), Self::Error> {
461 unreachable!()
462 }
463 fn serialize_i32(self, _: i32) -> Result<(), Self::Error> {
464 unreachable!()
465 }
466 fn serialize_i64(self, _: i64) -> Result<(), Self::Error> {
467 unreachable!()
468 }
469 fn serialize_u8(self, _: u8) -> Result<(), Self::Error> {
470 unreachable!()
471 }
472 fn serialize_u16(self, _: u16) -> Result<(), Self::Error> {
473 unreachable!()
474 }
475 fn serialize_u32(self, _: u32) -> Result<(), Self::Error> {
476 unreachable!()
477 }
478 fn serialize_u64(self, _: u64) -> Result<(), Self::Error> {
479 unreachable!()
480 }
481 fn serialize_f32(self, _: f32) -> Result<(), Self::Error> {
482 unreachable!()
483 }
484 fn serialize_f64(self, _: f64) -> Result<(), Self::Error> {
485 unreachable!()
486 }
487 fn serialize_char(self, _: char) -> Result<(), Self::Error> {
488 unreachable!()
489 }
490 fn serialize_str(self, _: &str) -> Result<(), Self::Error> {
491 unreachable!()
492 }
493 fn serialize_none(self) -> Result<(), Self::Error> {
494 unreachable!()
495 }
496 fn serialize_some<T: ?Sized + Serialize>(self, _: &T) -> Result<(), Self::Error> {
497 unreachable!()
498 }
499 fn serialize_unit(self) -> Result<(), Self::Error> {
500 unreachable!()
501 }
502 fn serialize_unit_struct(self, _: &'static str) -> Result<(), Self::Error> {
503 unreachable!()
504 }
505 fn serialize_unit_variant(
506 self,
507 _: &'static str,
508 _: u32,
509 _: &'static str,
510 ) -> Result<(), Self::Error> {
511 unreachable!()
512 }
513 fn serialize_newtype_struct<T: ?Sized + Serialize>(
514 self,
515 _: &'static str,
516 _: &T,
517 ) -> Result<(), Self::Error> {
518 unreachable!()
519 }
520 fn serialize_newtype_variant<T: ?Sized + Serialize>(
521 self,
522 _: &'static str,
523 _: u32,
524 _: &'static str,
525 _: &T,
526 ) -> Result<(), Self::Error> {
527 unreachable!()
528 }
529 fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
530 unreachable!()
531 }
532 fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
533 unreachable!()
534 }
535 fn serialize_tuple_struct(
536 self,
537 _: &'static str,
538 _: usize,
539 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
540 unreachable!()
541 }
542 fn serialize_tuple_variant(
543 self,
544 _: &'static str,
545 _: u32,
546 _: &'static str,
547 _: usize,
548 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
549 unreachable!()
550 }
551 fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
552 unreachable!()
553 }
554 fn serialize_struct(
555 self,
556 _: &'static str,
557 _: usize,
558 ) -> Result<Self::SerializeStruct, Self::Error> {
559 unreachable!()
560 }
561 fn serialize_struct_variant(
562 self,
563 _: &'static str,
564 _: u32,
565 _: &'static str,
566 _: usize,
567 ) -> Result<Self::SerializeStructVariant, Self::Error> {
568 unreachable!()
569 }
570 }
571
572 let oid: ObjectIdentifier = ECDSA_WITH_SHA256_OID.parse().unwrap();
573 let mut cap = BytesCapture {
574 captured: Vec::new(),
575 };
576 super::serialize(&oid, &mut cap).unwrap();
577 assert_eq!(cap.captured, ECDSA_WITH_SHA256_DER);
578 }
579}