parse static method

List<ASN1Object> parse({
  1. required Iterator<int> iterator,
})

Implementation

static List<ASN1Object> parse({required Iterator<int> iterator}) {
  var result = <ASN1Object>[];

  while (iterator.moveNext()) {
    var nextValue = iterator.current;

    var asn1obj = ASN1Object();
    asn1obj.identifier = ASN1Identifier(nextValue);

    if (asn1obj.identifier!.isConstructed()) {
      var contentData = loadSubContent(iterator: iterator);

      if (contentData.isEmpty) {
        asn1obj.sub = parse(iterator: iterator);
      } else {
        var subIterator = contentData.iterator;
        asn1obj.sub = parse(iterator: subIterator);
      }

      asn1obj.value = null;

      asn1obj.encoded = Uint8List.fromList(contentData);

      if (asn1obj.sub != null) {
        for (var item in asn1obj.sub!) {
          item.parent = asn1obj;
        }
      }
    } else {
      if (asn1obj.identifier!.typeClass() == ASN1IdentifierClass.UNIVERSAL) {
        var contentData = loadSubContent(iterator: iterator);

        asn1obj.encoded = Uint8List.fromList(contentData);

        // decode the content data with come more convenient format

        var tagNumber = asn1obj.identifier!.tagNumber();

        if (tagNumber == ASN1IdentifierTagNumber.END_OF_CONTENT) {
          return result;
        } else if (tagNumber == ASN1IdentifierTagNumber.BOOLEAN) {
          var value = contentData.length > 0 ? contentData.first : null;
          if (value != null) {
            asn1obj.value = value > 0 ? true : false;
          }
        } else if (tagNumber == ASN1IdentifierTagNumber.INTEGER) {
          while (contentData.length > 0 && contentData.first == 0) {
            contentData.removeAt(0); // remove not significant digit
          }
          asn1obj.value = contentData;
        } else if (tagNumber == ASN1IdentifierTagNumber.NULL) {
          asn1obj.value = null;
        } else if (tagNumber == ASN1IdentifierTagNumber.OBJECT_IDENTIFIER) {
          asn1obj.value = decodeOid(contentData: contentData);
        } else if ([
          ASN1IdentifierTagNumber.UTF8_STRING,
          ASN1IdentifierTagNumber.PRINTABLE_STRING,
          ASN1IdentifierTagNumber.NUMERIC_STRING,
          ASN1IdentifierTagNumber.GENERAL_STRING,
          ASN1IdentifierTagNumber.UNIVERSAL_STRING,
          ASN1IdentifierTagNumber.CHARACTER_STRING,
          ASN1IdentifierTagNumber.T61_STRING
        ].contains(tagNumber)) {
          asn1obj.value = utf8.decode(contentData, allowMalformed: true);
        } else if (tagNumber == ASN1IdentifierTagNumber.BMP_STRING) {
          asn1obj.value = String.fromCharCodes(contentData);
        } else if ([
          ASN1IdentifierTagNumber.VISIBLE_STRING,
          ASN1IdentifierTagNumber.IA5_STRING
        ].contains(tagNumber)) {
          asn1obj.value = ascii.decode(contentData, allowInvalid: true);
        } else if (tagNumber == ASN1IdentifierTagNumber.UTC_TIME) {
          asn1obj.value = utcTimeToDate(contentData: contentData);
        } else if (tagNumber == ASN1IdentifierTagNumber.GENERALIZED_TIME) {
          asn1obj.value = generalizedTimeToDate(contentData: contentData);
        } else if (tagNumber == ASN1IdentifierTagNumber.BIT_STRING) {
          if (contentData.length > 0) {
            contentData.removeAt(0); // unused bits
          }
          asn1obj.value = contentData;
        } else if (tagNumber == ASN1IdentifierTagNumber.OCTET_STRING) {
          try {
            var subIterator = contentData.iterator;
            asn1obj.sub = parse(iterator: subIterator);
          } catch (e) {
            var str;
            try {
              str = utf8.decode(contentData);
            } catch (e) {}
            if (str != null) {
              asn1obj.value = str;
            } else {
              asn1obj.value = contentData;
            }
          }
        } else {
          // print("unsupported tag: ${asn1obj.identifier.tagNumber()}");
          asn1obj.value = contentData;
        }
      } else {
        // custom/private tag

        var contentData = loadSubContent(iterator: iterator);

        var str;
        try {
          str = utf8.decode(contentData);
        } catch (e) {}
        if (str != null) {
          asn1obj.value = str;
        } else {
          asn1obj.value = contentData;
        }
      }
    }
    result.add(asn1obj);
  }

  return result;
}