189 lines
5.6 KiB
Dart
189 lines
5.6 KiB
Dart
import 'dart:typed_data';
|
|
|
|
import 'package:pointycastle/asn1/asn1_encoding_rule.dart';
|
|
import 'package:pointycastle/asn1/asn1_object.dart';
|
|
import 'package:pointycastle/asn1/asn1_tags.dart';
|
|
import 'package:pointycastle/asn1/object_identifiers.dart';
|
|
import 'package:pointycastle/asn1/unsupported_asn1_encoding_rule_exception.dart';
|
|
import 'package:pointycastle/asn1/unsupported_object_identifier_exception.dart';
|
|
|
|
class ASN1ObjectIdentifier extends ASN1Object {
|
|
///
|
|
/// The object identifier integer values
|
|
///
|
|
List<int>? objectIdentifier;
|
|
|
|
///
|
|
/// The String representation of the [objectIdentifier]
|
|
///
|
|
String? objectIdentifierAsString;
|
|
|
|
///
|
|
/// The readable representation of the [objectIdentifier]
|
|
///
|
|
String? readableName;
|
|
|
|
///
|
|
/// Create an [ASN1ObjectIdentifier] entity with the given [objectIdentifier].
|
|
///
|
|
ASN1ObjectIdentifier(this.objectIdentifier,
|
|
{int tag = ASN1Tags.OBJECT_IDENTIFIER})
|
|
: super(tag: tag) {
|
|
objectIdentifierAsString = objectIdentifier!.join('.');
|
|
}
|
|
|
|
///
|
|
/// Creates an [ASN1ObjectIdentifier] entity from the given [encodedBytes].
|
|
///
|
|
ASN1ObjectIdentifier.fromBytes(Uint8List super.encodedBytes)
|
|
: super.fromBytes() {
|
|
var value = 0;
|
|
var first = true;
|
|
BigInt? bigValue;
|
|
var list = <int>[];
|
|
var sb = StringBuffer();
|
|
for (var element in valueBytes!) {
|
|
var b = element & 0xff;
|
|
if (value < 0x80000000000000) {
|
|
value = value * 128 + (b & 0x7f);
|
|
if ((b & 0x80) == 0) {
|
|
if (first) {
|
|
var truncated = value ~/ 40;
|
|
if (truncated < 2) {
|
|
list.add(truncated);
|
|
sb.write(truncated);
|
|
value -= truncated * 40;
|
|
} else {
|
|
list.add(2);
|
|
sb.write('2');
|
|
value -= 80;
|
|
}
|
|
first = false;
|
|
}
|
|
list.add(value);
|
|
sb.write('.$value');
|
|
value = 0;
|
|
}
|
|
} else {
|
|
bigValue ??= BigInt.from(value);
|
|
bigValue = bigValue << (7);
|
|
bigValue = bigValue | BigInt.from(b & 0x7f);
|
|
if ((b & 0x80) == 0) {
|
|
sb.write('.$bigValue');
|
|
bigValue = null;
|
|
value = 0;
|
|
}
|
|
}
|
|
}
|
|
objectIdentifierAsString = sb.toString();
|
|
objectIdentifier = Uint8List.fromList(list);
|
|
var identifier =
|
|
ObjectIdentifiers.getIdentifierByIdentifier(objectIdentifierAsString);
|
|
if (identifier != null) {
|
|
readableName = identifier['readableName'] as String?;
|
|
}
|
|
}
|
|
|
|
///
|
|
/// Creates an [ASN1ObjectIdentifier] entity from the given [name].
|
|
///
|
|
/// Example:
|
|
/// ```
|
|
/// var oi = ASN1ObjectIdentifier.fromName('ecdsaWithSHA256');
|
|
/// ```
|
|
///
|
|
/// Throws an [UnsupportedObjectIdentifierException] if the given [name] is not supported
|
|
///
|
|
ASN1ObjectIdentifier.fromName(String name) {
|
|
tag = ASN1Tags.OBJECT_IDENTIFIER;
|
|
var identifier = ObjectIdentifiers.getIdentifierByName(name);
|
|
if (identifier == null) {
|
|
throw UnsupportedObjectIdentifierException(name);
|
|
}
|
|
objectIdentifierAsString = identifier['identifierString'] as String?;
|
|
readableName = identifier['readableName'] as String?;
|
|
objectIdentifier = identifier['identifier'] as List<int>?;
|
|
}
|
|
|
|
///
|
|
/// Creates an [ASN1ObjectIdentifier] entity from the given [objectIdentifierAsString].
|
|
///
|
|
/// Example:
|
|
/// ```
|
|
/// var oi = ASN1ObjectIdentifier.fromName('2.5.4.3');
|
|
/// ```
|
|
///
|
|
/// Throws an [UnsupportedObjectIdentifierException] if the given [objectIdentifierAsString] is not supported
|
|
///
|
|
ASN1ObjectIdentifier.fromIdentifierString(this.objectIdentifierAsString,
|
|
{int tag = ASN1Tags.OBJECT_IDENTIFIER})
|
|
: super(tag: tag) {
|
|
var identifier =
|
|
ObjectIdentifiers.getIdentifierByIdentifier(objectIdentifierAsString);
|
|
if (identifier != null) {
|
|
objectIdentifierAsString = identifier['identifierString'] as String?;
|
|
readableName = identifier['readableName'] as String?;
|
|
objectIdentifier = identifier['identifier'] as List<int>?;
|
|
} else {
|
|
var splittedInts = objectIdentifierAsString!.split('.');
|
|
objectIdentifier = <int>[];
|
|
for (var i in splittedInts) {
|
|
objectIdentifier!.add(int.parse(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
///
|
|
/// Encodes this ASN1Object depending on the given [encodingRule]
|
|
///
|
|
/// If no [ASN1EncodingRule] is given, ENCODING_DER will be used.
|
|
///
|
|
/// Supported encoding rules are :
|
|
/// * [ASN1EncodingRule.ENCODING_DER]
|
|
///
|
|
/// Throws an [UnsupportedAsn1EncodingRuleException] if the given [encodingRule] is not supported.
|
|
///
|
|
@override
|
|
Uint8List encode(
|
|
{ASN1EncodingRule encodingRule = ASN1EncodingRule.ENCODING_DER}) {
|
|
if (encodingRule != ASN1EncodingRule.ENCODING_DER) {
|
|
throw UnsupportedAsn1EncodingRuleException(encodingRule);
|
|
}
|
|
var oi = <int>[];
|
|
oi.add(objectIdentifier![0] * 40 + objectIdentifier![1]);
|
|
|
|
for (var ci = 2; ci < objectIdentifier!.length; ci++) {
|
|
var position = oi.length;
|
|
var v = objectIdentifier![ci];
|
|
assert(v >= 0);
|
|
|
|
var first = true;
|
|
do {
|
|
var remainder = v & 127;
|
|
v = v >> 7;
|
|
if (first) {
|
|
first = false;
|
|
} else {
|
|
remainder |= 0x80;
|
|
}
|
|
|
|
oi.insert(position, remainder);
|
|
} while (v > 0);
|
|
}
|
|
|
|
valueBytes = Uint8List.fromList(oi);
|
|
valueByteLength = oi.length;
|
|
|
|
return super.encode();
|
|
}
|
|
|
|
@override
|
|
String dump({int spaces = 0}) {
|
|
var sb = StringBuffer();
|
|
for (var i = 0; i < spaces; i++) {
|
|
sb.write(' ');
|
|
}
|
|
sb.write('OBJECT IDENTIFIER $objectIdentifierAsString $readableName');
|
|
return sb.toString();
|
|
}
|
|
}
|