Skip to content

Commit

Permalink
Support parsing of nested objects with indefinite lengths
Browse files Browse the repository at this point in the history
  • Loading branch information
hig-dev committed Dec 3, 2023
1 parent fb63f4d commit ef4818e
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 12 deletions.
6 changes: 4 additions & 2 deletions lib/asn1/asn1_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}

Expand Down
28 changes: 18 additions & 10 deletions lib/asn1/asn1_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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)
Expand All @@ -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;
Expand All @@ -195,20 +200,23 @@ 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);
while (parser.hasNext()) {
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'];
}
Expand Down

0 comments on commit ef4818e

Please sign in to comment.