1pub use num_bigint::{BigInt, BigUint};
30use num_traits::{FromPrimitive, One, ToPrimitive, Zero};
31#[cfg(test)]
32use quickcheck::quickcheck;
33use std::convert::TryFrom;
34use std::iter::FromIterator;
35use std::mem::size_of;
36use std::str::Utf8Error;
37use thiserror::Error;
38use time::PrimitiveDateTime;
39
40#[derive(Clone, Copy, Debug, PartialEq)]
45pub enum ASN1Class {
46 Universal,
47 Application,
48 ContextSpecific,
49 Private,
50}
51
52#[derive(Clone, Debug)]
70pub enum ASN1Block {
71 Boolean(usize, bool),
72 Integer(usize, BigInt),
73 BitString(usize, usize, Vec<u8>),
74 OctetString(usize, Vec<u8>),
75 Null(usize),
76 ObjectIdentifier(usize, OID),
77 UTF8String(usize, String),
78 PrintableString(usize, String),
79 TeletexString(usize, String),
80 IA5String(usize, String),
81 UTCTime(usize, PrimitiveDateTime),
82 GeneralizedTime(usize, PrimitiveDateTime),
83 UniversalString(usize, String),
84 BMPString(usize, String),
85 Sequence(usize, Vec<ASN1Block>),
86 Set(usize, Vec<ASN1Block>),
87 Explicit(ASN1Class, usize, BigUint, Box<ASN1Block>),
94 Unknown(ASN1Class, bool, usize, BigUint, Vec<u8>),
99}
100
101impl ASN1Block {
102 pub fn class(&self) -> ASN1Class {
105 match *self {
106 ASN1Block::Boolean(_, _) => ASN1Class::Universal,
107 ASN1Block::Integer(_, _) => ASN1Class::Universal,
108 ASN1Block::BitString(_, _, _) => ASN1Class::Universal,
109 ASN1Block::OctetString(_, _) => ASN1Class::Universal,
110 ASN1Block::Null(_) => ASN1Class::Universal,
111 ASN1Block::ObjectIdentifier(_, _) => ASN1Class::Universal,
112 ASN1Block::UTF8String(_, _) => ASN1Class::Universal,
113 ASN1Block::PrintableString(_, _) => ASN1Class::Universal,
114 ASN1Block::TeletexString(_, _) => ASN1Class::Universal,
115 ASN1Block::IA5String(_, _) => ASN1Class::Universal,
116 ASN1Block::UTCTime(_, _) => ASN1Class::Universal,
117 ASN1Block::GeneralizedTime(_, _) => ASN1Class::Universal,
118 ASN1Block::UniversalString(_, _) => ASN1Class::Universal,
119 ASN1Block::BMPString(_, _) => ASN1Class::Universal,
120 ASN1Block::Sequence(_, _) => ASN1Class::Universal,
121 ASN1Block::Set(_, _) => ASN1Class::Universal,
122 ASN1Block::Explicit(c, _, _, _) => c,
123 ASN1Block::Unknown(c, _, _, _, _) => c,
124 }
125 }
126 pub fn offset(&self) -> usize {
129 match *self {
130 ASN1Block::Boolean(o, _) => o,
131 ASN1Block::Integer(o, _) => o,
132 ASN1Block::BitString(o, _, _) => o,
133 ASN1Block::OctetString(o, _) => o,
134 ASN1Block::Null(o) => o,
135 ASN1Block::ObjectIdentifier(o, _) => o,
136 ASN1Block::UTF8String(o, _) => o,
137 ASN1Block::PrintableString(o, _) => o,
138 ASN1Block::TeletexString(o, _) => o,
139 ASN1Block::IA5String(o, _) => o,
140 ASN1Block::UTCTime(o, _) => o,
141 ASN1Block::GeneralizedTime(o, _) => o,
142 ASN1Block::UniversalString(o, _) => o,
143 ASN1Block::BMPString(o, _) => o,
144 ASN1Block::Sequence(o, _) => o,
145 ASN1Block::Set(o, _) => o,
146 ASN1Block::Explicit(_, o, _, _) => o,
147 ASN1Block::Unknown(_, _, o, _, _) => o,
148 }
149 }
150}
151
152impl PartialEq for ASN1Block {
153 fn eq(&self, other: &ASN1Block) -> bool {
154 match (self, other) {
155 (&ASN1Block::Boolean(_, a1), &ASN1Block::Boolean(_, a2)) => (a1 == a2),
156 (&ASN1Block::Integer(_, ref a1), &ASN1Block::Integer(_, ref a2)) => (a1 == a2),
157 (&ASN1Block::BitString(_, a1, ref b1), &ASN1Block::BitString(_, a2, ref b2)) => {
158 (a1 == a2) && (b1 == b2)
159 }
160 (&ASN1Block::OctetString(_, ref a1), &ASN1Block::OctetString(_, ref a2)) => (a1 == a2),
161 (&ASN1Block::Null(_), &ASN1Block::Null(_)) => true,
162 (&ASN1Block::ObjectIdentifier(_, ref a1), &ASN1Block::ObjectIdentifier(_, ref a2)) => {
163 a1 == a2
164 }
165 (&ASN1Block::UTF8String(_, ref a1), &ASN1Block::UTF8String(_, ref a2)) => (a1 == a2),
166 (&ASN1Block::PrintableString(_, ref a1), &ASN1Block::PrintableString(_, ref a2)) => {
167 a1 == a2
168 }
169 (&ASN1Block::TeletexString(_, ref a1), &ASN1Block::TeletexString(_, ref a2)) => {
170 a1 == a2
171 }
172 (&ASN1Block::IA5String(_, ref a1), &ASN1Block::IA5String(_, ref a2)) => (a1 == a2),
173 (&ASN1Block::UTCTime(_, ref a1), &ASN1Block::UTCTime(_, ref a2)) => (a1 == a2),
174 (&ASN1Block::GeneralizedTime(_, ref a1), &ASN1Block::GeneralizedTime(_, ref a2)) => {
175 a1 == a2
176 }
177 (&ASN1Block::UniversalString(_, ref a1), &ASN1Block::UniversalString(_, ref a2)) => {
178 a1 == a2
179 }
180 (&ASN1Block::BMPString(_, ref a1), &ASN1Block::BMPString(_, ref a2)) => (a1 == a2),
181 (&ASN1Block::Sequence(_, ref a1), &ASN1Block::Sequence(_, ref a2)) => (a1 == a2),
182 (&ASN1Block::Set(_, ref a1), &ASN1Block::Set(_, ref a2)) => (a1 == a2),
183 (
184 &ASN1Block::Explicit(a1, _, ref b1, ref c1),
185 &ASN1Block::Explicit(a2, _, ref b2, ref c2),
186 ) => (a1 == a2) && (b1 == b2) && (c1 == c2),
187 (
188 &ASN1Block::Unknown(a1, b1, _, ref c1, ref d1),
189 &ASN1Block::Unknown(a2, b2, _, ref c2, ref d2),
190 ) => (a1 == a2) && (b1 == b2) && (c1 == c2) && (d1 == d2),
191 _ => false,
192 }
193 }
194}
195
196#[derive(Clone, Debug, PartialEq, Eq)]
198pub struct OID(Vec<BigUint>);
199
200impl OID {
201 pub fn new(x: Vec<BigUint>) -> OID {
204 OID(x)
205 }
206
207 pub fn as_raw(&self) -> Result<Vec<u8>, ASN1EncodeErr> {
209 match (self.0.get(0), self.0.get(1)) {
210 (Some(v1), Some(v2)) => {
211 let two = BigUint::from_u8(2).unwrap();
212
213 if v1 > &two {
215 return Err(ASN1EncodeErr::ObjectIdentVal1TooLarge);
216 }
217
218 let u175 = BigUint::from_u8(175).unwrap();
219 let u39 = BigUint::from_u8(39).unwrap();
220 let bound = if v1 == &two { u175 } else { u39 };
221
222 if v2 > &bound {
223 return Err(ASN1EncodeErr::ObjectIdentVal2TooLarge);
224 }
225
226 let value1 = v1.to_u8().unwrap();
229 let value2 = v2.to_u8().unwrap();
230 let byte1 = (value1 * 40) + value2;
231
232 let mut body = vec![byte1];
234 for num in self.0.iter().skip(2) {
235 let mut local = encode_base127(num);
236 body.append(&mut local);
237 }
238
239 Ok(body)
240 }
241 _ => Err(ASN1EncodeErr::ObjectIdentHasTooFewFields),
242 }
243 }
244
245 pub fn as_vec<'a, T: TryFrom<&'a BigUint>>(&'a self) -> Result<Vec<T>, ASN1DecodeErr> {
246 let mut vec = Vec::new();
247 for val in self.0.iter() {
248 let ul = match T::try_from(val) {
249 Ok(a) => a,
250 Err(_) => return Err(ASN1DecodeErr::Overflow),
251 };
252 vec.push(ul);
253 }
254
255 Ok(vec)
256 }
257}
258
259impl<'a> PartialEq<OID> for &'a OID {
260 fn eq(&self, v2: &OID) -> bool {
261 let &&OID(ref vec1) = self;
262 let &OID(ref vec2) = v2;
263
264 if vec1.len() != vec2.len() {
265 return false;
266 }
267
268 for i in 0..vec1.len() {
269 if vec1[i] != vec2[i] {
270 return false;
271 }
272 }
273
274 true
275 }
276}
277
278#[macro_export]
283macro_rules! oid {
284 ( $( $e: expr ),* ) => {{
285 let mut res = Vec::new();
286
287 $(
288 res.push($crate::BigUint::from($e as u64));
289 )*
290 $crate::OID::new(res)
291 }};
292}
293
294const PRINTABLE_CHARS: &str =
295 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'()+,-./:=? ";
296
297#[cfg(test)]
298const KNOWN_TAGS: &[u8] = &[
299 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x0c, 0x10, 0x11, 0x13, 0x14, 0x16, 0x17, 0x18, 0x1c, 0x1e,
300];
301
302#[derive(Clone, Debug, Error, PartialEq)]
304pub enum ASN1DecodeErr {
305 #[error("Encountered an empty buffer decoding ASN1 block.")]
306 EmptyBuffer,
307 #[error("Bad length field in boolean block: {0}")]
308 BadBooleanLength(usize),
309 #[error("Length field too large for object type: {0}")]
310 LengthTooLarge(usize),
311 #[error("UTF8 string failed to properly decode: {0}")]
312 UTF8DecodeFailure(Utf8Error),
313 #[error("Printable string failed to properly decode.")]
314 PrintableStringDecodeFailure,
315 #[error("Invalid date value: {0}")]
316 InvalidDateValue(String),
317 #[error("Invalid length of bit string: {0}")]
318 InvalidBitStringLength(isize),
319 #[error("Invalid class value: {0}")]
321 InvalidClass(u8),
322 #[error("Incomplete data or invalid ASN1")]
326 Incomplete,
327 #[error("Value overflow")]
328 Overflow,
329}
330
331#[derive(Clone, Debug, Error, PartialEq)]
333pub enum ASN1EncodeErr {
334 #[error("ASN1 object identifier has too few fields.")]
335 ObjectIdentHasTooFewFields,
336 #[error("First value in ASN1 OID is too big.")]
337 ObjectIdentVal1TooLarge,
338 #[error("Second value in ASN1 OID is too big.")]
339 ObjectIdentVal2TooLarge,
340}
341
342pub fn from_der(i: &[u8]) -> Result<Vec<ASN1Block>, ASN1DecodeErr> {
345 from_der_(i, 0)
346}
347
348fn from_der_(i: &[u8], start_offset: usize) -> Result<Vec<ASN1Block>, ASN1DecodeErr> {
349 let mut result: Vec<ASN1Block> = Vec::new();
350 let mut index: usize = 0;
351 let len = i.len();
352
353 while index < len {
354 let soff = start_offset + index;
355 let (tag, constructed, class) = decode_tag(i, &mut index)?;
356 let len = decode_length(i, &mut index)?;
357 let checklen = index
358 .checked_add(len)
359 .ok_or(ASN1DecodeErr::LengthTooLarge(len))?;
360 if checklen > i.len() {
361 return Err(ASN1DecodeErr::Incomplete);
362 }
363 let body = &i[index..(index + len)];
364
365 if class != ASN1Class::Universal {
366 if constructed {
367 if let Ok(mut items) = from_der_(body, start_offset + index) {
369 if items.len() == 1 {
370 result.push(ASN1Block::Explicit(
371 class,
372 soff,
373 tag,
374 Box::new(items.remove(0)),
375 ));
376 index += len;
377 continue;
378 }
379 }
380 }
381 result.push(ASN1Block::Unknown(
382 class,
383 constructed,
384 soff,
385 tag,
386 body.to_vec(),
387 ));
388 index += len;
389 continue;
390 }
391
392 match tag.to_u8() {
394 Some(0x01) => {
396 if len != 1 {
397 return Err(ASN1DecodeErr::BadBooleanLength(len));
398 }
399 result.push(ASN1Block::Boolean(soff, body[0] != 0));
400 }
401 Some(0x02) => {
403 let res = BigInt::from_signed_bytes_be(body);
404 result.push(ASN1Block::Integer(soff, res));
405 }
406 Some(0x03) if body.is_empty() => result.push(ASN1Block::BitString(soff, 0, Vec::new())),
408 Some(0x03) => {
409 let bits = (&body[1..]).to_vec();
410 let bitcount = bits.len() * 8;
411 let rest = body[0] as usize;
412 if bitcount < rest {
413 return Err(ASN1DecodeErr::InvalidBitStringLength(
414 bitcount as isize - rest as isize,
415 ));
416 }
417
418 let nbits = bitcount - (body[0] as usize);
419 result.push(ASN1Block::BitString(soff, nbits, bits))
420 }
421 Some(0x04) => result.push(ASN1Block::OctetString(soff, body.to_vec())),
423 Some(0x05) => {
425 result.push(ASN1Block::Null(soff));
426 }
427 Some(0x06) => {
429 let mut value1 = BigUint::zero();
430 if body.is_empty() {
431 return Err(ASN1DecodeErr::Incomplete);
432 }
433 let mut value2 = BigUint::from_u8(body[0]).unwrap();
434 let mut oidres = Vec::new();
435 let mut bindex = 1;
436
437 if body[0] >= 40 {
438 if body[0] < 80 {
439 value1 = BigUint::one();
440 value2 -= BigUint::from_u8(40).unwrap();
441 } else {
442 value1 = BigUint::from_u8(2).unwrap();
443 value2 -= BigUint::from_u8(80).unwrap();
444 }
445 }
446
447 oidres.push(value1);
448 oidres.push(value2);
449 while bindex < body.len() {
450 oidres.push(decode_base127(body, &mut bindex)?);
451 }
452 let res = OID(oidres);
453
454 result.push(ASN1Block::ObjectIdentifier(soff, res))
455 }
456 Some(0x0C) => match String::from_utf8(body.to_vec()) {
458 Ok(v) => result.push(ASN1Block::UTF8String(soff, v)),
459 Err(e) => return Err(ASN1DecodeErr::UTF8DecodeFailure(e.utf8_error())),
460 },
461 Some(0x10) => match from_der_(body, start_offset + index) {
463 Ok(items) => result.push(ASN1Block::Sequence(soff, items)),
464 Err(e) => return Err(e),
465 },
466 Some(0x11) => match from_der_(body, start_offset + index) {
468 Ok(items) => result.push(ASN1Block::Set(soff, items)),
469 Err(e) => return Err(e),
470 },
471 Some(0x13) => {
473 let mut res = String::new();
474 let val = body.iter().map(|x| *x as char);
475
476 for c in val {
477 if PRINTABLE_CHARS.contains(c) {
478 res.push(c);
479 } else {
480 return Err(ASN1DecodeErr::PrintableStringDecodeFailure);
481 }
482 }
483 result.push(ASN1Block::PrintableString(soff, res));
484 }
485 Some(0x14) => match String::from_utf8(body.to_vec()) {
487 Ok(v) => result.push(ASN1Block::TeletexString(soff, v)),
488 Err(e) => return Err(ASN1DecodeErr::UTF8DecodeFailure(e.utf8_error())),
489 },
490 Some(0x16) => {
492 let val = body.iter().map(|x| *x as char);
493 let res = String::from_iter(val);
494 result.push(ASN1Block::IA5String(soff, res))
495 }
496 Some(0x17) => {
498 if body.len() != 13 {
499 return Err(ASN1DecodeErr::InvalidDateValue(format!("{}", body.len())));
500 }
501
502 let v = String::from_iter(body.iter().map(|x| *x as char));
503
504 let y = match v.get(0..2) {
505 Some(yy) => yy,
506 None => {
507 return Err(ASN1DecodeErr::InvalidDateValue(v));
509 }
510 };
511
512 let y_prefix = match y.parse::<u8>() {
513 Err(_) => return Err(ASN1DecodeErr::InvalidDateValue(v)),
514 Ok(y) => {
515 if y >= 50 {
516 "19"
517 } else {
518 "20"
519 }
520 }
521 };
522
523 let v = format!("{}{}", y_prefix, v);
524
525 let format = time::format_description::parse(
526 "[year][month][day][hour repr:24][minute][second]Z",
527 )
528 .unwrap();
529
530 match PrimitiveDateTime::parse(&v, &format) {
531 Err(_) => return Err(ASN1DecodeErr::InvalidDateValue(v)),
532 Ok(t) => result.push(ASN1Block::UTCTime(soff, t)),
533 }
534 }
535 Some(0x18) => {
537 if body.len() < 15 {
538 return Err(ASN1DecodeErr::InvalidDateValue(format!("{}", body.len())));
539 }
540
541 let mut v: String = String::from_utf8(body.to_vec())
542 .map_err(|e| ASN1DecodeErr::UTF8DecodeFailure(e.utf8_error()))?;
543 if !v.is_ascii() {
546 return Err(ASN1DecodeErr::InvalidDateValue(v));
547 }
548
549 if !v.contains('.') {
551 v.insert(14, '.')
552 }
553 while v.len() < 25 {
554 let idx = v.len() - 1;
555 v.insert(idx, '0');
556 }
557
558 let format = time::format_description::parse(
559 "[year][month][day][hour repr:24][minute][second].[subsecond]Z",
560 )
561 .unwrap();
562
563 match PrimitiveDateTime::parse(&v, &format) {
564 Err(_) => return Err(ASN1DecodeErr::InvalidDateValue(v)),
565 Ok(t) => result.push(ASN1Block::GeneralizedTime(soff, t)),
566 }
567 }
568 Some(0x1C) => match String::from_utf8(body.to_vec()) {
570 Ok(v) => result.push(ASN1Block::UniversalString(soff, v)),
571 Err(e) => return Err(ASN1DecodeErr::UTF8DecodeFailure(e.utf8_error())),
572 },
573 Some(0x1E) => match String::from_utf8(body.to_vec()) {
575 Ok(v) => result.push(ASN1Block::BMPString(soff, v)),
576 Err(e) => return Err(ASN1DecodeErr::UTF8DecodeFailure(e.utf8_error())),
577 },
578 _ => {
580 result.push(ASN1Block::Unknown(
581 class,
582 constructed,
583 soff,
584 tag,
585 body.to_vec(),
586 ));
587 }
588 }
589 index += len;
590 }
591
592 if result.is_empty() {
593 Err(ASN1DecodeErr::EmptyBuffer)
594 } else {
595 Ok(result)
596 }
597}
598
599fn decode_tag(i: &[u8], index: &mut usize) -> Result<(BigUint, bool, ASN1Class), ASN1DecodeErr> {
601 if *index >= i.len() {
602 return Err(ASN1DecodeErr::Incomplete);
603 }
604 let tagbyte = i[*index];
605 let constructed = (tagbyte & 0b0010_0000) != 0;
606 let class = decode_class(tagbyte)?;
607 let basetag = tagbyte & 0b1_1111;
608
609 *index += 1;
610
611 if basetag == 0b1_1111 {
612 let res = decode_base127(i, index)?;
613 Ok((res, constructed, class))
614 } else {
615 Ok((BigUint::from(basetag), constructed, class))
616 }
617}
618
619fn decode_base127(i: &[u8], index: &mut usize) -> Result<BigUint, ASN1DecodeErr> {
620 let mut res = BigUint::zero();
621
622 loop {
623 if *index >= i.len() {
624 return Err(ASN1DecodeErr::Incomplete);
625 }
626
627 let nextbyte = i[*index];
628
629 *index += 1;
630 res = (res << 7) + BigUint::from(nextbyte & 0x7f);
631 if (nextbyte & 0x80) == 0 {
632 return Ok(res);
633 }
634 }
635}
636
637fn decode_class(i: u8) -> Result<ASN1Class, ASN1DecodeErr> {
638 match i >> 6 {
639 0b00 => Ok(ASN1Class::Universal),
640 0b01 => Ok(ASN1Class::Application),
641 0b10 => Ok(ASN1Class::ContextSpecific),
642 0b11 => Ok(ASN1Class::Private),
643 _ => Err(ASN1DecodeErr::InvalidClass(i)),
644 }
645}
646
647fn decode_length(i: &[u8], index: &mut usize) -> Result<usize, ASN1DecodeErr> {
648 if *index >= i.len() {
649 return Err(ASN1DecodeErr::Incomplete);
650 }
651 let startbyte = i[*index];
652
653 *index += 1;
658 if startbyte >= 0x80 {
659 let mut lenlen = (startbyte & 0x7f) as usize;
660 let mut res = 0;
661
662 if lenlen > size_of::<usize>() {
663 return Err(ASN1DecodeErr::LengthTooLarge(lenlen));
664 }
665
666 while lenlen > 0 {
667 if *index >= i.len() {
668 return Err(ASN1DecodeErr::Incomplete);
669 }
670
671 res = (res << 8) + (i[*index] as usize);
672
673 *index += 1;
674 lenlen -= 1;
675 }
676
677 Ok(res)
678 } else {
679 Ok(startbyte as usize)
680 }
681}
682
683pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>, ASN1EncodeErr> {
686 match *i {
687 ASN1Block::Boolean(_, val) => {
689 let inttag = BigUint::one();
690 let mut tagbytes = encode_tag(ASN1Class::Universal, false, &inttag);
691 tagbytes.push(1);
692 tagbytes.push(if val { 0xFF } else { 0x00 });
693 Ok(tagbytes)
694 }
695 ASN1Block::Integer(_, ref int) => {
697 let mut base = int.to_signed_bytes_be();
698 let mut lenbytes = encode_len(base.len());
699 let inttag = BigUint::from_u8(0x02).unwrap();
700 let mut tagbytes = encode_tag(ASN1Class::Universal, false, &inttag);
701
702 let mut result = Vec::new();
703 result.append(&mut tagbytes);
704 result.append(&mut lenbytes);
705 result.append(&mut base);
706 Ok(result)
707 }
708 ASN1Block::BitString(_, bits, ref vs) => {
710 let inttag = BigUint::from_u8(0x03).unwrap();
711 let mut tagbytes = encode_tag(ASN1Class::Universal, false, &inttag);
712
713 if bits == 0 {
714 tagbytes.push(0);
715 Ok(tagbytes)
716 } else {
717 let mut lenbytes = encode_len(vs.len() + 1);
718 let nbits = (vs.len() * 8) - bits;
719
720 let mut result = Vec::new();
721 result.append(&mut tagbytes);
722 result.append(&mut lenbytes);
723 result.push(nbits as u8);
724 result.extend_from_slice(vs);
725 Ok(result)
726 }
727 }
728 ASN1Block::OctetString(_, ref bytes) => {
730 let inttag = BigUint::from_u8(0x04).unwrap();
731 let mut tagbytes = encode_tag(ASN1Class::Universal, false, &inttag);
732 let mut lenbytes = encode_len(bytes.len());
733
734 let mut result = Vec::new();
735 result.append(&mut tagbytes);
736 result.append(&mut lenbytes);
737 result.extend_from_slice(bytes);
738 Ok(result)
739 }
740 ASN1Block::Null(_) => {
742 let inttag = BigUint::from_u8(0x05).unwrap();
743 let mut result = encode_tag(ASN1Class::Universal, false, &inttag);
744 result.push(0);
745 Ok(result)
746 }
747 ASN1Block::ObjectIdentifier(_, OID(ref nums)) => {
749 match (nums.get(0), nums.get(1)) {
750 (Some(v1), Some(v2)) => {
751 let two = BigUint::from_u8(2).unwrap();
752
753 if v1 > &two {
755 return Err(ASN1EncodeErr::ObjectIdentVal1TooLarge);
756 }
757
758 let u175 = BigUint::from_u8(175).unwrap();
759 let u39 = BigUint::from_u8(39).unwrap();
760 let bound = if v1 == &two { u175 } else { u39 };
761
762 if v2 > &bound {
763 return Err(ASN1EncodeErr::ObjectIdentVal2TooLarge);
764 }
765
766 let value1 = v1.to_u8().unwrap();
769 let value2 = v2.to_u8().unwrap();
770 let byte1 = (value1 * 40) + value2;
771
772 let mut body = vec![byte1];
774 for num in nums.iter().skip(2) {
775 let mut local = encode_base127(num);
776 body.append(&mut local);
777 }
778
779 let inttag = BigUint::from_u8(0x06).unwrap();
781 let mut result = encode_tag(ASN1Class::Universal, false, &inttag);
782 let mut lenbytes = encode_len(body.len());
783
784 result.append(&mut lenbytes);
785 result.append(&mut body);
786
787 Ok(result)
788 }
789 _ => Err(ASN1EncodeErr::ObjectIdentHasTooFewFields),
790 }
791 }
792 ASN1Block::Sequence(_, ref items) => {
794 let mut body = Vec::new();
795
796 for x in items.iter() {
798 let mut bytes = to_der(x)?;
799 body.append(&mut bytes);
800 }
801
802 let inttag = BigUint::from_u8(0x10).unwrap();
803 let mut lenbytes = encode_len(body.len());
804 let mut tagbytes = encode_tag(ASN1Class::Universal, true, &inttag);
807
808 let mut res = Vec::new();
809 res.append(&mut tagbytes);
810 res.append(&mut lenbytes);
811 res.append(&mut body);
812 Ok(res)
813 }
814 ASN1Block::Set(_, ref items) => {
816 let mut body = Vec::new();
817
818 for x in items.iter() {
820 let mut bytes = to_der(x)?;
821 body.append(&mut bytes);
822 }
823
824 let inttag = BigUint::from_u8(0x11).unwrap();
825 let mut lenbytes = encode_len(body.len());
826 let mut tagbytes = encode_tag(ASN1Class::Universal, true, &inttag);
829
830 let mut res = Vec::new();
831 res.append(&mut tagbytes);
832 res.append(&mut lenbytes);
833 res.append(&mut body);
834 Ok(res)
835 }
836 ASN1Block::UTCTime(_, ref time) => {
837 let format = time::format_description::parse(
838 "[year][month][day][hour repr:24][minute][second]Z",
839 )
840 .unwrap();
841 let mut body = time.format(&format).unwrap().into_bytes();
842 body.drain(0..2);
843 let inttag = BigUint::from_u8(0x17).unwrap();
844 let mut lenbytes = encode_len(body.len());
845 let mut tagbytes = encode_tag(ASN1Class::Universal, false, &inttag);
846
847 let mut res = Vec::new();
848 res.append(&mut tagbytes);
849 res.append(&mut lenbytes);
850 res.append(&mut body);
851 Ok(res)
852 }
853 ASN1Block::GeneralizedTime(_, ref time) => {
854 let format = time::format_description::parse(
855 "[year][month][day][hour repr:24][minute][second].[subsecond]",
856 )
857 .unwrap();
858 let base = time.format(&format).unwrap();
859 let zclear = base.trim_end_matches('0');
860 let dclear = zclear.trim_end_matches('.');
861 let mut body = format!("{}Z", dclear).into_bytes();
862
863 let inttag = BigUint::from_u8(0x18).unwrap();
864 let mut lenbytes = encode_len(body.len());
865 let mut tagbytes = encode_tag(ASN1Class::Universal, false, &inttag);
866
867 let mut res = Vec::new();
868 res.append(&mut tagbytes);
869 res.append(&mut lenbytes);
870 res.append(&mut body);
871 Ok(res)
872 }
873 ASN1Block::UTF8String(_, ref str) => {
874 encode_asn1_string(0x0c, false, ASN1Class::Universal, str)
875 }
876 ASN1Block::PrintableString(_, ref str) => {
877 encode_asn1_string(0x13, true, ASN1Class::Universal, str)
878 }
879 ASN1Block::TeletexString(_, ref str) => {
880 encode_asn1_string(0x14, false, ASN1Class::Universal, str)
881 }
882 ASN1Block::UniversalString(_, ref str) => {
883 encode_asn1_string(0x1c, false, ASN1Class::Universal, str)
884 }
885 ASN1Block::IA5String(_, ref str) => {
886 encode_asn1_string(0x16, true, ASN1Class::Universal, str)
887 }
888 ASN1Block::BMPString(_, ref str) => {
889 encode_asn1_string(0x1e, false, ASN1Class::Universal, str)
890 }
891 ASN1Block::Explicit(class, _, ref tag, ref item) => {
892 let mut tagbytes = encode_tag(class, true, tag);
893 let mut bytes = to_der(item)?;
894 let mut lenbytes = encode_len(bytes.len());
895
896 let mut res = Vec::new();
897 res.append(&mut tagbytes);
898 res.append(&mut lenbytes);
899 res.append(&mut bytes);
900 Ok(res)
901 }
902 ASN1Block::Unknown(class, c, _, ref tag, ref bytes) => {
904 let mut tagbytes = encode_tag(class, c, tag);
905 let mut lenbytes = encode_len(bytes.len());
906
907 let mut res = Vec::new();
908 res.append(&mut tagbytes);
909 res.append(&mut lenbytes);
910 res.extend_from_slice(bytes);
911 Ok(res)
912 }
913 }
914}
915
916fn encode_asn1_string(
917 tag: u8,
918 force_chars: bool,
919 c: ASN1Class,
920 s: &str,
921) -> Result<Vec<u8>, ASN1EncodeErr> {
922 let mut body = {
923 if force_chars {
924 let mut out = Vec::new();
925
926 for c in s.chars() {
927 out.push(c as u8);
928 }
929 out
930 } else {
931 s.to_string().into_bytes()
932 }
933 };
934 let inttag = BigUint::from_u8(tag).unwrap();
935 let mut lenbytes = encode_len(body.len());
936 let mut tagbytes = encode_tag(c, false, &inttag);
937
938 let mut res = Vec::new();
939 res.append(&mut tagbytes);
940 res.append(&mut lenbytes);
941 res.append(&mut body);
942 Ok(res)
943}
944
945fn encode_tag(c: ASN1Class, constructed: bool, t: &BigUint) -> Vec<u8> {
946 let cbyte = encode_class(c);
947
948 match t.to_u8() {
949 Some(mut x) if x < 31 => {
950 if constructed {
951 x |= 0b0010_0000;
952 }
953 vec![cbyte | x]
954 }
955 _ => {
956 let mut res = encode_base127(t);
957 let mut x = cbyte | 0b0001_1111;
958 if constructed {
959 x |= 0b0010_0000;
960 }
961 res.insert(0, x);
962 res
963 }
964 }
965}
966
967fn encode_base127(v: &BigUint) -> Vec<u8> {
968 let mut acc = v.clone();
969 let mut res = Vec::new();
970 let u128 = BigUint::from_u8(128).unwrap();
971 let zero = BigUint::zero();
972
973 if acc == zero {
974 res.push(0);
975 return res;
976 }
977
978 while acc > zero {
979 let digit = &acc % &u128;
981 acc >>= 7;
982
983 match digit.to_u8() {
984 None => panic!("7 bits don't fit into 8, cause ..."),
985 Some(x) if res.is_empty() => res.push(x),
986 Some(x) => res.push(x | 0x80),
987 }
988 }
989
990 res.reverse();
991 res
992}
993
994fn encode_class(c: ASN1Class) -> u8 {
995 match c {
996 ASN1Class::Universal => 0b0000_0000,
997 ASN1Class::Application => 0b0100_0000,
998 ASN1Class::ContextSpecific => 0b1000_0000,
999 ASN1Class::Private => 0b1100_0000,
1000 }
1001}
1002
1003fn encode_len(x: usize) -> Vec<u8> {
1004 if x < 128 {
1005 vec![x as u8]
1006 } else {
1007 let mut bstr = Vec::new();
1008 let mut work = x;
1009
1010 while work > 0 {
1012 bstr.push(work as u8);
1013 work >>= 8;
1014 }
1015
1016 let len = bstr.len() as u8;
1018 bstr.push(len | 0x80);
1019
1020 bstr.reverse();
1022 bstr
1023 }
1024}
1025
1026pub trait FromASN1WithBody: Sized {
1032 type Error: From<ASN1DecodeErr>;
1033
1034 fn from_asn1_with_body<'a>(
1035 v: &'a [ASN1Block],
1036 _b: &[u8],
1037 ) -> Result<(Self, &'a [ASN1Block]), Self::Error>;
1038}
1039
1040pub trait FromASN1: Sized {
1044 type Error: From<ASN1DecodeErr>;
1045
1046 fn from_asn1(v: &[ASN1Block]) -> Result<(Self, &[ASN1Block]), Self::Error>;
1047}
1048
1049impl<T: FromASN1> FromASN1WithBody for T {
1050 type Error = T::Error;
1051
1052 fn from_asn1_with_body<'a>(
1053 v: &'a [ASN1Block],
1054 _b: &[u8],
1055 ) -> Result<(T, &'a [ASN1Block]), T::Error> {
1056 T::from_asn1(v)
1057 }
1058}
1059
1060pub fn der_decode<T: FromASN1WithBody>(v: &[u8]) -> Result<T, T::Error> {
1063 let vs = from_der(v)?;
1064 T::from_asn1_with_body(&vs, v).map(|(a, _)| a)
1065}
1066
1067pub trait ToASN1 {
1073 type Error: From<ASN1EncodeErr>;
1074
1075 fn to_asn1(&self) -> Result<Vec<ASN1Block>, Self::Error> {
1076 self.to_asn1_class(ASN1Class::Universal)
1077 }
1078 fn to_asn1_class(&self, c: ASN1Class) -> Result<Vec<ASN1Block>, Self::Error>;
1079}
1080
1081pub fn der_encode<T: ToASN1>(v: &T) -> Result<Vec<u8>, T::Error> {
1084 let blocks = T::to_asn1(v)?;
1085 let mut res = Vec::new();
1086
1087 for block in blocks {
1088 let mut x = to_der(&block)?;
1089 res.append(&mut x);
1090 }
1091
1092 Ok(res)
1093}
1094
1095#[cfg(test)]
1098mod tests {
1099 use super::*;
1100 use quickcheck::{Arbitrary, Gen};
1101 use std::fs::File;
1102 use std::io::Read;
1103 use time::{Date, Month, Time};
1104
1105 impl Arbitrary for ASN1Class {
1106 fn arbitrary(g: &mut Gen) -> ASN1Class {
1107 match u8::arbitrary(g) % 4 {
1108 0 => ASN1Class::Private,
1109 1 => ASN1Class::ContextSpecific,
1110 2 => ASN1Class::Universal,
1111 3 => ASN1Class::Application,
1112 _ => panic!("I weep for a broken life."),
1113 }
1114 }
1115 }
1116
1117 quickcheck! {
1118 fn class_encdec_roundtrips(c: ASN1Class) -> bool {
1119 c == decode_class(encode_class(c.clone())).unwrap()
1120 }
1121
1122 fn class_decenc_roundtrips(v: u8) -> bool {
1123 (v & 0b11000000) == encode_class(decode_class(v).unwrap())
1124 }
1125 }
1126
1127 #[derive(Clone, Debug)]
1128 struct RandomUint {
1129 x: BigUint,
1130 }
1131
1132 impl Arbitrary for RandomUint {
1133 fn arbitrary(g: &mut Gen) -> RandomUint {
1134 let v = BigUint::from_u32(u32::arbitrary(g)).unwrap();
1135 RandomUint { x: v }
1136 }
1137 }
1138
1139 quickcheck! {
1140 fn tags_encdec_roundtrips(c: ASN1Class, con: bool, t: RandomUint) -> bool {
1141 let bytes = encode_tag(c, con, &t.x);
1142 let mut zero = 0;
1143 let (t2, con2, c2) = decode_tag(&bytes[..], &mut zero).unwrap();
1144 (c == c2) && (con == con2) && (t.x == t2)
1145 }
1146
1147 fn len_encdec_roundtrips(l: usize) -> bool {
1148 let bytes = encode_len(l);
1149 let mut zero = 0;
1150 match decode_length(&bytes[..], &mut zero) {
1151 Err(_) => false,
1152 Ok(l2) => l == l2
1153 }
1154 }
1155 }
1156
1157 #[derive(Clone, Debug)]
1158 struct RandomInt {
1159 x: BigInt,
1160 }
1161
1162 impl Arbitrary for RandomInt {
1163 fn arbitrary(g: &mut Gen) -> RandomInt {
1164 let v = BigInt::from_i64(i64::arbitrary(g)).unwrap();
1165 RandomInt { x: v }
1166 }
1167 }
1168
1169 #[allow(type_alias_bounds)]
1170 type ASN1BlockGen = fn(&mut Gen, usize) -> ASN1Block;
1171
1172 fn arb_boolean(g: &mut Gen, _d: usize) -> ASN1Block {
1173 let v = bool::arbitrary(g);
1174 ASN1Block::Boolean(0, v)
1175 }
1176
1177 fn arb_integer(g: &mut Gen, _d: usize) -> ASN1Block {
1178 let d = RandomInt::arbitrary(g);
1179 ASN1Block::Integer(0, d.x)
1180 }
1181
1182 fn arb_bitstr(g: &mut Gen, _d: usize) -> ASN1Block {
1183 let size = u16::arbitrary(g) as usize % 16;
1184 let maxbits = (size as usize) * 8;
1185 let modbits = u8::arbitrary(g) as usize % 8;
1186 let nbits = if modbits > maxbits {
1187 maxbits
1188 } else {
1189 maxbits - modbits
1190 };
1191
1192 let mut bytes = Vec::with_capacity(size);
1193 while bytes.len() < size {
1194 bytes.push(u8::arbitrary(g));
1195 }
1196
1197 ASN1Block::BitString(0, nbits, bytes)
1198 }
1199
1200 fn arb_octstr(g: &mut Gen, _d: usize) -> ASN1Block {
1201 let size = usize::arbitrary(g) % 16;
1202 let mut bytes = Vec::with_capacity(size);
1203
1204 while bytes.len() < size {
1205 bytes.push(u8::arbitrary(g));
1206 }
1207
1208 ASN1Block::OctetString(0, bytes)
1209 }
1210
1211 fn arb_null(_g: &mut Gen, _d: usize) -> ASN1Block {
1212 ASN1Block::Null(0)
1213 }
1214
1215 impl Arbitrary for OID {
1216 fn arbitrary(g: &mut Gen) -> OID {
1217 let count = usize::arbitrary(g) % 40;
1218 let val1 = u8::arbitrary(g) % 3;
1219 let v2mod = if val1 == 2 { 176 } else { 40 };
1220 let val2 = u8::arbitrary(g) % v2mod;
1221 let v1 = BigUint::from_u8(val1).unwrap();
1222 let v2 = BigUint::from_u8(val2).unwrap();
1223 let mut nums = vec![v1, v2];
1224
1225 for _ in 0..count {
1226 let num = RandomUint::arbitrary(g);
1227 nums.push(num.x);
1228 }
1229
1230 OID(nums)
1231 }
1232 }
1233
1234 fn arb_objid(g: &mut Gen, _d: usize) -> ASN1Block {
1235 let oid = OID::arbitrary(g);
1236 ASN1Block::ObjectIdentifier(0, oid)
1237 }
1238
1239 fn arb_seq(g: &mut Gen, d: usize) -> ASN1Block {
1240 let count = usize::arbitrary(g) % 63 + 1;
1241 let mut items = Vec::new();
1242
1243 for _ in 0..count {
1244 items.push(limited_arbitrary(g, d - 1));
1245 }
1246
1247 ASN1Block::Sequence(0, items)
1248 }
1249
1250 fn arb_set(g: &mut Gen, d: usize) -> ASN1Block {
1251 let count = usize::arbitrary(g) % 63 + 1;
1252 let mut items = Vec::new();
1253
1254 for _ in 0..count {
1255 items.push(limited_arbitrary(g, d - 1));
1256 }
1257
1258 ASN1Block::Set(0, items)
1259 }
1260
1261 fn arb_print(g: &mut Gen, _d: usize) -> ASN1Block {
1262 let count = usize::arbitrary(g) % 384;
1263 let mut items = Vec::new();
1264
1265 for _ in 0..count {
1266 let v = g.choose(PRINTABLE_CHARS.as_bytes());
1267 items.push(*v.unwrap() as char);
1268 }
1269
1270 ASN1Block::PrintableString(0, String::from_iter(items.iter()))
1271 }
1272
1273 fn arb_ia5(g: &mut Gen, _d: usize) -> ASN1Block {
1274 let count = usize::arbitrary(g) % 384;
1275 let mut items = Vec::new();
1276
1277 for _ in 0..count {
1278 items.push(u8::arbitrary(g) as char);
1279 }
1280
1281 ASN1Block::IA5String(0, String::from_iter(items.iter()))
1282 }
1283
1284 fn arb_utf8(g: &mut Gen, _d: usize) -> ASN1Block {
1285 let val = String::arbitrary(g);
1286 ASN1Block::UTF8String(0, val)
1287 }
1288
1289 fn arb_tele(g: &mut Gen, _d: usize) -> ASN1Block {
1290 let val = String::arbitrary(g);
1291 ASN1Block::TeletexString(0, val)
1292 }
1293
1294 fn arb_uni(g: &mut Gen, _d: usize) -> ASN1Block {
1295 let val = String::arbitrary(g);
1296 ASN1Block::UniversalString(0, val)
1297 }
1298
1299 fn arb_bmp(g: &mut Gen, _d: usize) -> ASN1Block {
1300 let val = String::arbitrary(g);
1301 ASN1Block::BMPString(0, val)
1302 }
1303
1304 fn arb_utc(g: &mut Gen, _d: usize) -> ASN1Block {
1305 let min = Date::from_calendar_date(1950, Month::January, 01)
1306 .unwrap()
1307 .to_julian_day();
1308 let max = Date::from_calendar_date(2049, Month::December, 31)
1309 .unwrap()
1310 .to_julian_day();
1311 let date =
1312 Date::from_julian_day(i32::arbitrary(g).rem_euclid(max - min + 1) + min).unwrap();
1313
1314 let h = u8::arbitrary(g).rem_euclid(24);
1315 let m = u8::arbitrary(g).rem_euclid(60);
1316 let s = u8::arbitrary(g).rem_euclid(60);
1317 let time = Time::from_hms(h, m, s).unwrap();
1318
1319 let t = PrimitiveDateTime::new(date, time);
1320 ASN1Block::UTCTime(0, t)
1321 }
1322
1323 fn arb_time(g: &mut Gen, _d: usize) -> ASN1Block {
1324 let min = Date::from_calendar_date(0, Month::January, 01)
1325 .unwrap()
1326 .to_julian_day();
1327 let max = Date::from_calendar_date(9999, Month::December, 31)
1328 .unwrap()
1329 .to_julian_day();
1330 let date =
1331 Date::from_julian_day(i32::arbitrary(g).rem_euclid(max - min + 1) + min).unwrap();
1332
1333 let time = Time::arbitrary(g);
1334
1335 let t = PrimitiveDateTime::new(date, time);
1336 ASN1Block::GeneralizedTime(0, t)
1337 }
1338
1339 fn arb_explicit(g: &mut Gen, d: usize) -> ASN1Block {
1340 let mut class = ASN1Class::arbitrary(g);
1341 if class == ASN1Class::Universal {
1342 class = ASN1Class::ContextSpecific;
1344 }
1345 let tag = RandomUint::arbitrary(g);
1346 let item = limited_arbitrary(g, d - 1);
1347
1348 ASN1Block::Explicit(class, 0, tag.x, Box::new(item))
1349 }
1350
1351 fn arb_unknown(g: &mut Gen, _d: usize) -> ASN1Block {
1352 let class = ASN1Class::arbitrary(g);
1353 let tag = loop {
1354 let potential = RandomUint::arbitrary(g);
1355 match potential.x.to_u8() {
1356 None => break potential,
1357 Some(x) if KNOWN_TAGS.contains(&x) => {}
1358 Some(_) => break potential,
1359 }
1360 };
1361 let size = usize::arbitrary(g) % 128;
1362 let mut items = Vec::with_capacity(size);
1363
1364 while items.len() < size {
1365 items.push(u8::arbitrary(g));
1366 }
1367
1368 ASN1Block::Unknown(class, false, 0, tag.x, items)
1369 }
1370
1371 fn limited_arbitrary(g: &mut Gen, d: usize) -> ASN1Block {
1372 let mut possibles: Vec<ASN1BlockGen> = vec![
1373 arb_boolean,
1374 arb_integer,
1375 arb_bitstr,
1376 arb_octstr,
1377 arb_null,
1378 arb_objid,
1379 arb_utf8,
1380 arb_print,
1381 arb_tele,
1382 arb_uni,
1383 arb_ia5,
1384 arb_utc,
1385 arb_time,
1386 arb_bmp,
1387 arb_unknown,
1388 ];
1389
1390 if d > 0 {
1391 possibles.push(arb_seq);
1392 possibles.push(arb_set);
1393 possibles.push(arb_explicit);
1394 }
1395
1396 match g.choose(&possibles[..]) {
1397 Some(f) => f(g, d),
1398 None => panic!("Couldn't generate arbitrary value."),
1399 }
1400 }
1401
1402 impl Arbitrary for ASN1Block {
1403 fn arbitrary(g: &mut Gen) -> ASN1Block {
1404 limited_arbitrary(g, 2)
1405 }
1406 }
1407
1408 quickcheck! {
1409 fn encode_decode_roundtrips(v: ASN1Block) -> bool {
1410 match to_der(&v) {
1411 Err(e) => {
1412 println!("Serialization error: {:?}", e);
1413 false
1414 }
1415 Ok(bytes) =>
1416 match from_der(&bytes[..]) {
1417 Err(e) => {
1418 println!("Parse error: {:?}", e);
1419 false
1420 }
1421 Ok(ref rvec) if rvec.len() == 1 => {
1422 let v2 = rvec.get(0).unwrap();
1423 if &v != v2 {
1424 println!("Original: {:?}", v);
1425 println!("Constructed: {:?}", v2);
1426 }
1427 &v == v2
1428 }
1429 Ok(_) => {
1430 println!("Too many results returned.");
1431 false
1432 }
1433 }
1434 }
1435 }
1436 }
1437
1438 fn result_int(v: i16) -> Result<Vec<ASN1Block>, ASN1DecodeErr> {
1439 let val = BigInt::from(v);
1440 Ok(vec![ASN1Block::Integer(0, val)])
1441 }
1442
1443 #[test]
1444 fn utc_time_tests() {
1445 let input = [
1448 55, 13, 13, 133, 13, 13, 50, 13, 13, 133, 13, 13, 50, 13, 133,
1449 ];
1450 let output = from_der(&input);
1451 assert!(output.is_err());
1452 }
1453
1454 #[test]
1455 fn generalized_time_tests() {
1456 check_spec(
1457 &PrimitiveDateTime::new(
1458 Date::from_calendar_date(1992, Month::May, 21).unwrap(),
1459 Time::from_hms(0, 0, 0).unwrap(),
1460 ),
1461 "19920521000000Z".to_string(),
1462 );
1463 check_spec(
1464 &PrimitiveDateTime::new(
1465 Date::from_calendar_date(1992, Month::June, 22).unwrap(),
1466 Time::from_hms(12, 34, 21).unwrap(),
1467 ),
1468 "19920622123421Z".to_string(),
1469 );
1470 check_spec(
1471 &PrimitiveDateTime::new(
1472 Date::from_calendar_date(1992, Month::July, 22).unwrap(),
1473 Time::from_hms_milli(13, 21, 00, 300).unwrap(),
1474 ),
1475 "19920722132100.3Z".to_string(),
1476 );
1477 }
1478
1479 fn check_spec(d: &PrimitiveDateTime, s: String) {
1480 let b = ASN1Block::GeneralizedTime(0, d.clone());
1481 match to_der(&b) {
1482 Err(_) => assert_eq!(format!("Broken: {}", d), s),
1483 Ok(ref vec) => {
1484 let mut resvec = vec.clone();
1485 resvec.remove(0);
1486 resvec.remove(0);
1487 assert_eq!(String::from_utf8(resvec).unwrap(), s);
1488 match from_der_(vec, 0) {
1489 Err(_) => assert_eq!(format!("Broken [reparse]: {}", d), s),
1490 Ok(mut vec) => {
1491 assert_eq!(vec.len(), 1);
1492 match vec.pop() {
1493 None => assert!(false, "The world's gone mad again."),
1494 Some(ASN1Block::GeneralizedTime(_, d2)) => assert_eq!(&d2, d),
1495 Some(_) => assert!(false, "Bad reparse of GeneralizedTime."),
1496 }
1497 }
1498 }
1499 }
1500 }
1501 }
1502
1503 #[test]
1504 fn base_integer_tests() {
1505 assert_eq!(from_der(&vec![0x02, 0x01, 0x00]), result_int(0));
1506 assert_eq!(from_der(&vec![0x02, 0x01, 0x7F]), result_int(127));
1507 assert_eq!(from_der(&vec![0x02, 0x02, 0x00, 0x80]), result_int(128));
1508 assert_eq!(from_der(&vec![0x02, 0x02, 0x01, 0x00]), result_int(256));
1509 assert_eq!(from_der(&vec![0x02, 0x01, 0x80]), result_int(-128));
1510 assert_eq!(from_der(&vec![0x02, 0x02, 0xFF, 0x7F]), result_int(-129));
1511 }
1512
1513 fn can_parse(f: &str) -> Result<Vec<ASN1Block>, ASN1DecodeErr> {
1514 let mut fd = File::open(f).unwrap();
1515 let mut buffer = Vec::new();
1516 let _amt = fd.read_to_end(&mut buffer);
1517 from_der(&buffer[..])
1518 }
1519
1520 #[test]
1521 fn x509_tests() {
1522 can_parse("test/server.bin").unwrap();
1523 can_parse("test/key.bin").unwrap();
1524 }
1525
1526 #[test]
1527 fn encode_base127_zero() {
1528 let zero = BigUint::from(0 as u64);
1529 let encoded = encode_base127(&zero);
1530 let expected: Vec<u8> = vec![0x0];
1531 assert_eq!(expected, encoded);
1532 }
1533
1534 #[test]
1535 fn raw_oid_eq() {
1536 let md5 = (
1542 oid!(1, 2, 840, 113549, 2, 5),
1543 vec![
1544 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05,
1545 0x05, 0x00, 0x04, 0x10,
1546 ],
1547 );
1548
1549 let ripmed160 = (
1550 oid!(1, 3, 36, 3, 2, 1),
1551 vec![
1552 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04,
1553 0x14,
1554 ],
1555 );
1556
1557 let sha1 = (
1558 oid!(1, 3, 14, 3, 2, 26),
1559 vec![
1560 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04,
1561 0x14,
1562 ],
1563 );
1564
1565 let sha224 = (
1566 oid!(2, 16, 840, 1, 101, 3, 4, 2, 4),
1567 vec![
1568 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
1569 0x04, 0x05, 0x00, 0x04, 0x1C,
1570 ],
1571 );
1572
1573 let sha256 = (
1574 oid!(2, 16, 840, 1, 101, 3, 4, 2, 1),
1575 vec![
1576 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
1577 0x01, 0x05, 0x00, 0x04, 0x20,
1578 ],
1579 );
1580
1581 let sha384 = (
1582 oid!(2, 16, 840, 1, 101, 3, 4, 2, 2),
1583 vec![
1584 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
1585 0x02, 0x05, 0x00, 0x04, 0x30,
1586 ],
1587 );
1588
1589 let sha512 = (
1590 oid!(2, 16, 840, 1, 101, 3, 4, 2, 3),
1591 vec![
1592 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
1593 0x03, 0x05, 0x00, 0x04, 0x40,
1594 ],
1595 );
1596
1597 let tests: Vec<(OID, Vec<u8>)> = vec![md5, ripmed160, sha1, sha224, sha256, sha384, sha512];
1598
1599 for test in tests {
1600 let expected = test.1;
1601 let raw_oid = test.0.as_raw().expect("Failed to convert OID to raw");
1602 assert_eq!(raw_oid, &expected[6..(expected.len() - 4)]);
1603 }
1604 }
1605
1606 #[test]
1607 fn vec_oid() {
1608 let vec_u64: Vec<u64> = vec![1, 2, 840, 10045, 4, 3, 2];
1609 let vec_i64: Vec<i64> = vec![1, 2, 840, 10045, 4, 3, 2];
1610 let vec_usize: Vec<usize> = vec![1, 2, 840, 10045, 4, 3, 2];
1611
1612 let mut o = Vec::new();
1613 for val in vec_u64.iter() {
1614 o.push(BigUint::from(*val));
1615 }
1616
1617 let oid = OID::new(o);
1618
1619 assert_eq!(Ok(vec_u64), oid.as_vec());
1620 assert_eq!(Ok(vec_i64), oid.as_vec());
1621 assert_eq!(Ok(vec_usize), oid.as_vec());
1622 assert_eq!(Err(ASN1DecodeErr::Overflow), oid.as_vec::<u8>());
1623 }
1624}