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