Skip to content

Commit

Permalink
A lot of cleanup (#64)
Browse files Browse the repository at this point in the history
- Made a number of APIs not-nullable
- Made a number of fields final where they could be
- Added types to a few public APIs
- Enabled and fixed a bunch of new lints
- Moved part files to the lib/src dir
- Require Dart 3
kevmoo authored Jul 26, 2023
1 parent 7debac9 commit bea77eb
Showing 50 changed files with 233 additions and 260 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ jobs:
strategy:
fail-fast: false
matrix:
sdk: [2.18.0, dev]
sdk: [3.0.0, dev]
steps:
- uses: actions/checkout@v2
- uses: dart-lang/setup-dart@v1.3
@@ -47,7 +47,7 @@ jobs:
matrix:
# Add macos-latest and/or windows-latest if relevant for this package.
os: [ubuntu-latest]
sdk: [2.18.0, dev]
sdk: [3.0.0, dev]
steps:
- uses: actions/checkout@v2
- uses: dart-lang/setup-dart@v1.3
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

### 1.5.0

- Make a number of fields `final` that should not be changed.
- Add types to a few members.
- Remove nullability from a field fields.
- Require Dart 3.0

### 1.4.1

- Fix null assertion when accessing valueBytes before encodedBytes.
@@ -20,6 +27,7 @@
### 1.2.2

- Fix #62. Allow context specific tags to be cast to an asn1 sequence.

### 1.2.1

- Fix #57
4 changes: 3 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
include: package:lints/recommended.yaml
include: package:dart_flutter_team_lints/analysis_options.yaml

# This package was created before these constant rules were best practice.
linter:
rules:
constant_identifier_names: false
lines_longer_than_80_chars: false
non_constant_identifier_names: false
use_super_parameters: true
3 changes: 2 additions & 1 deletion example/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:convert';
import 'dart:typed_data';

import 'package:asn1lib/asn1lib.dart';

final certificateDER = decodePEM('''-----BEGIN CERTIFICATE-----
@@ -44,7 +45,7 @@ void main() {
print(seq.valueBytes().length);
}

Uint8List decodePEM(pem) {
Uint8List decodePEM(String pem) {
var startsWith = [
'-----BEGIN PUBLIC KEY-----',
'-----BEGIN PRIVATE KEY-----',
58 changes: 26 additions & 32 deletions lib/asn1lib.dart
Original file line number Diff line number Diff line change
@@ -1,34 +1,28 @@
library asn1lib;

import 'dart:typed_data';
import 'dart:convert';
import 'dart:typed_data';

part 'asn1integer.dart';
part 'asn1enumerated.dart';

part 'asn1object.dart';
part 'asn1application.dart';

part 'asn1util.dart';
part 'asn1octetstring.dart';
part 'asn1exception.dart';
part 'asn1sequence.dart';
part 'asn1length.dart';
part 'asn1parser.dart';
part 'asn1constants.dart';
part 'asn1null.dart';
part 'asn1boolean.dart';
part 'asn1set.dart';

part 'asn1objectidentifier.dart';
part 'asn1bitstring.dart';
part 'asn1printablestring.dart';
part 'asn1numericstring.dart';
part 'asn1utf8string.dart';
part 'asn1ia5string.dart';
part 'asn1utctime.dart';
part 'asn1bmpstring.dart';
part 'asn1generalizedtime.dart';
part 'asn1teletextstring.dart';

part 'asn1ipaddress.dart';
part 'src/asn1application.dart';
part 'src/asn1bitstring.dart';
part 'src/asn1bmpstring.dart';
part 'src/asn1boolean.dart';
part 'src/asn1constants.dart';
part 'src/asn1enumerated.dart';
part 'src/asn1exception.dart';
part 'src/asn1generalizedtime.dart';
part 'src/asn1ia5string.dart';
part 'src/asn1integer.dart';
part 'src/asn1ipaddress.dart';
part 'src/asn1length.dart';
part 'src/asn1null.dart';
part 'src/asn1numericstring.dart';
part 'src/asn1object.dart';
part 'src/asn1objectidentifier.dart';
part 'src/asn1octetstring.dart';
part 'src/asn1parser.dart';
part 'src/asn1printablestring.dart';
part 'src/asn1sequence.dart';
part 'src/asn1set.dart';
part 'src/asn1teletextstring.dart';
part 'src/asn1utctime.dart';
part 'src/asn1utf8string.dart';
part 'src/asn1util.dart';
14 changes: 7 additions & 7 deletions lib/asn1application.dart → lib/src/asn1application.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
part of asn1lib;
part of '../asn1lib.dart';

// Represent an ASN1 APPLICATION type. An Application is a
// custom ASN1 object that delegates the interpretation to the
// consumer.
class ASN1Application extends ASN1Object {
ASN1Application({int tag = APPLICATION_CLASS}) : super(tag: tag);
ASN1Application({super.tag = APPLICATION_CLASS});

ASN1Application.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1Application.fromBytes(super.bytes) : super.fromBytes() {
// check that this really is an application type
if (!isApplication(tag)) {
throw ASN1Exception('tag $tag is not an ASN1 Application class');
@@ -18,9 +18,9 @@ class ASN1Application extends ASN1Object {
// custom ASN1 object that delegates the interpretation to the
// consumer.
class ASN1Private extends ASN1Object {
ASN1Private({int tag = PRIVATE_CLASS}) : super(tag: tag);
ASN1Private({super.tag = PRIVATE_CLASS});

ASN1Private.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1Private.fromBytes(super.bytes) : super.fromBytes() {
// check that this really is an Private type
if (!isPrivate(tag)) {
throw ASN1Exception('tag $tag is not an ASN1 Private class');
@@ -32,9 +32,9 @@ class ASN1Private extends ASN1Object {
// custom ASN1 object that delegates the interpretation to the
// consumer.
class ASN1ContextSpecific extends ASN1Object {
ASN1ContextSpecific({int tag = PRIVATE_CLASS}) : super(tag: tag);
ASN1ContextSpecific({super.tag = PRIVATE_CLASS});

ASN1ContextSpecific.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1ContextSpecific.fromBytes(super.bytes) : super.fromBytes() {
// check that this really is an Private type
if (!isContextSpecific(tag)) {
throw ASN1Exception('tag $tag is not an ASN1 Context specific class');
15 changes: 7 additions & 8 deletions lib/asn1bitstring.dart → lib/src/asn1bitstring.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 Octet String. This is an array of character codes.
///
class ASN1BitString extends ASN1Object {
/// The decoded string value
late List<int> stringValue;
int unusedbits = 0;
late final List<int> stringValue;
late final int unusedbits;

@override
Uint8List contentBytes() => Uint8List.fromList(stringValue);
@@ -15,25 +15,24 @@ class ASN1BitString extends ASN1Object {
/// Create an [ASN1BitString] initialized with String value. Optionally override the tag.
///
ASN1BitString(this.stringValue,
{this.unusedbits = 0, int tag = BIT_STRING_TYPE})
: super(tag: tag);
{this.unusedbits = 0, super.tag = BIT_STRING_TYPE});

///
/// Create an [ASN1OctetString] from an encoded list of bytes
///
ASN1BitString.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1BitString.fromBytes(super.bytes) : super.fromBytes() {
unusedbits = valueBytes()[0];
stringValue = valueBytes().sublist(1);
}

@override
Uint8List? _encode() {
Uint8List _encode() {
var valBytes = [unusedbits];
valBytes.addAll(stringValue);
_valueByteLength = valBytes.length;
_encodeHeader();
_setValueBytes(valBytes);
return _encodedBytes;
return _encodedBytes!;
}

static String decodeOctetString(Uint8List bytes) =>
13 changes: 6 additions & 7 deletions lib/asn1bmpstring.dart → lib/src/asn1bmpstring.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 BMP String.
@@ -7,19 +7,18 @@ part of asn1lib;
///
class ASN1BMPString extends ASN1Object {
/// The decoded string value
late String stringValue;
late final String stringValue;

///
/// Create an [ASN1BMPString] initialized with String value.
/// Optionally override the tag
///
ASN1BMPString(this.stringValue, {int tag = BMP_STRING_TYPE})
: super(tag: tag);
ASN1BMPString(this.stringValue, {super.tag = BMP_STRING_TYPE});

///
/// Create an [ASN1BMPString] from an encoded list of bytes
///
ASN1BMPString.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1BMPString.fromBytes(super.bytes) : super.fromBytes() {
var octets = valueBytes();
var mergedOctets = <int>[];

@@ -33,7 +32,7 @@ class ASN1BMPString extends ASN1Object {
}

@override
Uint8List? _encode() {
Uint8List _encode() {
var octets = utf8.encode(stringValue);
var doubleOctets = <int>[];

@@ -45,7 +44,7 @@ class ASN1BMPString extends ASN1Object {
_valueByteLength = doubleOctets.length;
_encodeHeader();
_setValueBytes(doubleOctets);
return _encodedBytes;
return _encodedBytes!;
}

@override
16 changes: 7 additions & 9 deletions lib/asn1boolean.dart → lib/src/asn1boolean.dart
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 Boolean
///
class ASN1Boolean extends ASN1Object {
bool? _boolValue;
late final bool booleanValue;

static final ASN1Boolean ASN1TrueBoolean = ASN1Boolean(true);
static final ASN1Boolean ASN1FalseBoolean = ASN1Boolean(false);

bool? get booleanValue => _boolValue;

// ASN1Boolean(this._boolValue,{tag: BOOLEAN_TYPE}):super(tag:BOOLEAN_TYPE) {
ASN1Boolean(this._boolValue, {tag = BOOLEAN_TYPE}) : super(tag: tag) {
ASN1Boolean(this.booleanValue, {super.tag = BOOLEAN_TYPE}) {
_valueByteLength = 1;
}

ASN1Boolean.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
var b = bytes[_valueStartPosition];
_boolValue = (b == BOOLEAN_TRUE_VALUE);
booleanValue = (b == BOOLEAN_TRUE_VALUE);
}

@override
Uint8List? _encode() {
Uint8List _encode() {
super._encodeHeader();
super._setValueBytes(
[_boolValue == true ? BOOLEAN_TRUE_VALUE : BOOLEAN_FALSE_VALUE]);
return _encodedBytes;
[booleanValue ? BOOLEAN_TRUE_VALUE : BOOLEAN_FALSE_VALUE]);
return _encodedBytes!;
}
}
2 changes: 1 addition & 1 deletion lib/asn1constants.dart → lib/src/asn1constants.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

// Sere https://luca.ntop.org/Teaching/Appunti/asn1.html
// tag bytes for various ASN1 BER objects
4 changes: 2 additions & 2 deletions lib/asn1enumerated.dart → lib/src/asn1enumerated.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An enum is encoded as an Integer.
///
class ASN1Enumerated extends ASN1Integer {
ASN1Enumerated(int i, {tag = ENUMERATED_TYPE})
ASN1Enumerated(int i, {int tag = ENUMERATED_TYPE})
: super(BigInt.from(i), tag: tag);
}
2 changes: 1 addition & 1 deletion lib/asn1exception.dart → lib/src/asn1exception.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 Exception
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 GeneralizedTime value.
@@ -10,20 +10,19 @@ part of asn1lib;
///
class ASN1GeneralizedTime extends ASN1Object {
// The decoded date value
late DateTime dateTimeValue;
late final DateTime dateTimeValue;

///
/// Create an [ASN1GeneralizedTime] initialized with DateTime value.
///
/// Optionally override the tag
///
ASN1GeneralizedTime(this.dateTimeValue, {int tag = GENERALIZED_TIME})
: super(tag: tag);
ASN1GeneralizedTime(this.dateTimeValue, {super.tag = GENERALIZED_TIME});

///
/// Create an [ASN1GeneralizedTime] from an encoded list of bytes
///
ASN1GeneralizedTime.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1GeneralizedTime.fromBytes(super.bytes) : super.fromBytes() {
var octets = valueBytes();
var stringValue = ascii.decode(octets);
var year = stringValue.substring(0, 4);
@@ -42,7 +41,7 @@ class ASN1GeneralizedTime extends ASN1Object {
}

@override
Uint8List? _encode() {
Uint8List _encode() {
var utc = dateTimeValue.toUtc();
var year = utc.year.toString();
var month = utc.month.toString();
@@ -57,7 +56,7 @@ class ASN1GeneralizedTime extends ASN1Object {
_valueByteLength = valBytes.length;
_encodeHeader();
_setValueBytes(valBytes);
return _encodedBytes;
return _encodedBytes!;
}

@override
13 changes: 6 additions & 7 deletions lib/asn1ia5string.dart → lib/src/asn1ia5string.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 IA5 String.
@@ -7,30 +7,29 @@ part of asn1lib;
///
class ASN1IA5String extends ASN1Object {
/// The decoded string value
late String stringValue;
late final String stringValue;

///
/// Create an [ASN1IA5String] initialized with String value.
/// Optionally override the tag
///
ASN1IA5String(this.stringValue, {int tag = IA5_STRING_TYPE})
: super(tag: tag);
ASN1IA5String(this.stringValue, {super.tag = IA5_STRING_TYPE});

///
/// Create an [ASN1IA5String] from an encoded list of bytes
///
ASN1IA5String.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1IA5String.fromBytes(super.bytes) : super.fromBytes() {
var octets = valueBytes();
stringValue = ascii.decode(octets);
}

@override
Uint8List? _encode() {
Uint8List _encode() {
var octets = ascii.encode(stringValue);
_valueByteLength = octets.length;
_encodeHeader();
_setValueBytes(octets);
return _encodedBytes;
return _encodedBytes!;
}

@override
30 changes: 14 additions & 16 deletions lib/asn1integer.dart → lib/src/asn1integer.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// ASN1Integer encoding / decoding.
@@ -8,30 +8,28 @@ part of asn1lib;
/// int or BigInt
///
class ASN1Integer extends ASN1Object {
late BigInt _intValue;
late final BigInt valueAsBigInteger;

ASN1Integer(this._intValue, {tag = INTEGER_TYPE}) : super(tag: tag);
ASN1Integer(this.valueAsBigInteger, {super.tag = INTEGER_TYPE});

ASN1Integer.fromInt(int x, {tag = INTEGER_TYPE}) : super(tag: tag) {
_intValue = BigInt.from(x);
ASN1Integer.fromInt(int x, {super.tag = INTEGER_TYPE}) {
valueAsBigInteger = BigInt.from(x);
_encode();
}

ASN1Integer.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
_intValue = decodeBigInt(valueBytes());
ASN1Integer.fromBytes(super.bytes) : super.fromBytes() {
valueAsBigInteger = decodeBigInt(valueBytes());
}

int get intValue => _intValue.toInt();

BigInt? get valueAsBigInteger => _intValue;
int get intValue => valueAsBigInteger.toInt();

@override
Uint8List? _encode() {
var t = encodeBigInt(_intValue);
Uint8List _encode() {
var t = encodeBigInt(valueAsBigInteger);
_valueByteLength = t.length;
super._encodeHeader();
_setValueBytes(t);
return _encodedBytes;
return _encodedBytes!;
}

static Uint8List encodeInt(int x) => encodeBigInt(BigInt.from(x));
@@ -90,7 +88,7 @@ class ASN1Integer extends ASN1Object {
var result = Uint8List(bytes);

number = number.abs();
for (var i = 0, j = bytes - 1; i < (bytes); i++, --j) {
for (var i = 0, j = bytes - 1; i < bytes; i++, --j) {
var x = number.remainder(_b256).toInt();
result[j] = x;
number = number >> 8;
@@ -137,8 +135,8 @@ class ASN1Integer extends ASN1Object {
identical(this, other) ||
other is ASN1Integer &&
runtimeType == other.runtimeType &&
_intValue == other._intValue;
valueAsBigInteger == other.valueAsBigInteger;

@override
int get hashCode => _intValue.hashCode;
int get hashCode => valueAsBigInteger.hashCode;
}
13 changes: 6 additions & 7 deletions lib/asn1ipaddress.dart → lib/src/asn1ipaddress.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 IP Address. This is length-4 array of character codes.
@@ -21,24 +21,23 @@ class ASN1IpAddress extends ASN1OctetString {
///
/// Create an [ASN1IpAddress] from an encoded list of bytes.
///
ASN1IpAddress.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
octets = valueBytes();
ASN1IpAddress.fromBytes(super.bytes) : super.fromBytes() {
_assertValidLength(octets);
}

///
/// Create an [ASN1IpAddress] from an IP Address String such as '192.168.1.1'
///
static ASN1IpAddress fromComponentString(String path, {tag = IP_ADDRESS}) =>
fromComponents(path.split('.').map((v) => int.parse(v)).toList(),
tag: tag);
static ASN1IpAddress fromComponentString(String path,
{int tag = IP_ADDRESS}) =>
fromComponents(path.split('.').map(int.parse).toList(), tag: tag);

///
/// Create an [ASN1IpAddress] from a list of int IP Address octets
/// e.g. [192, 168, 1, 1]
///
static ASN1IpAddress fromComponents(List<int> components,
{tag = IP_ADDRESS}) =>
{int tag = IP_ADDRESS}) =>
ASN1IpAddress(components, tag: tag);

/// Ensure there are no more or less than 4 octets for an IPv4 address
6 changes: 3 additions & 3 deletions lib/asn1length.dart → lib/src/asn1length.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// Class to encode /decode ASN1 length bytes.
@@ -65,14 +65,14 @@ class ASN1Length {
///
static ASN1Length decodeLength(Uint8List encodedBytes) {
var valueStartPosition = 2; //default
var length = (encodedBytes[1] & 0x7F);
var length = encodedBytes[1] & 0x7F;
if (length != encodedBytes[1]) {
var numLengthBytes = length;

length = 0;
for (var i = 0; i < numLengthBytes; i++) {
length <<= 8;
length |= (encodedBytes[valueStartPosition++] & 0xFF);
length |= encodedBytes[valueStartPosition++] & 0xFF;
}
}
/*
6 changes: 3 additions & 3 deletions lib/asn1null.dart → lib/src/asn1null.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 Null Object
@@ -7,9 +7,9 @@ class ASN1Null extends ASN1Object {
@override
Uint8List get _encodedBytes => Uint8List.fromList([tag, 0x00]);

ASN1Null({tag = NULL_TYPE}) : super(tag: tag);
ASN1Null({super.tag = NULL_TYPE});

ASN1Null.fromBytes(Uint8List bytes) : super.fromBytes(bytes);
ASN1Null.fromBytes(super.bytes) : super.fromBytes();

@override
Uint8List _encode() => Uint8List.fromList([tag, 0x00]);
13 changes: 6 additions & 7 deletions lib/asn1numericstring.dart → lib/src/asn1numericstring.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 Numeric String
@@ -8,15 +8,14 @@ part of asn1lib;
///
class ASN1NumericString extends ASN1Object {
// The decoded string value
late String stringValue;
late final String stringValue;

///
/// Create an [ASN1NumericString] initialized with String value.
///
/// Optionally override the tag
///
ASN1NumericString(this.stringValue, {int tag = NUMERIC_STRING_TYPE})
: super(tag: tag) {
ASN1NumericString(this.stringValue, {super.tag = NUMERIC_STRING_TYPE}) {
if (!RegExp(r'^[\d\s]*$').hasMatch(stringValue)) {
throw ASN1Exception(
'ASN1 NumericString should only include digits or spaces');
@@ -26,18 +25,18 @@ class ASN1NumericString extends ASN1Object {
///
/// Create an [ASN1NumericString] from an encoded list of bytes.
///
ASN1NumericString.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1NumericString.fromBytes(super.bytes) : super.fromBytes() {
var octets = valueBytes();
stringValue = ascii.decode(octets);
}

@override
Uint8List? _encode() {
Uint8List _encode() {
var octets = ascii.encode(stringValue);
_valueByteLength = octets.length;
_encodeHeader();
_setValueBytes(octets);
return _encodedBytes;
return _encodedBytes!;
}

@override
27 changes: 13 additions & 14 deletions lib/asn1object.dart → lib/src/asn1object.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// Holds the encoded and decoded representation of an ASN1 object.
@@ -12,8 +12,7 @@ part of asn1lib;
///
class ASN1Object {
/// The BER tag representing this object
final int _tag;
int get tag => _tag;
final int tag;

///
/// The ASN1 encoded bytes.
@@ -44,15 +43,15 @@ class ASN1Object {
bool get isEncoded => _encodedBytes != null;

/// Create an ASN1Object. Optionally set the tag
ASN1Object({int tag = 0}) : _tag = tag;
ASN1Object({this.tag = 0});

///
/// Create an object that encapsulates a set of value bytes that are already encoded.
///
/// This is used in LDAP (for example) to encode a CHOICE type
/// The supplied valBytes is the encoded value of the choice element
///
ASN1Object.preEncoded(int tag, Uint8List valBytes) : _tag = tag {
ASN1Object.preEncoded(this.tag, Uint8List valBytes) {
_valueByteLength = valBytes.length;
_encodeHeader();
_encodedBytes!.setRange(
@@ -69,7 +68,7 @@ class ASN1Object {
/// byte stream we dont always know how long an object is
/// until we complete parsing it).
///
ASN1Object.fromBytes(Uint8List bytes) : _tag = bytes[0] {
ASN1Object.fromBytes(Uint8List bytes) : tag = bytes[0] {
_encodedBytes = bytes;
_initFromBytes();
}
@@ -92,13 +91,13 @@ class ASN1Object {
/// next object starts in the stream.
///
////
int get totalEncodedByteLength => _valueStartPosition + _valueByteLength!;
int get totalEncodedByteLength => _valueStartPosition + _valueByteLength;

///
/// Length of the encoded value bytes. This does not include the length of
/// the tag or length fields. See [totalEncodedByteLength].
///
int? _valueByteLength;
late int _valueByteLength;

///
/// The index where the value bytes start. This is the position after the tag + length bytes.
@@ -116,23 +115,23 @@ class ASN1Object {
/// calling this. We need this know how big to make the encoded object array. Subclasses are
/// responsible for encoding their value representations using [encodeBigInt]
///
Uint8List? _encodeHeader() {
Uint8List _encodeHeader() {
if (_encodedBytes == null) {
var lenEnc = ASN1Length.encodeLength(_valueByteLength!);
_encodedBytes = Uint8List(1 + lenEnc.length + _valueByteLength!);
var lenEnc = ASN1Length.encodeLength(_valueByteLength);
_encodedBytes = Uint8List(1 + lenEnc.length + _valueByteLength);
_encodedBytes![0] = tag;
_encodedBytes!.setRange(1, 1 + lenEnc.length, lenEnc, 0);
_valueStartPosition = 1 + lenEnc.length;
}
return _encodedBytes;
return _encodedBytes!;
}

///
/// Trigger encoding of the object. After calling this the encoded bytes will be available in [encodedBytes].
///
/// Subclasses will need to override this.
///
Uint8List? _encode() => _encodeHeader();
Uint8List _encode() => _encodeHeader();

///
/// Return just the value bytes.
@@ -150,7 +149,7 @@ class ASN1Object {
/// some other tags like BitString include padding in their valueBytes.
/// This method always returns the unpadded contentBytes.
///
Uint8List? contentBytes() => valueBytes();
Uint8List contentBytes() => valueBytes();

///
/// Subclasses can call this to set the value bytes
24 changes: 12 additions & 12 deletions lib/asn1objectidentifier.dart → lib/src/asn1objectidentifier.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 Object Identifier
///
class ASN1ObjectIdentifier extends ASN1Object {
static final Map<String, String> DN = {
static const Map<String, String> DN = {
'cn': '2.5.4.3',
'sn': '2.5.4.4',
'c': '2.5.4.6',
@@ -58,12 +58,12 @@ class ASN1ObjectIdentifier extends ASN1Object {
'ecdsaWithSHA256': '1.2.840.10045.4.3.2'
};

late List<int> oi;
late final List<int> oi;

String? identifier;

ASN1ObjectIdentifier(this.oi, {this.identifier, tag = OBJECT_IDENTIFIER})
: super(tag: tag);
ASN1ObjectIdentifier(this.oi,
{this.identifier, super.tag = OBJECT_IDENTIFIER});

///
/// Instantiate a [ASN1ObjectIdentifier] from the given [bytes].
@@ -123,7 +123,7 @@ class ASN1ObjectIdentifier extends ASN1Object {
}

@override
Uint8List? _encode() {
Uint8List _encode() {
var valBytes = <int>[oi[0] * 40 + oi[1]];

for (var ci = 2; ci < oi.length; ci++) {
@@ -146,16 +146,15 @@ class ASN1ObjectIdentifier extends ASN1Object {
_valueByteLength = valBytes.length;
super._encodeHeader();
_setValueBytes(valBytes);
return _encodedBytes;
return _encodedBytes!;
}

static ASN1ObjectIdentifier fromComponentString(String path,
{tag = OBJECT_IDENTIFIER}) =>
fromComponents(path.split('.').map((v) => int.parse(v)).toList(),
tag: tag);
{int tag = OBJECT_IDENTIFIER}) =>
fromComponents(path.split('.').map(int.parse).toList(), tag: tag);

static ASN1ObjectIdentifier fromComponents(List<int> components,
{tag = OBJECT_IDENTIFIER}) {
{int tag = OBJECT_IDENTIFIER}) {
assert(components.length >= 2);
assert(components[0] < 3);
assert(components[1] < 39);
@@ -166,7 +165,8 @@ class ASN1ObjectIdentifier extends ASN1Object {

static final _names = <String, ASN1ObjectIdentifier>{};

static ASN1ObjectIdentifier fromName(String name, {tag = OBJECT_IDENTIFIER}) {
static ASN1ObjectIdentifier fromName(String name,
{int tag = OBJECT_IDENTIFIER}) {
name = name.toLowerCase();

for (var entry in _names.entries) {
15 changes: 7 additions & 8 deletions lib/asn1octetstring.dart → lib/src/asn1octetstring.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 Octet String. This is an array of character codes.
///
class ASN1OctetString extends ASN1Object {
/// The decoded string value
late Uint8List octets;
late final Uint8List octets;

@override
Uint8List? contentBytes() => octets;
Uint8List contentBytes() => octets;

///
/// Create an [ASN1OctetString] initialized with a [String] or a [List<int>].
/// Optionally override the tag
///
ASN1OctetString(dynamic octets, {int tag = OCTET_STRING_TYPE})
: super(tag: tag) {
ASN1OctetString(dynamic octets, {super.tag = OCTET_STRING_TYPE}) {
if (octets is String) {
this.octets = Uint8List.fromList(octets.codeUnits);
} else if (octets is Uint8List) {
@@ -31,7 +30,7 @@ class ASN1OctetString extends ASN1Object {
///
/// Create an [ASN1OctetString] from an encoded list of bytes.
///
ASN1OctetString.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1OctetString.fromBytes(super.bytes) : super.fromBytes() {
octets = valueBytes();
}

@@ -41,13 +40,13 @@ class ASN1OctetString extends ASN1Object {
String get stringValue => String.fromCharCodes(octets);

@override
Uint8List? _encode() {
Uint8List _encode() {
_valueByteLength = octets.length;
_encodeHeader();
_setValueBytes(octets);
//this.encodedBytes.setRange(valueStartPosition,
// valueStartPosition + valBytes.length, valBytes);
return _encodedBytes;
return _encodedBytes!;
}

@override
6 changes: 4 additions & 2 deletions lib/asn1parser.dart → lib/src/asn1parser.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// Parses ASN1 BER Encoded bytes to create ASN1 Objects
@@ -38,7 +38,7 @@ class ASN1Parser {
var subBytes = Uint8List.view(_bytes.buffer, offset, len);
//print("parser _bytes=${_bytes} position=${_position} len=$l bytes=${hex(subBytes)}");

late ASN1Object obj;
final ASN1Object obj;

switch (tag & 0xc0) {
// get highest 2 bits - these are the type
@@ -59,6 +59,8 @@ class ASN1Parser {
case CONTEXT_SPECIFIC_CLASS:
obj = ASN1Object.fromBytes(subBytes);
break;
default:
throw UnimplementedError();
}

_position = _position + obj.totalEncodedByteLength;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 Printable String.
@@ -8,31 +8,30 @@ part of asn1lib;
///
class ASN1PrintableString extends ASN1Object {
// The decoded string value
late String stringValue;
late final String stringValue;

///
/// Create an [ASN1PrintableString] initialized with String value.
///
/// Optionally override the tag
///
ASN1PrintableString(this.stringValue, {int tag = PRINTABLE_STRING_TYPE})
: super(tag: tag);
ASN1PrintableString(this.stringValue, {super.tag = PRINTABLE_STRING_TYPE});

///
/// Create an [ASN1PrintableString] from an encoded list of bytes.
///
ASN1PrintableString.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1PrintableString.fromBytes(super.bytes) : super.fromBytes() {
var octets = valueBytes();
stringValue = ascii.decode(octets);
}

@override
Uint8List? _encode() {
Uint8List _encode() {
var octets = ascii.encode(stringValue);
_valueByteLength = octets.length;
_encodeHeader();
_setValueBytes(octets);
return _encodedBytes;
return _encodedBytes!;
}

@override
12 changes: 6 additions & 6 deletions lib/asn1sequence.dart → lib/src/asn1sequence.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// Represents a ASN1 BER encoded sequence.
@@ -15,7 +15,7 @@ class ASN1Sequence extends ASN1Object {
/// Note that bytes array b could be longer than the actual encoded sequence - in which case
/// we ignore any remaining bytes.
///
ASN1Sequence.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1Sequence.fromBytes(super.bytes) : super.fromBytes() {
if (isUniversal(tag) && !isSequence(tag)) {
throw ASN1Exception('The tag $tag does not look like a sequence type');
}
@@ -25,7 +25,7 @@ class ASN1Sequence extends ASN1Object {
///
/// Create a new empty ASN1 Sequence. Optionally override the default tag
///
ASN1Sequence({int tag = CONSTRUCTED_SEQUENCE_TYPE}) : super(tag: tag);
ASN1Sequence({super.tag = CONSTRUCTED_SEQUENCE_TYPE});

///
/// Add an [ASN1Object] to the sequence. Objects will be serialized to BER in the order they were added
@@ -35,7 +35,7 @@ class ASN1Sequence extends ASN1Object {
}

@override
Uint8List? _encode() {
Uint8List _encode() {
_valueByteLength = _childLength();
super._encodeHeader();
var i = _valueStartPosition;
@@ -45,7 +45,7 @@ class ASN1Sequence extends ASN1Object {
encodedBytes.setRange(i, i + b.length, b);
i += b.length;
}
return _encodedBytes;
return _encodedBytes!;
}

///
@@ -54,7 +54,7 @@ class ASN1Sequence extends ASN1Object {
int _childLength() {
var l = 0;
for (var obj in elements) {
l += obj._encode()!.length;
l += obj._encode().length;
}
return l;
}
10 changes: 5 additions & 5 deletions lib/asn1set.dart → lib/src/asn1set.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1Set.
@@ -11,14 +11,14 @@ class ASN1Set extends ASN1Object {
///
/// Note that bytes could be longer than the actual sequence - in which case we would ignore any remaining bytes
///
ASN1Set.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1Set.fromBytes(super.bytes) : super.fromBytes() {
if (!isSet(tag)) {
throw ASN1Exception('The tag $tag does not look like a set type');
}
_decodeSet();
}

ASN1Set({int tag = CONSTRUCTED_SET_TYPE}) : super(tag: tag);
ASN1Set({super.tag = CONSTRUCTED_SET_TYPE});

///
/// Add an element to the set
@@ -28,7 +28,7 @@ class ASN1Set extends ASN1Object {
}

@override
Uint8List? _encode() {
Uint8List _encode() {
_valueByteLength = _childLength();
//super._encode();

@@ -39,7 +39,7 @@ class ASN1Set extends ASN1Object {
encodedBytes.setRange(i, i + b.length, b);
i += b.length;
}
return _encodedBytes;
return _encodedBytes!;
}

///
13 changes: 6 additions & 7 deletions lib/asn1teletextstring.dart → lib/src/asn1teletextstring.dart
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 Teletext String.
///
class ASN1TeletextString extends ASN1Object {
// The decoded string value
late String stringValue;
late final String stringValue;

///
/// Create an [ASN1TeletextString] initialized with String value.
///
/// Optionally override the tag
///
ASN1TeletextString(this.stringValue, {int tag = UTF8_STRING_TYPE})
: super(tag: tag);
ASN1TeletextString(this.stringValue, {super.tag = UTF8_STRING_TYPE});

///
/// Create an [ASN1TeletextString] from an encoded list of bytes
///
ASN1TeletextString.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1TeletextString.fromBytes(super.bytes) : super.fromBytes() {
var octets = valueBytes();
stringValue = ascii.decode(octets);
}

@override
Uint8List? _encode() {
Uint8List _encode() {
var octets = ascii.encode(stringValue);
_valueByteLength = octets.length;
_encodeHeader();
_setValueBytes(octets);
return _encodedBytes;
return _encodedBytes!;
}

@override
12 changes: 6 additions & 6 deletions lib/asn1utctime.dart → lib/src/asn1utctime.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 UtcTime value.
@@ -10,19 +10,19 @@ part of asn1lib;
///
class ASN1UtcTime extends ASN1Object {
// The decoded date value
late DateTime dateTimeValue;
late final DateTime dateTimeValue;

///
/// Create an [ASN1UtcTime] initialized with DateTime value.
///
/// Optionally override the tag
///
ASN1UtcTime(this.dateTimeValue, {int tag = UTC_TIME_TYPE}) : super(tag: tag);
ASN1UtcTime(this.dateTimeValue, {super.tag = UTC_TIME_TYPE});

///
/// Create an [ASN1UtcTime] from an encoded list of bytes
///
ASN1UtcTime.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1UtcTime.fromBytes(super.bytes) : super.fromBytes() {
// The DateTime.parse() function wants:
// * Either T or space as separator between date and time.
// * Full year with 4 digits (the UtcTime in ASN.1 has only two digits for year).
@@ -41,7 +41,7 @@ class ASN1UtcTime extends ASN1Object {
}

@override
Uint8List? _encode() {
Uint8List _encode() {
var utc = dateTimeValue.toUtc();
var year = utc.year.toString().substring(2).padLeft(2, '0');
var month = utc.month.toString().padLeft(2, '0');
@@ -56,7 +56,7 @@ class ASN1UtcTime extends ASN1Object {
_valueByteLength = valBytes.length;
_encodeHeader();
_setValueBytes(valBytes);
return _encodedBytes;
return _encodedBytes!;
}

@override
13 changes: 6 additions & 7 deletions lib/asn1utf8string.dart → lib/src/asn1utf8string.dart
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
part of asn1lib;
part of '../asn1lib.dart';

///
/// An ASN1 UTF8 String.
///
class ASN1UTF8String extends ASN1Object {
// The decoded string value
late String utf8StringValue;
late final String utf8StringValue;

///
/// Create an [ASN1UTF8String] initialized with String value.
///
/// Optionally override the tag
///
ASN1UTF8String(this.utf8StringValue, {int tag = UTF8_STRING_TYPE})
: super(tag: tag);
ASN1UTF8String(this.utf8StringValue, {super.tag = UTF8_STRING_TYPE});

///
/// Create an [ASN1UTF8String] from an encoded list of bytes
///
ASN1UTF8String.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
ASN1UTF8String.fromBytes(super.bytes) : super.fromBytes() {
var octets = valueBytes();
utf8StringValue = utf8.decode(octets);
}

@override
Uint8List? _encode() {
Uint8List _encode() {
var octets = utf8.encode(utf8StringValue);
_valueByteLength = octets.length;
_encodeHeader();
_setValueBytes(octets);
return _encodedBytes;
return _encodedBytes!;
}

@override
4 changes: 2 additions & 2 deletions lib/asn1util.dart → lib/src/asn1util.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
part of asn1lib;
part of '../asn1lib.dart';

class ASN1Util {
// convert a list to a hex string. Used for debugging ASN1 output
@@ -18,7 +18,7 @@ class ASN1Util {
if (x is List) {
return listToString(x as List<int>);
} else {
return x.toRadixString(16);
return (x as int).toRadixString(16);
}
}

6 changes: 3 additions & 3 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
name: asn1lib
version: 1.4.1
version: 1.5.0
description: An ASN1 parser library for Dart. Encodes / decodes from ASN1 Objects to BER bytes
homepage: https://github.com/wstrange/asn1lib
environment:
sdk: '>=2.12.0 <4.0.0'
sdk: ^3.0.0

dev_dependencies:
dart_flutter_team_lints: ^1.0.0
test: ^1.22.0
lints: ^2.0.0

# PEM certs are for testing - and are OK to publish
false_secrets:
3 changes: 2 additions & 1 deletion test/app_test.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:test/test.dart';

import 'package:asn1lib/asn1lib.dart';
import 'package:test/test.dart';

void main() {
// https://github.com/wstrange/asn1lib/issues/57
2 changes: 1 addition & 1 deletion test/asn1_generalized_time_test.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';
import 'package:test/test.dart';

void main() {
test('encode', () {
6 changes: 3 additions & 3 deletions test/asn1_integer_test.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';
import 'package:test/test.dart';

// list of test value pairs. The first value is the integer to encode, the
// second is expected length of the content bytes (excludes type and length).
final List<int> intTestValues = [
const List<int> intTestValues = [
0x00000000,
1,
0x00000001,
@@ -189,7 +189,7 @@ void testPair(int x, int expectedLength) {
//print(
// 'Value 0x${x.toRadixString(16)},$expectedLength. Encoded Bytes = ${_printBytes(int1.encodedBytes.sublist(2))}');

var contentLength = int1.contentBytes()!.length;
var contentLength = int1.contentBytes().length;
expect(contentLength, expectedLength,
reason: 'expected number of content bytes is wrong');
var int2 = ASN1Integer.fromBytes(int1.encodedBytes);
4 changes: 1 addition & 3 deletions test/asn1_object_prencoded_test.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
library asn1test;

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';
import 'package:test/test.dart';

void main() {
test('support optional tagging', () {
4 changes: 1 addition & 3 deletions test/asn1_parser_test.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
library asn1test;

import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';
import 'package:test/test.dart';

void main() {
test('ASN1Parser Encode/Decode Test', () {
2 changes: 1 addition & 1 deletion test/asn1_teletext_string_test.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';
import 'package:test/test.dart';

void main() {
test('encode', () {
5 changes: 2 additions & 3 deletions test/asn1bit_string.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
library asn1test;
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';
import 'dart:typed_data';
import 'package:test/test.dart';

void main() {
test('Decode 0 unused bits', () {
10 changes: 4 additions & 6 deletions test/asn1element_test.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
library asn1test;
import 'dart:math';
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';

import 'dart:typed_data';
import 'dart:math';
import 'package:test/test.dart';

void main() {
test('Test integer encoding', () {
// key = integer to encode, val = expected encoding bytes
var m = {};
var m = <int, List<int>>{};
m[0] = [0x0];
m[127] = [0x7f];
m[128] = [0x0, 0x80];
6 changes: 2 additions & 4 deletions test/asn1ia5string_test.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
library asn1test;
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';

import 'dart:typed_data';
import 'package:test/test.dart';

void main() {
test('encode', () {
6 changes: 2 additions & 4 deletions test/asn1ipaddress_test.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
library asn1test;
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';

import 'dart:typed_data';
import 'package:test/test.dart';

void main() {
test('IpAddress default constructor', () {
4 changes: 1 addition & 3 deletions test/asn1null_test.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
library asn1test;

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';
import 'package:test/test.dart';

void main() {
test('tagless', () {
6 changes: 2 additions & 4 deletions test/asn1numericstring_test.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
library asn1test;
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';

import 'dart:typed_data';
import 'package:test/test.dart';

void main() {
test('encode', () {
6 changes: 2 additions & 4 deletions test/asn1objectidentifier_test.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
library asn1test;
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';

import 'dart:typed_data';
import 'package:test/test.dart';

// many tests from - http://luca.ntop.org/Teaching/Appunti/asn1.html
// print(a.oi.map((x) => '0x' + x.toRadixString(16).padLeft(2, '0')));
6 changes: 2 additions & 4 deletions test/asn1utf8string_test.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
library asn1test;
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';

import 'dart:typed_data';
import 'package:test/test.dart';

void main() {
test('encode', () {
10 changes: 4 additions & 6 deletions test/bigint_test.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
library asn1test;

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';

import 'dart:convert';
import 'dart:typed_data';
import 'dart:io';
import 'dart:typed_data';

import 'package:asn1lib/asn1lib.dart';
import 'package:test/test.dart';

void main() {
test('rsa private key', () {
4 changes: 1 addition & 3 deletions test/der_encoding_test.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
library asn1test.der;

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';
import 'package:test/test.dart';

void main() {
group('der-encoding', () {
4 changes: 3 additions & 1 deletion test/issue_61.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'dart:convert';
import 'dart:typed_data';

import 'package:asn1lib/asn1lib.dart';
import 'package:test/test.dart';
import 'dart:convert';

import '../example/main.dart'; // for decodePEM

// Test cases for https://github.com/wstrange/asn1lib/issues/61
2 changes: 1 addition & 1 deletion test/issue_62_test.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';
import 'package:test/test.dart';

// test for issue https://github.com/wstrange/asn1lib/issues/62
void main() {
11 changes: 6 additions & 5 deletions test/pem_encoded_rsa_keys_test.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import 'dart:convert';
import 'package:test/test.dart';
import 'package:asn1lib/asn1lib.dart';
import 'dart:typed_data';

import 'package:asn1lib/asn1lib.dart';
import 'package:test/test.dart';

void main() {
var publicKeyDER = decodePEM('''-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1W25XAj9GvCvSY7JzVAh
@@ -202,7 +203,7 @@ L2fTYScBC9dHB+QBDm/c/oYpIj9tsKuxNJO0Io+b1cIziWqOytwlHnzAx9X/KGeB

expect(publicKeyBitString.valueBytes().length, 271);

asn1Parser = ASN1Parser(publicKeyBitString.contentBytes()!);
asn1Parser = ASN1Parser(publicKeyBitString.contentBytes());
var pkSeq = asn1Parser.nextObject() as ASN1Sequence;

var expected = BigInt.from(65537);
@@ -250,7 +251,7 @@ c0 f1 cc 0e 1a 2c a6 52-b1 ee 6e a3 fe 21 cb e5
var privateKey = topLevelSeq.elements[2];
expect(privateKey.valueBytes().length, 1193);

asn1Parser = ASN1Parser(privateKey.contentBytes()!);
asn1Parser = ASN1Parser(privateKey.contentBytes());
var pkSeq = asn1Parser.nextObject() as ASN1Sequence;
version = pkSeq.elements[0];
var modulus = pkSeq.elements[1] as ASN1Integer;
@@ -376,7 +377,7 @@ f0:57:25:e7:78:12:17:5d:f5
});
}

Uint8List decodePEM(pem) {
Uint8List decodePEM(String pem) {
var startsWith = [
'-----BEGIN PUBLIC KEY-----',
'-----BEGIN PRIVATE KEY-----',

0 comments on commit bea77eb

Please sign in to comment.