@@ -7,7 +7,10 @@ use napi::{
77use num_bigint:: BigInt ;
88use rasn:: {
99 ber:: { decode, encode} ,
10- types:: { Any , BitString , Class , OctetString , PrintableString } ,
10+ types:: {
11+ Any , BitString , BmpString , Class , GeneralString , Ia5String , NumericString , OctetString ,
12+ PrintableString , UniversalString , Utf8String , VisibleString ,
13+ } ,
1114 Decode , Tag ,
1215} ;
1316
@@ -222,7 +225,17 @@ impl ASN1Decoder {
222225 /// Convert to a string.
223226 #[ napi]
224227 pub fn into_string ( & self ) -> Result < String > {
225- Ok ( self . decode :: < PrintableString > ( ) ?. as_str ( ) . into ( ) )
228+ Ok ( match * self . get_tag ( ) {
229+ Tag :: PRINTABLE_STRING => self . decode :: < PrintableString > ( ) ?. as_str ( ) . into ( ) ,
230+ Tag :: BMP_STRING => self . decode :: < BmpString > ( ) ?. as_str ( ) . into ( ) ,
231+ Tag :: GENERAL_STRING => self . decode :: < GeneralString > ( ) ?. as_str ( ) . into ( ) ,
232+ Tag :: IA5_STRING => self . decode :: < Ia5String > ( ) ?. as_str ( ) . into ( ) ,
233+ Tag :: VISIBLE_STRING => self . decode :: < VisibleString > ( ) ?. as_str ( ) . into ( ) ,
234+ Tag :: NUMERIC_STRING => self . decode :: < NumericString > ( ) ?. as_str ( ) . into ( ) ,
235+ Tag :: UNIVERSAL_STRING => self . decode :: < UniversalString > ( ) ?. as_str ( ) . into ( ) ,
236+ Tag :: UTF8_STRING => self . decode :: < Utf8String > ( ) ?. as_str ( ) . into ( ) ,
237+ _ => bail ! ( ASN1NAPIError :: UnknownStringFormat ) ,
238+ } )
226239 }
227240
228241 /// Convert to a date.
@@ -351,21 +364,17 @@ impl TryFrom<Vec<u8>> for ASN1Decoder {
351364
352365#[ cfg( test) ]
353366mod test {
367+ use std:: collections:: VecDeque ;
354368 use std:: str:: FromStr ;
355369
356370 use chrono:: { DateTime , FixedOffset , TimeZone , Utc } ;
357371 use num_bigint:: BigInt ;
358372 use rasn:: types:: BitString ;
359373
360- use crate :: asn1:: ASN1Decoder ;
361- use crate :: asn1:: ASN1Encoder ;
362- use crate :: cast_data;
363- use crate :: objects:: ASN1Context ;
364- use crate :: objects:: ASN1Object ;
365- use crate :: objects:: ASN1Set ;
366- use crate :: objects:: ASN1OID ;
367- use crate :: types:: ASN1Data ;
368- use crate :: types:: JsType ;
374+ use crate :: asn1:: * ;
375+ use crate :: objects:: * ;
376+ use crate :: types:: * ;
377+ use crate :: * ;
369378
370379 const TEST_VOTE : & str = "MFEGCWCGSAFlAwQCCDBEBCCb0PJlcOIUeBZH8vNeObY9pg\
371380 xw+6PUh6ku6n9k9VVYDgQge0hOYtjbsjyJqqx5m7D8iP+i\
@@ -377,6 +386,20 @@ mod test {
377386 v3MD2DK+so3K1BuRAgEKAkEA66ba0QK07zVrshYkOF3cO\
378387 aW61T1ckn9QymeSBE+yE7EJPDnrN6g54KxBaAjRVFlT3i\
379388 Ze4qTtQfXRoCkhoCgzqg==";
389+ const TEST_CERT : & str = "MIIB3jCCAYWgAwIBAgIBATAKBggqhkjOPQQDAjBEMQswCQ\
390+ YDVQQGEwJVUzELMAkGA1UECBMCQ0ExDjAMBgNVBAoTBUtl\
391+ ZXRhMRgwFgYDVQQDEw9ub2RlMS5rZWV0YS5jb20wHhcNMj\
392+ IxMTAzMDEyOTU4WhcNMjcwNTExMDEyOTU4WjBiMQswCQYD\
393+ VQQGEwJVUzELMAkGA1UECAwCQ0ExFDASBgNVBAcMC0xvcy\
394+ BBbmdlbGVzMQ4wDAYDVQQKDAVLZWV0YTEgMB4GA1UEAwwX\
395+ Y2xpZW50MS5ub2RlMS5rZWV0YS5jb20wVjAQBgcqhkjOPQ\
396+ IBBgUrgQQACgNCAAQ3605beUhS+2ZGuk4OkQ2utb239l2g\
397+ kAl4tgKp1JFyujP8aNZ5Zh7nnfB64eWCOHtaGIXHYeXlYf\
398+ +rZ9KfnULdo00wSzAdBgNVHQ4EFgQUGKqtzLuSNICC4hId\
399+ Fc3a7QdIkhMwHwYDVR0jBBgwFoAUeqmWlg9mdQnXDtFiV8\
400+ uXgiCC8yswCQYDVR0TBAIwADAKBggqhkjOPQQDAgNHADBE\
401+ AiB/sWgSvLZSddTHD64sWgPDgQSnWXxjfIzcoP1W48lZng\
402+ IgazAF+38D5aIrcmtnD2YEp5i1ydiYzxKCU1RFAZf540c=";
380403
381404 fn fixture_get_test_vote ( ) -> Vec < ASN1Data > {
382405 vec ! [
@@ -445,6 +468,110 @@ mod test {
445468 ]
446469 }
447470
471+ fn fixture_get_test_cert ( ) -> Vec < ASN1Data > {
472+ vec ! [
473+ ASN1Data :: Array ( vec![
474+ ASN1Data :: Object ( ASN1Object :: Context ( ASN1Context {
475+ value: 0 ,
476+ contains: Box :: new( ASN1Data :: Integer ( 2 ) ) ,
477+ } ) ) ,
478+ ASN1Data :: Integer ( 1 ) ,
479+ ASN1Data :: Array ( vec![ ASN1Data :: Object ( ASN1Object :: Oid ( ASN1OID :: new(
480+ "sha256WithEcDSA" ,
481+ ) ) ) ] ) ,
482+ ASN1Data :: Array ( vec![
483+ ASN1Data :: Object ( ASN1Object :: Set ( ASN1Set :: new( ASN1OID :: new( "2.5.4.6" ) , "US" ) ) ) ,
484+ ASN1Data :: Object ( ASN1Object :: Set ( ASN1Set :: new( ASN1OID :: new( "2.5.4.8" ) , "CA" ) ) ) ,
485+ ASN1Data :: Object ( ASN1Object :: Set ( ASN1Set :: new(
486+ ASN1OID :: new( "2.5.4.10" ) ,
487+ "Keeta" ,
488+ ) ) ) ,
489+ ASN1Data :: Object ( ASN1Object :: Set ( ASN1Set :: new(
490+ ASN1OID :: new( "commonName" ) ,
491+ "node1.keeta.com" ,
492+ ) ) ) ,
493+ ] ) ,
494+ ASN1Data :: Array ( vec![
495+ ASN1Data :: Date ( DateTime :: <FixedOffset >:: from(
496+ Utc . ymd( 2022 , 11 , 03 ) . and_hms_milli( 1 , 29 , 58 , 0 ) ,
497+ ) ) ,
498+ ASN1Data :: Date ( DateTime :: <FixedOffset >:: from(
499+ Utc . ymd( 2027 , 05 , 11 ) . and_hms_milli( 1 , 29 , 58 , 0 ) ,
500+ ) ) ,
501+ ] ) ,
502+ ASN1Data :: Array ( vec![
503+ ASN1Data :: Object ( ASN1Object :: Set ( ASN1Set :: new( ASN1OID :: new( "2.5.4.6" ) , "US" ) ) ) ,
504+ ASN1Data :: Object ( ASN1Object :: Set ( ASN1Set :: new( ASN1OID :: new( "2.5.4.8" ) , "CA" ) ) ) ,
505+ ASN1Data :: Object ( ASN1Object :: Set ( ASN1Set :: new(
506+ ASN1OID :: new( "2.5.4.7" ) ,
507+ "Los Angeles" ,
508+ ) ) ) ,
509+ ASN1Data :: Object ( ASN1Object :: Set ( ASN1Set :: new(
510+ ASN1OID :: new( "2.5.4.10" ) ,
511+ "Keeta" ,
512+ ) ) ) ,
513+ ASN1Data :: Object ( ASN1Object :: Set ( ASN1Set :: new(
514+ ASN1OID :: new( "commonName" ) ,
515+ "client1.node1.keeta.com" ,
516+ ) ) ) ,
517+ ] ) ,
518+ ASN1Data :: Array ( vec![
519+ ASN1Data :: Array ( vec![
520+ ASN1Data :: Object ( ASN1Object :: Oid ( ASN1OID :: new( "ecdsa" ) ) ) ,
521+ ASN1Data :: Object ( ASN1Object :: Oid ( ASN1OID :: new( "secp256k1" ) ) ) ,
522+ ] ) ,
523+ ASN1Data :: Object ( ASN1Object :: BitString ( ASN1RawBitString :: new(
524+ BitString :: from_vec( vec![
525+ 0x04 , 0x37 , 0xEB , 0x4E , 0x5B , 0x79 , 0x48 , 0x52 , 0xFB , 0x66 , 0x46 , 0xBA ,
526+ 0x4E , 0x0E , 0x91 , 0x0D , 0xAE , 0xB5 , 0xBD , 0xB7 , 0xF6 , 0x5D , 0xA0 , 0x90 ,
527+ 0x09 , 0x78 , 0xB6 , 0x02 , 0xA9 , 0xD4 , 0x91 , 0x72 , 0xBA , 0x33 , 0xFC , 0x68 ,
528+ 0xD6 , 0x79 , 0x66 , 0x1E , 0xE7 , 0x9D , 0xF0 , 0x7A , 0xE1 , 0xE5 , 0x82 , 0x38 ,
529+ 0x7B , 0x5A , 0x18 , 0x85 , 0xC7 , 0x61 , 0xE5 , 0xE5 , 0x61 , 0xFF , 0xAB , 0x67 ,
530+ 0xD2 , 0x9F , 0x9D , 0x42 , 0xDD ,
531+ ] ) ,
532+ ) ) ) ,
533+ ] ) ,
534+ ASN1Data :: Object ( ASN1Object :: Context ( ASN1Context :: new(
535+ 3 ,
536+ ASN1Data :: Array ( vec![
537+ ASN1Data :: Array ( vec![
538+ ASN1Data :: Object ( ASN1Object :: Oid ( ASN1OID :: new( "2.5.29.14" ) ) ) ,
539+ ASN1Data :: Bytes ( vec![
540+ 0x04 , 0x14 , 0x18 , 0xAA , 0xAD , 0xCC , 0xBB , 0x92 , 0x34 , 0x80 , 0x82 ,
541+ 0xE2 , 0x12 , 0x1D , 0x15 , 0xCD , 0xDA , 0xED , 0x07 , 0x48 , 0x92 , 0x13 ,
542+ ] ) ,
543+ ] ) ,
544+ ASN1Data :: Array ( vec![
545+ ASN1Data :: Object ( ASN1Object :: Oid ( ASN1OID :: new( "2.5.29.35" ) ) ) ,
546+ ASN1Data :: Bytes ( vec![
547+ 0x30 , 0x16 , 0x80 , 0x14 , 0x7A , 0xA9 , 0x96 , 0x96 , 0x0F , 0x66 , 0x75 ,
548+ 0x09 , 0xD7 , 0x0E , 0xD1 , 0x62 , 0x57 , 0xCB , 0x97 , 0x82 , 0x20 , 0x82 ,
549+ 0xF3 , 0x2B ,
550+ ] ) ,
551+ ] ) ,
552+ ASN1Data :: Array ( vec![
553+ ASN1Data :: Object ( ASN1Object :: Oid ( ASN1OID :: new( "2.5.29.19" ) ) ) ,
554+ ASN1Data :: Bytes ( vec![ 0x30 , 0 ] ) ,
555+ ] ) ,
556+ ] ) ,
557+ ) ) ) ,
558+ ] ) ,
559+ ASN1Data :: Array ( vec![ ASN1Data :: Object ( ASN1Object :: Oid ( ASN1OID :: new(
560+ "sha256WithEcDSA" ,
561+ ) ) ) ] ) ,
562+ ASN1Data :: Object ( ASN1Object :: BitString ( ASN1RawBitString :: new(
563+ BitString :: from_vec( vec![
564+ 0x30 , 0x44 , 0x02 , 0x20 , 0x7F , 0xB1 , 0x68 , 0x12 , 0xBC , 0xB6 , 0x52 , 0x75 , 0xD4 ,
565+ 0xC7 , 0x0F , 0xAE , 0x2C , 0x5A , 0x03 , 0xC3 , 0x81 , 0x04 , 0xA7 , 0x59 , 0x7C , 0x63 ,
566+ 0x7C , 0x8C , 0xDC , 0xA0 , 0xFD , 0x56 , 0xE3 , 0xC9 , 0x59 , 0x9E , 0x02 , 0x20 , 0x6B ,
567+ 0x30 , 0x05 , 0xFB , 0x7F , 0x03 , 0xE5 , 0xA2 , 0x2B , 0x72 , 0x6B , 0x67 , 0x0F , 0x66 ,
568+ 0x04 , 0xA7 , 0x98 , 0xB5 , 0xC9 , 0xD8 , 0x98 , 0xCF , 0x12 , 0x82 , 0x53 , 0x54 , 0x45 ,
569+ 0x01 , 0x97 , 0xF9 , 0xE3 , 0x47 ,
570+ ] ) ,
571+ ) ) ) ,
572+ ]
573+ }
574+
448575 #[ test]
449576 fn test_asn1_into_bool ( ) {
450577 let encoded_true = "AQH/" ;
@@ -623,6 +750,28 @@ mod test {
623750 } ) ;
624751 }
625752
753+ #[ test]
754+ fn test_asn1_cert_into_sequence ( ) {
755+ let obj = ASN1Decoder :: from_base64 ( TEST_CERT . into ( ) ) . expect ( "base64" ) ;
756+ let js_type = * obj. get_js_type ( ) ;
757+
758+ assert_eq ! ( js_type, JsType :: Sequence ) ;
759+
760+ let mut test = VecDeque :: from ( fixture_get_test_cert ( ) ) ;
761+ let test_tbs = test. pop_front ( ) . unwrap ( ) ;
762+ let test_algo = test. pop_front ( ) . unwrap ( ) ;
763+ let test_sig = test. pop_front ( ) . unwrap ( ) ;
764+
765+ let mut cert = obj. into_iter ( ) ;
766+ let tbs = cert. next ( ) . unwrap ( ) . unwrap ( ) ;
767+ let algo = cert. next ( ) . unwrap ( ) . unwrap ( ) ;
768+ let sig = cert. next ( ) . unwrap ( ) . unwrap ( ) ;
769+
770+ assert_eq ! ( tbs, test_tbs) ;
771+ assert_eq ! ( algo, test_algo) ;
772+ assert_eq ! ( sig, test_sig) ;
773+ }
774+
626775 #[ test]
627776 fn test_asn1_encoder_to_base64 ( ) {
628777 let block = fixture_get_test_block ( ) ;
0 commit comments