1use crate::types::{Asn1Writable, SimpleAsn1Writable};
2use crate::Tag;
3#[cfg(not(feature = "std"))]
4use alloc::vec::Vec;
5use alloc::{fmt, vec};
6
7#[derive(PartialEq, Eq, Debug)]
9pub enum WriteError {
10 AllocationError,
11 InvalidSetOrdering,
12}
13
14impl fmt::Display for WriteError {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 match self {
17 WriteError::AllocationError => write!(f, "allocation error"),
18 WriteError::InvalidSetOrdering => {
19 write!(f, "SET elements are not in DER order")
20 }
21 }
22 }
23}
24
25#[cfg(feature = "std")]
26impl std::error::Error for WriteError {}
27
28pub type WriteResult<T = ()> = Result<T, WriteError>;
29
30pub struct WriteBuf(Vec<u8>);
31
32impl WriteBuf {
33 #[inline]
34 pub(crate) fn new(data: Vec<u8>) -> WriteBuf {
35 WriteBuf(data)
36 }
37
38 #[inline]
39 pub(crate) fn len(&self) -> usize {
40 self.0.len()
41 }
42
43 #[inline]
44 pub(crate) fn as_slice(&self) -> &[u8] {
45 self.0.as_slice()
46 }
47
48 #[inline]
49 pub(crate) fn as_mut_slice(&mut self) -> &mut [u8] {
50 self.0.as_mut_slice()
51 }
52
53 #[inline]
55 pub fn reserve_additional(&mut self, len: usize) -> WriteResult {
56 self.0
57 .try_reserve(len)
58 .map_err(|_| WriteError::AllocationError)?;
59
60 Ok(())
61 }
62
63 #[inline]
64 pub fn push_byte(&mut self, b: u8) -> WriteResult {
65 self.reserve_additional(1)?;
66 self.0.push(b);
67 Ok(())
68 }
69
70 #[inline]
71 pub fn push_slice(&mut self, data: &[u8]) -> WriteResult {
72 self.reserve_additional(data.len())?;
73
74 self.0.extend_from_slice(data);
75 Ok(())
76 }
77}
78
79fn _length_length(length: usize) -> u8 {
80 (usize::BITS - length.leading_zeros()).div_ceil(8) as u8
81}
82
83pub(crate) fn length_encoding_size(content_length: usize) -> usize {
86 if content_length < 128 {
87 1
88 } else {
89 1 + _length_length(content_length) as usize
90 }
91}
92
93fn _insert_at_position(buf: &mut WriteBuf, pos: usize, data: &[u8]) -> WriteResult {
94 for _ in 0..data.len() {
95 buf.push_byte(0)?;
96 }
97 let src_range = pos..buf.len() - data.len();
98 buf.as_mut_slice().copy_within(src_range, pos + data.len());
99 buf.as_mut_slice()[pos..pos + data.len()].copy_from_slice(data);
100
101 Ok(())
102}
103
104pub struct Writer<'a> {
107 pub(crate) buf: &'a mut WriteBuf,
108}
109
110impl Writer<'_> {
111 #[inline]
112 #[doc(hidden)]
113 pub fn new(buf: &mut WriteBuf) -> Writer<'_> {
114 Writer { buf }
115 }
116
117 #[inline]
119 pub fn write_element<T: Asn1Writable>(&mut self, val: &T) -> Result<(), T::Error> {
120 if let Some(len) = val.encoded_length() {
121 self.buf.reserve_additional(len)?;
122 }
123 val.write(self)
124 }
125
126 #[inline]
133 pub fn write_tlv<E: From<WriteError>, F: FnOnce(&mut WriteBuf) -> Result<(), E>>(
134 &mut self,
135 tag: Tag,
136 content_length: Option<usize>,
137 body: F,
138 ) -> Result<(), E> {
139 tag.write_to(self.buf)?;
140
141 match content_length {
142 Some(len) => {
143 if len < 128 {
145 self.buf.push_byte(len as u8)?;
146 } else {
147 let num_length_bytes = _length_length(len);
148 self.buf.push_byte(0x80 | num_length_bytes)?;
149 for i in (1..=num_length_bytes).rev() {
150 self.buf.push_byte((len >> ((i - 1) * 8)) as u8)?;
151 }
152 }
153 let start_len = self.buf.len();
154 body(self.buf)?;
155 assert_eq!(len, self.buf.len() - start_len);
156 Ok(())
157 }
158 None => {
159 self.buf.push_byte(0)?;
162 let start_len = self.buf.len();
163 body(self.buf)?;
164 self.insert_length(start_len)?;
165 Ok(())
166 }
167 }
168 }
169
170 #[inline]
171 fn insert_length(&mut self, start_len: usize) -> WriteResult {
172 let added_len = self.buf.len() - start_len;
173 if added_len >= 128 {
174 let n = _length_length(added_len);
175 self.buf.as_mut_slice()[start_len - 1] = 0x80 | n;
176 let mut length_buf = [0u8; 8];
177 for (pos, i) in (1..=n).rev().enumerate() {
178 length_buf[pos] = (added_len >> ((i - 1) * 8)) as u8;
179 }
180 _insert_at_position(self.buf, start_len, &length_buf[..n as usize])?;
181 } else {
182 self.buf.as_mut_slice()[start_len - 1] = added_len as u8;
183 }
184
185 Ok(())
186 }
187
188 pub fn write_explicit_element<T: Asn1Writable>(
190 &mut self,
191 val: &T,
192 tag: u32,
193 ) -> Result<(), T::Error> {
194 let tag = crate::explicit_tag(tag);
195 self.write_tlv(tag, val.encoded_length(), |dest| {
196 Writer::new(dest).write_element(val)
197 })
198 }
199
200 pub fn write_implicit_element<T: SimpleAsn1Writable>(
202 &mut self,
203 val: &T,
204 tag: u32,
205 ) -> Result<(), T::Error> {
206 let tag = crate::implicit_tag(tag, T::TAG);
207 self.write_tlv(tag, val.data_length(), |dest| val.write_data(dest))
208 }
209}
210
211#[inline]
214pub fn write<E: From<WriteError>, F: Fn(&mut Writer<'_>) -> Result<(), E>>(
215 f: F,
216) -> Result<Vec<u8>, E> {
217 let mut v = WriteBuf::new(vec![]);
218 let mut w = Writer::new(&mut v);
219 f(&mut w)?;
220 Ok(v.0)
221}
222
223pub fn write_single<T: Asn1Writable>(v: &T) -> Result<Vec<u8>, T::Error> {
227 write(|w| w.write_element(v))
228}
229
230#[cfg(test)]
231mod tests {
232 #[cfg(not(feature = "std"))]
233 use alloc::boxed::Box;
234 #[cfg(not(feature = "std"))]
235 use alloc::vec;
236
237 use super::{_insert_at_position, write, write_single, WriteBuf, Writer};
238 use crate::types::{Asn1Writable, SimpleAsn1Writable};
239 use crate::{
240 parse_single, BMPString, BigInt, BigUint, BitString, Choice1, Choice2, Choice3, DateTime,
241 Enumerated, Explicit, GeneralizedTime, IA5String, Implicit, ObjectIdentifier,
242 OctetStringEncoded, OwnedBigInt, OwnedBigUint, OwnedBitString, PrintableString, Sequence,
243 SequenceOf, SequenceOfWriter, SequenceWriter, Set, SetElementWriter, SetOf, SetOfWriter,
244 SetWriter, Tag, Tlv, UniversalString, UtcTime, Utf8String, VisibleString, WriteError,
245 X509GeneralizedTime,
246 };
247 #[cfg(not(feature = "std"))]
248 use alloc::vec::Vec;
249
250 fn assert_writes<T>(data: &[(T, &[u8])])
251 where
252 T: Asn1Writable,
253 T::Error: core::fmt::Debug,
254 {
255 for (val, expected) in data {
256 let result = write_single(val).unwrap();
257 assert_eq!(&result, expected);
258 }
259 }
260
261 #[test]
262 fn test_insert_at_position() {
263 let mut v = WriteBuf::new(vec![1, 2, 3, 4]);
264 _insert_at_position(&mut v, 2, &[5, 6]).unwrap();
265 assert_eq!(v.as_slice(), &[1, 2, 5, 6, 3, 4]);
266 }
267
268 #[test]
269 fn test_write_error_eq() {
270 let e1 = WriteError::AllocationError;
271 let e2 = WriteError::AllocationError;
272
273 assert_eq!(e1, e2);
274 }
275
276 #[test]
277 fn test_write_element() {
278 assert_eq!(write(|w| w.write_element(&())).unwrap(), b"\x05\x00");
279 }
280
281 #[test]
282 fn test_write_null() {
283 assert_writes::<()>(&[((), b"\x05\x00")]);
284 }
285
286 #[test]
287 fn test_write_bool() {
288 assert_writes::<bool>(&[(false, b"\x01\x01\x00"), (true, b"\x01\x01\xff")]);
289 }
290
291 #[test]
292 fn test_write_octet_string() {
293 assert_writes::<&[u8]>(&[
294 (b"", b"\x04\x00"),
295 (b"\x01\x02\x03", b"\x04\x03\x01\x02\x03"),
296 (b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", b"\x04\x81\x81aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
297 (b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", b"\x04\x82\x01\x02aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
298 ]);
299
300 assert_writes::<[u8; 0]>(&[([], b"\x04\x00")]);
301 assert_writes::<[u8; 1]>(&[([1], b"\x04\x01\x01")]);
302 assert_writes::<[u8; 2]>(&[([2, 3], b"\x04\x02\x02\x03")]);
303 }
304
305 #[test]
306 fn test_write_octet_string_encoded() {
307 assert_writes::<OctetStringEncoded<bool>>(&[
308 (OctetStringEncoded::new(true), b"\x04\x03\x01\x01\xff"),
309 (OctetStringEncoded::new(false), b"\x04\x03\x01\x01\x00"),
310 ]);
311 }
312
313 #[test]
314 fn test_write_printable_string() {
315 assert_writes::<PrintableString<'_>>(&[
316 (
317 PrintableString::new("Test User 1").unwrap(),
318 b"\x13\x0bTest User 1",
319 ),
320 (
321 PrintableString::new("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").unwrap(),
322 b"\x13\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
323 ),
324 ]);
325 }
326
327 #[test]
328 fn test_write_ia5string() {
329 assert_writes::<IA5String<'_>>(&[
330 (
331 IA5String::new("Test User 1").unwrap(),
332 b"\x16\x0bTest User 1",
333 ),
334 (
335 IA5String::new("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").unwrap(),
336 b"\x16\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
337 ),
338 ]);
339 }
340
341 #[test]
342 fn test_write_utf8string() {
343 assert_writes::<Utf8String<'_>>(&[
344 (
345 Utf8String::new("Test User 1"),
346 b"\x0c\x0bTest User 1",
347 ),
348 (
349 Utf8String::new("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"),
350 b"\x0c\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
351 ),
352 ]);
353 }
354
355 #[test]
356 fn test_write_visiblestring() {
357 assert_writes::<VisibleString<'_>>(&[
358 (
359 VisibleString::new("Test User 1").unwrap(),
360 b"\x1a\x0bTest User 1",
361 ),
362 (
363 VisibleString::new("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").unwrap(),
364 b"\x1a\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
365 ),
366 ]);
367 }
368
369 #[test]
370 fn test_write_bmpstring() {
371 assert_writes::<BMPString<'_>>(&[(
372 BMPString::new(b"\x00a\x00b\x00c").unwrap(),
373 b"\x1e\x06\x00a\x00b\x00c",
374 )]);
375 }
376
377 #[test]
378 fn test_write_universalstring() {
379 assert_writes::<UniversalString<'_>>(&[(
380 UniversalString::new(b"\x00\x00\x00a\x00\x00\x00b\x00\x00\x00c").unwrap(),
381 b"\x1c\x0c\x00\x00\x00a\x00\x00\x00b\x00\x00\x00c",
382 )]);
383 }
384
385 #[test]
386 fn test_write_i64() {
387 assert_writes::<i64>(&[
388 (0, b"\x02\x01\x00"),
389 (127, b"\x02\x01\x7f"),
390 (128, b"\x02\x02\x00\x80"),
391 (255, b"\x02\x02\x00\xff"),
392 (256, b"\x02\x02\x01\x00"),
393 (-1, b"\x02\x01\xff"),
394 (-128, b"\x02\x01\x80"),
395 (-129, b"\x02\x02\xff\x7f"),
396 ]);
397 }
398
399 #[test]
400 fn test_write_u64() {
401 assert_writes::<u64>(&[(
402 12356915591483590945,
403 b"\x02\x09\x00\xab\x7c\x95\x42\xbd\xdd\x89\x21",
404 )]);
405 }
406
407 #[test]
408 fn test_write_i32() {
409 assert_writes::<i32>(&[
410 (0, b"\x02\x01\x00"),
411 (127, b"\x02\x01\x7f"),
412 (128, b"\x02\x02\x00\x80"),
413 (255, b"\x02\x02\x00\xff"),
414 (256, b"\x02\x02\x01\x00"),
415 (-1, b"\x02\x01\xff"),
416 (-128, b"\x02\x01\x80"),
417 (-129, b"\x02\x02\xff\x7f"),
418 ]);
419 }
420
421 #[test]
422 fn test_write_u16() {
423 assert_writes::<u16>(&[
424 (0, b"\x02\x01\x00"),
425 (1, b"\x02\x01\x01"),
426 (256, b"\x02\x02\x01\x00"),
427 (65535, b"\x02\x03\x00\xff\xff"),
428 ]);
429 }
430
431 #[test]
432 fn test_write_i16() {
433 assert_writes::<i16>(&[
434 (0, b"\x02\x01\x00"),
435 (1, b"\x02\x01\x01"),
436 (-256, b"\x02\x02\xff\x00"),
437 (-1, b"\x02\x01\xff"),
438 (-32768, b"\x02\x02\x80\x00"),
439 (32767, b"\x02\x02\x7f\xff"),
440 ]);
441 }
442
443 #[test]
444 fn test_write_nonzeroi8_like_underlying() {
445 use std::num::NonZeroI8;
446 for val in [1, -1, i8::MIN, i8::MAX] {
447 assert_eq!(
448 write_single::<i8>(&val).unwrap(),
449 write_single(&NonZeroI8::new(val).unwrap()).unwrap()
450 );
451 }
452 }
453
454 #[test]
455 fn test_write_nonzeroi16_like_underlying() {
456 use std::num::NonZeroI16;
457 for val in [1, -1, i16::MIN, i16::MAX] {
458 assert_eq!(
459 write_single::<i16>(&val).unwrap(),
460 write_single(&NonZeroI16::new(val).unwrap()).unwrap()
461 );
462 }
463 }
464
465 #[test]
466 fn test_write_nonzeroi32_like_underlying() {
467 use std::num::NonZeroI32;
468 for val in [1, -1, i32::MIN, i32::MAX] {
469 assert_eq!(
470 write_single::<i32>(&val).unwrap(),
471 write_single(&NonZeroI32::new(val).unwrap()).unwrap()
472 );
473 }
474 }
475
476 #[test]
477 fn test_write_nonzeroi64_like_underlying() {
478 use std::num::NonZeroI64;
479 for val in [1, -1, i64::MIN, i64::MAX] {
480 assert_eq!(
481 write_single::<i64>(&val).unwrap(),
482 write_single(&NonZeroI64::new(val).unwrap()).unwrap()
483 );
484 }
485 }
486
487 #[test]
488 fn test_write_nonzerou8_like_underlying() {
489 use std::num::NonZeroU8;
490 for val in [1, u8::MAX] {
491 assert_eq!(
492 write_single::<u8>(&val).unwrap(),
493 write_single(&NonZeroU8::new(val).unwrap()).unwrap()
494 );
495 }
496 }
497
498 #[test]
499 fn test_write_nonzerou16_like_underlying() {
500 use std::num::NonZeroU16;
501 for val in [1, u16::MAX] {
502 assert_eq!(
503 write_single::<u16>(&val).unwrap(),
504 write_single(&NonZeroU16::new(val).unwrap()).unwrap()
505 );
506 }
507 }
508
509 #[test]
510 fn test_write_nonzerou32_like_underlying() {
511 use std::num::NonZeroU32;
512 for val in [1, u32::MAX] {
513 assert_eq!(
514 write_single::<u32>(&val).unwrap(),
515 write_single(&NonZeroU32::new(val).unwrap()).unwrap()
516 );
517 }
518 }
519
520 #[test]
521 fn test_write_nonzerou64_like_underlying() {
522 use std::num::NonZeroU64;
523 for val in [1, u64::MAX] {
524 assert_eq!(
525 write_single::<u64>(&val).unwrap(),
526 write_single(&NonZeroU64::new(val).unwrap()).unwrap()
527 );
528 }
529 }
530
531 #[test]
532 fn test_write_u8() {
533 assert_writes::<u8>(&[
534 (0, b"\x02\x01\x00"),
535 (127, b"\x02\x01\x7f"),
536 (128, b"\x02\x02\x00\x80"),
537 ]);
538 }
539
540 #[test]
541 fn test_write_i8() {
542 assert_writes::<i8>(&[
543 (0, b"\x02\x01\x00"),
544 (127, b"\x02\x01\x7f"),
545 (-1, b"\x02\x01\xff"),
546 (-128, b"\x02\x01\x80"),
547 ]);
548 }
549
550 #[test]
551 fn test_write_biguint() {
552 assert_writes::<BigUint<'_>>(&[
553 (BigUint::new(b"\x00\xff").unwrap(), b"\x02\x02\x00\xff"),
554 (
555 BigUint::new(b"\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap(),
556 b"\x02\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
557 ),
558 ]);
559 }
560
561 #[test]
562 fn test_write_ownedbiguint() {
563 assert_writes::<OwnedBigUint>(&[
564 (
565 OwnedBigUint::new(b"\x00\xff".to_vec()).unwrap(),
566 b"\x02\x02\x00\xff",
567 ),
568 (
569 OwnedBigUint::new(b"\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff".to_vec())
570 .unwrap(),
571 b"\x02\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
572 ),
573 ]);
574 }
575
576 #[test]
577 fn test_write_bigint() {
578 assert_writes::<BigInt<'_>>(&[
579 (BigInt::new(b"\xff").unwrap(), b"\x02\x01\xff"),
580 (
581 BigInt::new(b"\xff\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap(),
582 b"\x02\x0c\xff\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
583 ),
584 ]);
585 }
586
587 #[test]
588 fn test_write_ownedbigint() {
589 assert_writes::<OwnedBigInt>(&[
590 (OwnedBigInt::new(b"\xff".to_vec()).unwrap(), b"\x02\x01\xff"),
591 (
592 OwnedBigInt::new(b"\xff\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff".to_vec())
593 .unwrap(),
594 b"\x02\x0c\xff\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
595 ),
596 ]);
597 }
598
599 #[test]
600 fn test_write_object_identifier() {
601 assert_writes::<ObjectIdentifier>(&[
602 (
603 ObjectIdentifier::from_string("1.2.840.113549").unwrap(),
604 b"\x06\x06\x2a\x86\x48\x86\xf7\x0d",
605 ),
606 (
607 ObjectIdentifier::from_string("1.2.3.4").unwrap(),
608 b"\x06\x03\x2a\x03\x04",
609 ),
610 (
611 ObjectIdentifier::from_string("1.2.840.133549.1.1.5").unwrap(),
612 b"\x06\x09\x2a\x86\x48\x88\x93\x2d\x01\x01\x05",
613 ),
614 (
615 ObjectIdentifier::from_string("2.100.3").unwrap(),
616 b"\x06\x03\x81\x34\x03",
617 ),
618 (
619 ObjectIdentifier::from_string("2.4.0").unwrap(),
620 b"\x06\x02\x54\x00",
621 ),
622 ]);
623 }
624
625 #[test]
626 fn test_write_bit_string() {
627 assert_writes::<BitString<'_>>(&[
628 (BitString::new(b"", 0).unwrap(), b"\x03\x01\x00"),
629 (BitString::new(b"\x80", 7).unwrap(), b"\x03\x02\x07\x80"),
630 (
631 BitString::new(b"\x81\xf0", 4).unwrap(),
632 b"\x03\x03\x04\x81\xf0",
633 ),
634 ]);
635
636 assert_writes::<OwnedBitString>(&[
637 (OwnedBitString::new(vec![], 0).unwrap(), b"\x03\x01\x00"),
638 (
639 OwnedBitString::new(vec![0x80], 7).unwrap(),
640 b"\x03\x02\x07\x80",
641 ),
642 (
643 OwnedBitString::new(vec![0x81, 0xf0], 4).unwrap(),
644 b"\x03\x03\x04\x81\xf0",
645 ),
646 ]);
647 }
648
649 #[test]
650 fn test_write_utctime() {
651 assert_writes::<UtcTime>(&[
652 (
653 UtcTime::new(DateTime::new(1991, 5, 6, 23, 45, 40).unwrap()).unwrap(),
654 b"\x17\x0d910506234540Z",
655 ),
656 (
657 UtcTime::new(DateTime::new(1970, 1, 1, 0, 0, 0).unwrap()).unwrap(),
658 b"\x17\x0d700101000000Z",
659 ),
660 (
661 UtcTime::new(DateTime::new(2009, 11, 15, 22, 56, 16).unwrap()).unwrap(),
662 b"\x17\x0d091115225616Z",
663 ),
664 ]);
665 }
666
667 #[test]
668 fn test_write_x509_generalizedtime() {
669 assert_writes(&[
670 (
671 X509GeneralizedTime::new(DateTime::new(1991, 5, 6, 23, 45, 40).unwrap()).unwrap(),
672 b"\x18\x0f19910506234540Z",
673 ),
674 (
675 X509GeneralizedTime::new(DateTime::new(1970, 1, 1, 0, 0, 0).unwrap()).unwrap(),
676 b"\x18\x0f19700101000000Z",
677 ),
678 (
679 X509GeneralizedTime::new(DateTime::new(2009, 11, 15, 22, 56, 16).unwrap()).unwrap(),
680 b"\x18\x0f20091115225616Z",
681 ),
682 ]);
683 }
684
685 #[test]
686 fn test_write_generalizedtime() {
687 assert_writes(&[
688 (
689 GeneralizedTime::new(DateTime::new(1991, 5, 6, 23, 45, 40).unwrap(), Some(1_234))
690 .unwrap(),
691 b"\x18\x1919910506234540.000001234Z",
692 ),
693 (
694 GeneralizedTime::new(DateTime::new(1991, 5, 6, 23, 45, 40).unwrap(), Some(1))
695 .unwrap(),
696 b"\x18\x1919910506234540.000000001Z",
697 ),
698 (
699 GeneralizedTime::new(DateTime::new(1970, 1, 1, 0, 0, 0).unwrap(), None).unwrap(),
700 b"\x18\x0f19700101000000Z",
701 ),
702 (
703 GeneralizedTime::new(
704 DateTime::new(2009, 11, 15, 22, 56, 16).unwrap(),
705 Some(100_000_000),
706 )
707 .unwrap(),
708 b"\x18\x1120091115225616.1Z",
709 ),
710 (
711 GeneralizedTime::new(
712 DateTime::new(2009, 11, 15, 22, 56, 16).unwrap(),
713 Some(999_999_999),
714 )
715 .unwrap(),
716 b"\x18\x1920091115225616.999999999Z",
717 ),
718 ]);
719 }
720
721 #[test]
722 fn test_write_enumerated() {
723 assert_writes::<Enumerated>(&[
724 (Enumerated::new(0), b"\x0a\x01\x00"),
725 (Enumerated::new(12), b"\x0a\x01\x0c"),
726 ]);
727 }
728
729 #[test]
730 fn test_write_sequence() {
731 assert_eq!(
732 write(|w| {
733 w.write_element(&SequenceWriter::new(&|w: &mut Writer<'_>| {
734 w.write_element(&())
735 }))
736 })
737 .unwrap(),
738 b"\x30\x02\x05\x00"
739 );
740 assert_eq!(
741 write(|w| {
742 w.write_element(&SequenceWriter::new(&|w: &mut Writer<'_>| {
743 w.write_element(&true)
744 }))
745 })
746 .unwrap(),
747 b"\x30\x03\x01\x01\xff"
748 );
749 assert_eq!(
750 write(|w| {
751 w.write_element(&SequenceWriter::new(&|w: &mut Writer<'_>| {
752 w.write_element(&b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
753 }))
754 }).unwrap(),
755 b"\x30\x81\x84\x04\x81\x81aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
756 );
757
758 assert_writes(&[(
759 parse_single::<Sequence<'_>>(b"\x30\x06\x01\x01\xff\x02\x01\x06").unwrap(),
760 b"\x30\x06\x01\x01\xff\x02\x01\x06",
761 )]);
762 }
763
764 #[test]
765 fn test_write_sequence_of() {
766 assert_writes::<SequenceOfWriter<'_, u8, &[u8]>>(&[
767 (SequenceOfWriter::new(&[]), b"\x30\x00"),
768 (
769 SequenceOfWriter::new(&[1u8, 2, 3]),
770 b"\x30\x09\x02\x01\x01\x02\x01\x02\x02\x01\x03",
771 ),
772 ]);
773 assert_writes::<SequenceOfWriter<'_, u8, Vec<u8>>>(&[
774 (SequenceOfWriter::new(vec![]), b"\x30\x00"),
775 (
776 SequenceOfWriter::new(vec![1u8, 2, 3]),
777 b"\x30\x09\x02\x01\x01\x02\x01\x02\x02\x01\x03",
778 ),
779 ]);
780 assert_writes::<SequenceOfWriter<'_, SequenceWriter<'_>, &[SequenceWriter<'_>]>>(&[
781 (SequenceOfWriter::new(&[]), b"\x30\x00"),
782 (
783 SequenceOfWriter::new(&[SequenceWriter::new(&|_w| Ok(()))]),
784 b"\x30\x02\x30\x00",
785 ),
786 (
787 SequenceOfWriter::new(&[SequenceWriter::new(&|w: &mut Writer<'_>| {
788 w.write_element(&1u64)
789 })]),
790 b"\x30\x05\x30\x03\x02\x01\x01",
791 ),
792 ]);
793
794 assert_writes(&[(
795 parse_single::<SequenceOf<'_, u64>>(b"\x30\x06\x02\x01\x05\x02\x01\x07").unwrap(),
796 b"\x30\x06\x02\x01\x05\x02\x01\x07",
797 )]);
798 }
799
800 #[test]
801 fn test_write_set() {
802 assert_eq!(
803 write(|w| {
804 w.write_element(&SetWriter::new(&|w: &mut SetElementWriter<'_>| {
805 w.write_element(&())
806 }))
807 })
808 .unwrap(),
809 b"\x31\x02\x05\x00"
810 );
811 assert_eq!(
812 write(|w| {
813 w.write_element(&SetWriter::new(&|w: &mut SetElementWriter<'_>| {
814 w.write_element(&true)
815 }))
816 })
817 .unwrap(),
818 b"\x31\x03\x01\x01\xff"
819 );
820 assert_eq!(
821 write(|w| {
822 w.write_element(&SetWriter::new(&|w: &mut SetElementWriter<'_>| {
823 w.write_element(&b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
824 }))
825 }).unwrap(),
826 b"\x31\x81\x84\x04\x81\x81aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
827 );
828
829 assert_writes(&[(
830 parse_single::<Set<'_>>(b"\x31\x06\x01\x01\xff\x02\x01\x06").unwrap(),
831 b"\x31\x06\x01\x01\xff\x02\x01\x06",
832 )]);
833
834 assert!(write(|w| {
835 w.write_element(&SetWriter::new(&|w: &mut SetElementWriter<'_>| {
836 w.write_element(&true)?; w.write_element(&1i64) }))
839 })
840 .is_ok());
841
842 assert_eq!(
843 write(|w| {
844 w.write_element(&SetWriter::new(&|w: &mut SetElementWriter<'_>| {
845 w.write_element(&1i64)?; w.write_element(&true) }))
848 }),
849 Err(WriteError::InvalidSetOrdering)
850 );
851
852 assert_eq!(
853 write(|w| {
854 w.write_element(&SetWriter::new(&|w: &mut SetElementWriter<'_>| {
855 w.write_element(&true)?;
856 w.write_element(&Some(1i64))
857 }))
858 })
859 .unwrap(),
860 b"\x31\x06\x01\x01\xff\x02\x01\x01"
861 );
862
863 assert_eq!(
864 write(|w| {
865 w.write_element(&SetWriter::new(&|w: &mut SetElementWriter<'_>| {
866 w.write_element(&true)?;
867 w.write_element(&Option::<i64>::None)
868 }))
869 })
870 .unwrap(),
871 b"\x31\x03\x01\x01\xff"
872 );
873 }
874
875 #[test]
876 fn test_write_set_of() {
877 assert_writes::<SetOfWriter<'_, u8, &[u8]>>(&[
878 (SetOfWriter::new(&[]), b"\x31\x00"),
879 (SetOfWriter::new(&[1u8]), b"\x31\x03\x02\x01\x01"),
880 (
881 SetOfWriter::new(&[1, 2, 3]),
882 b"\x31\x09\x02\x01\x01\x02\x01\x02\x02\x01\x03",
883 ),
884 (
885 SetOfWriter::new(&[3, 2, 1]),
886 b"\x31\x09\x02\x01\x01\x02\x01\x02\x02\x01\x03",
887 ),
888 ]);
889 assert_writes(&[
890 (SetOfWriter::new(vec![]), b"\x31\x00"),
891 (SetOfWriter::new(vec![1u8]), b"\x31\x03\x02\x01\x01"),
892 (
893 SetOfWriter::new(vec![1, 2, 3]),
894 b"\x31\x09\x02\x01\x01\x02\x01\x02\x02\x01\x03",
895 ),
896 (
897 SetOfWriter::new(vec![3, 2, 1]),
898 b"\x31\x09\x02\x01\x01\x02\x01\x02\x02\x01\x03",
899 ),
900 ]);
901
902 assert_writes(&[(
903 parse_single::<SetOf<'_, u64>>(b"\x31\x06\x02\x01\x05\x02\x01\x07").unwrap(),
904 b"\x31\x06\x02\x01\x05\x02\x01\x07",
905 )]);
906 }
907
908 #[test]
909 fn test_write_implicit() {
910 assert_writes::<Implicit<bool, 2>>(&[
911 (Implicit::new(true), b"\x82\x01\xff"),
912 (Implicit::new(false), b"\x82\x01\x00"),
913 ]);
914
915 assert_eq!(
916 write(|w| { w.write_implicit_element(&true, 2) }).unwrap(),
917 b"\x82\x01\xff"
918 );
919
920 assert_eq!(
921 write(|w| {
922 w.write_implicit_element(&SequenceWriter::new(&|_w| Ok::<_, WriteError>(())), 2)
923 })
924 .unwrap(),
925 b"\xa2\x00"
926 );
927 }
928
929 #[test]
930 fn test_write_explicit() {
931 assert_writes::<Explicit<bool, 2>>(&[
932 (Explicit::new(true), b"\xa2\x03\x01\x01\xff"),
933 (Explicit::new(false), b"\xa2\x03\x01\x01\x00"),
934 ]);
935
936 assert_eq!(
937 write(|w| { w.write_explicit_element(&true, 2) }).unwrap(),
938 b"\xa2\x03\x01\x01\xff"
939 );
940 }
941
942 #[test]
943 fn test_write_option() {
944 assert_writes::<Option<bool>>(&[
945 (Some(true), b"\x01\x01\xff"),
946 (Some(false), b"\x01\x01\x00"),
947 (None, b""),
948 ]);
949 }
950
951 #[test]
952 fn test_write_choice() {
953 assert_writes::<Choice1<bool>>(&[(Choice1::ChoiceA(true), b"\x01\x01\xff")]);
954
955 assert_writes::<Choice2<bool, i64>>(&[
956 (Choice2::ChoiceA(true), b"\x01\x01\xff"),
957 (Choice2::ChoiceB(18), b"\x02\x01\x12"),
958 ]);
959
960 assert_writes::<Choice3<bool, i64, ()>>(&[
961 (Choice3::ChoiceA(true), b"\x01\x01\xff"),
962 (Choice3::ChoiceB(18), b"\x02\x01\x12"),
963 (Choice3::ChoiceC(()), b"\x05\x00"),
964 ]);
965 }
966
967 #[test]
968 fn test_write_tlv() {
969 assert_writes(&[
970 (
971 parse_single::<Tlv<'_>>(b"\x01\x01\x00").unwrap(),
972 b"\x01\x01\x00",
973 ),
974 (
975 parse_single::<Tlv<'_>>(b"\x1f\x81\x80\x01\x00").unwrap(),
976 b"\x1f\x81\x80\x01\x00",
977 ),
978 (
979 parse_single::<Tlv<'_>>(b"\x1f\x1f\x00").unwrap(),
980 b"\x1f\x1f\x00",
981 ),
982 ]);
983 }
984
985 #[test]
986 fn test_write_box() {
987 assert_writes(&[
988 (Box::new(12u8), b"\x02\x01\x0c"),
989 (Box::new(0), b"\x02\x01\x00"),
990 ]);
991 }
992
993 #[test]
994 fn test_write_error_display() {
995 use alloc::string::ToString;
996 assert_eq!(&WriteError::AllocationError.to_string(), "allocation error");
997 assert_eq!(
998 &WriteError::InvalidSetOrdering.to_string(),
999 "SET elements are not in DER order"
1000 );
1001 }
1002
1003 #[test]
1004 fn test_custom_write_error() {
1005 #[derive(Debug, PartialEq, Eq)]
1006 enum CustomError {
1007 Write(WriteError),
1008 Custom,
1009 }
1010
1011 impl From<WriteError> for CustomError {
1012 fn from(e: WriteError) -> Self {
1013 CustomError::Write(e)
1014 }
1015 }
1016
1017 struct FailingWriter;
1018
1019 impl SimpleAsn1Writable for FailingWriter {
1020 type Error = CustomError;
1021 const TAG: Tag = Tag::primitive(0x04);
1022
1023 fn write_data(&self, _dest: &mut WriteBuf) -> Result<(), CustomError> {
1024 Err(CustomError::Custom)
1025 }
1026
1027 fn data_length(&self) -> Option<usize> {
1028 Some(0)
1029 }
1030 }
1031
1032 let result = write_single(&FailingWriter);
1033 assert_eq!(result, Err(CustomError::Custom));
1034
1035 assert_eq!(
1036 CustomError::from(WriteError::AllocationError),
1037 CustomError::Write(WriteError::AllocationError)
1038 );
1039 }
1040}