From ef4818e991b0da082ee8815133f6cf92046083b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20G=C3=B6cer?= Date: Sun, 3 Dec 2023 12:15:20 +0100 Subject: [PATCH] Support parsing of nested objects with indefinite lengths --- lib/asn1/asn1_parser.dart | 6 ++++-- lib/asn1/asn1_utils.dart | 28 ++++++++++++++++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/lib/asn1/asn1_parser.dart b/lib/asn1/asn1_parser.dart index 0ea0f525..55884043 100644 --- a/lib/asn1/asn1_parser.dart +++ b/lib/asn1/asn1_parser.dart @@ -55,7 +55,8 @@ class ASN1Parser { // Get the length of the value bytes for the current object var length = ASN1Utils.decodeLength(bytes!.sublist(_position)); - var valueStartPosition = ASN1Utils.calculateValueStartPosition(bytes!.sublist(_position)); + var valueStartPosition = + ASN1Utils.calculateValueStartPosition(bytes!.sublist(_position)); var isIndefiniteLength = false; @@ -88,7 +89,8 @@ class ASN1Parser { } // Update the position - _position = _position + obj.totalEncodedByteLength + (isIndefiniteLength ? 2 : 0); + _position = + _position + obj.totalEncodedByteLength + (isIndefiniteLength ? 2 : 0); return obj; } diff --git a/lib/asn1/asn1_utils.dart b/lib/asn1/asn1_utils.dart index e5106cab..289f6b71 100644 --- a/lib/asn1/asn1_utils.dart +++ b/lib/asn1/asn1_utils.dart @@ -127,21 +127,24 @@ class ASN1Utils { var currentPosition = startPosition; var indefiniteLengthObjects = 0; while (currentPosition < bytes.length - 1) { - if (bytes[currentPosition] == 0x00 && bytes[currentPosition + 1] == 0x00) { + if (bytes[currentPosition] == 0x00 && + bytes[currentPosition + 1] == 0x00) { indefiniteLengthObjects--; if (indefiniteLengthObjects == 0) { return currentPosition - startPosition; } currentPosition += 2; } else { - final nextLength = ASN1Utils.decodeLength(bytes.sublist(currentPosition)); - final valueStartPosition = - ASN1Utils.calculateValueStartPosition(bytes.sublist(currentPosition)); + final nextLength = + ASN1Utils.decodeLength(bytes.sublist(currentPosition)); + final valueStartPosition = ASN1Utils.calculateValueStartPosition( + bytes.sublist(currentPosition)); if (nextLength == 0) { throw ArgumentError('Invalid length of zero.'); } if (valueStartPosition <= 0) { - throw ArgumentError('Invalid value start position: $valueStartPosition'); + throw ArgumentError( + 'Invalid value start position: $valueStartPosition'); } if (nextLength == -1) { @@ -156,7 +159,8 @@ class ASN1Utils { throw ArgumentError('End of content octets not found'); } - static Uint8List getBytesFromPEMString(String pem, {bool checkHeader = true}) { + static Uint8List getBytesFromPEMString(String pem, + {bool checkHeader = true}) { var lines = LineSplitter.split(pem) .map((line) => line.trim()) .where((line) => line.isNotEmpty) @@ -177,7 +181,8 @@ class ASN1Utils { return Uint8List.fromList(base64Decode(base64)); } - static ECPrivateKey ecPrivateKeyFromDerBytes(Uint8List bytes, {bool pkcs8 = false}) { + static ECPrivateKey ecPrivateKeyFromDerBytes(Uint8List bytes, + {bool pkcs8 = false}) { var asn1Parser = ASN1Parser(bytes); var topLevelSeq = asn1Parser.nextObject() as ASN1Sequence; var curveName; @@ -195,12 +200,14 @@ class ASN1Utils { var octetString = topLevelSeq.elements!.elementAt(2) as ASN1OctetString; asn1Parser = ASN1Parser(octetString.valueBytes); var octetStringSeq = asn1Parser.nextObject() as ASN1Sequence; - var octetStringKeyData = octetStringSeq.elements!.elementAt(1) as ASN1OctetString; + var octetStringKeyData = + octetStringSeq.elements!.elementAt(1) as ASN1OctetString; x = octetStringKeyData.valueBytes!; } else { // Parse the SEC1 format - var privateKeyAsOctetString = topLevelSeq.elements!.elementAt(1) as ASN1OctetString; + var privateKeyAsOctetString = + topLevelSeq.elements!.elementAt(1) as ASN1OctetString; var choice = topLevelSeq.elements!.elementAt(2); var s = ASN1Sequence(); var parser = ASN1Parser(choice.valueBytes); @@ -208,7 +215,8 @@ class ASN1Utils { s.add(parser.nextObject()); } var curveNameOi = s.elements!.elementAt(0) as ASN1ObjectIdentifier; - var data = ObjectIdentifiers.getIdentifierByIdentifier(curveNameOi.objectIdentifierAsString); + var data = ObjectIdentifiers.getIdentifierByIdentifier( + curveNameOi.objectIdentifierAsString); if (data != null) { curveName = data['readableName']; }