updated X509Certificate class

This commit is contained in:
Lorenzo Pichilli 2020-06-16 00:25:29 +02:00
parent 62d14039be
commit b0c06c6146
7 changed files with 132 additions and 28 deletions

View File

@ -26,6 +26,7 @@
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/build" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_inappwebview/example/ios/Flutter/App.framework/flutter_assets/packages" />
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/.pub" />
<excludeFolder url="file://$MODULE_DIR$/flutter_inappbrowser_tests/build" />

View File

@ -25,6 +25,20 @@ class ASN1Object {
return null;
}
ASN1Object firstSub() {
if (subCount() > 0) {
return sub.first;
}
return null;
}
ASN1Object lastSub() {
if (subCount() > 0) {
return sub.last;
}
return null;
}
int subCount() {
return sub?.length ?? 0;
}

View File

@ -0,0 +1,55 @@
class KeyUsage {
final int _value;
const KeyUsage._internal(this._value);
static List<KeyUsage> values = [
KeyUsage.digitalSignature,
KeyUsage.nonRepudiation,
KeyUsage.keyEncipherment,
KeyUsage.dataEncipherment,
KeyUsage.keyAgreement,
KeyUsage.keyCertSign,
KeyUsage.cRLSign,
KeyUsage.encipherOnly,
KeyUsage.decipherOnly,
];
static KeyUsage fromIndex(int value) {
return KeyUsage.values.firstWhere((element) => element.toValue() == value, orElse: () => null);
}
int toValue() => _value;
String name() => _KeyUsageMapName[this._value];
@override
String toString() => "($_value, ${name()})";
static const digitalSignature = const KeyUsage._internal(0);
static const nonRepudiation = const KeyUsage._internal(1);
static const keyEncipherment = const KeyUsage._internal(2);
static const dataEncipherment = const KeyUsage._internal(3);
static const keyAgreement = const KeyUsage._internal(4);
static const keyCertSign = const KeyUsage._internal(5);
static const cRLSign = const KeyUsage._internal(6);
static const encipherOnly = const KeyUsage._internal(7);
static const decipherOnly = const KeyUsage._internal(8);
bool operator ==(value) => value == _value;
@override
int get hashCode => _value.hashCode;
static const Map<int, String> _KeyUsageMapName = {
0: "digitalSignature",
1: "nonRepudiation",
2: "keyEncipherment",
3: "dataEncipherment",
4: "keyAgreement",
5: "keyCertSign",
6: "cRLSign",
7: "encipherOnly",
8: "decipherOnly",
};
}

View File

@ -3,6 +3,7 @@ export 'asn1_distinguished_names.dart';
export 'asn1_identifier.dart';
export 'asn1_object.dart';
export 'oid.dart';
export 'key_usage.dart';
export 'x509_certificate.dart';
export 'x509_extension.dart';
export 'x509_public_key.dart';

View File

@ -236,14 +236,15 @@ class OID {
"1.2.840.113549.1.1.11": "sha256WithRSAEncryption",
"1.2.840.113549.1.1.12": "sha384WithRSAEncryption",
"1.2.840.113549.1.1.13": "sha512WithRSAEncryption",
"1.2.840.113549.1.7.1": "data",
"1.2.840.113549.1.7.2": "signedData",
"1.2.840.113549.1.7.1": "pkcs7data",
"1.2.840.113549.1.7.2": "pkcs7signedData",
"1.2.840.113549.1.7.3": "pkcs7envelopedData",
"1.2.840.113549.1.9.1": "emailAddress",
"1.2.840.113549.1.9.16.2.47": "signingCertificateV2",
"1.2.840.113549.1.9.3": "contentType",
"1.2.840.113549.1.9.4": "messageDigest",
"1.2.840.113549.1.9.5": "signingTime",
"1.2.840.10040.4.3": 'dsa-with-sha1',
"1.2.840.10040.4.3": "dsaWithSha1",
"1.3.6.1.4.1.11129.2.4.2": "certificateExtension",
"1.3.6.1.4.1.311.60.2.1.2": "jurisdictionOfIncorporationSP",
"1.3.6.1.4.1.311.60.2.1.3": "jurisdictionOfIncorporationC",
@ -264,7 +265,7 @@ class OID {
"1.2.840.113549.2.5": "md5",
"2.16.840.1.113733.1.7.23.6": "VeriSign EV policy",
"2.23.140.1.1": "extendedValidation",
"2.23.140.1.2.2": "extendedValidation",
"2.23.140.1.2.2": "organizationValidated",
"2.5.29.14": "subjectKeyIdentifier",
"2.5.29.15": "keyUsage",
"2.5.29.17": "subjectAltName",

View File

@ -228,16 +228,16 @@ class X509Certificate {
return value;
}
/// Gets the signature value (the raw signature bits) from the certificate.
///Gets the signature value (the raw signature bits) from the certificate.
List<int> get signature => asn1[0].subAtIndex(2)?.value as List<int>;
/// Gets the signature algorithm name for the certificate signature algorithm.
///Gets the signature algorithm name for the certificate signature algorithm.
String get sigAlgName => OID.fromValue(sigAlgOID ?? "")?.name();
/// Gets the signature algorithm OID string from the certificate.
///Gets the signature algorithm OID string from the certificate.
String get sigAlgOID => block1.subAtIndex(2)?.subAtIndex(0)?.value as String;
/// Gets the DER-encoded signature algorithm parameters from this certificate's signature algorithm.
///Gets the DER-encoded signature algorithm parameters from this certificate's signature algorithm.
List<int> get sigAlgParams => null;
///Gets a boolean array representing bits of the KeyUsage extension, (OID = 2.5.29.15).
@ -262,7 +262,7 @@ class X509Certificate {
if (sub != null && sub.length > 0) {
var data = sub.last.subAtIndex(0)?.value as List<int>;
int bits = (data != null && data.length > 0) ? data.first ?? 0 : 0;
for (var index = 0; index < 7; index++) {
for (var index = 0; index < 8; index++) {
var value = bits & (1 << index).toUnsigned(8) != 0;
result.insert(0, value);
}
@ -321,12 +321,53 @@ class X509Certificate {
///Gets the certificate constraints path length from the
///critical BasicConstraints extension, (OID = 2.5.29.19).
int get basicConstraints => extensionObject(oid: OID.basicConstraints)?.value as int ?? -1;
int get basicConstraints {
var sub = extensionObject(oid: OID.basicConstraints)?.block?.lastSub()?.lastSub()?.lastSub();
if (sub != null) {
if (sub.value is List<int>) {
return (sub.value as List<int>).length;
}
}
return -1;
}
///Gets the raw bits from the Subject Key Identifier (SKID) extension, (OID = 2.5.29.14).
List<int> get subjectKeyIdentifier =>
extensionObject(oid: OID.subjectKeyIdentifier)?.block?.lastSub()?.lastSub()?.value ?? <int>[];
///Gets the raw bits from the Authority Key Identifier extension, (OID = 2.5.29.35).
List<int> get authorityKeyIdentifier =>
extensionObject(oid: OID.authorityKeyIdentifier)?.block?.lastSub()?.lastSub()?.firstSub()?.value ?? <int>[];
///Gets the list of certificate policies from the CertificatePolicies extension, (OID = 2.5.29.32).
List<String> get certificatePolicies =>
extensionObject(oid: OID.certificatePolicies)?.block?.lastSub()?.firstSub()?.sub?.map((e) => e.firstSub()?.value as String)?.toList() ?? <String>[];
///Gets the list of CRL distribution points from the CRLDistributionPoints extension, (OID = 2.5.29.31).
List<String> get cRLDistributionPoints =>
extensionObject(oid: OID.cRLDistributionPoints)?.block?.lastSub()?.firstSub()?.sub?.map((e) => e.firstSub()?.firstSub()?.firstSub()?.value as String)?.toList() ?? <String>[];
///Gets the map of the format (as a key) and location (as a value) of additional information
///about the CA who issued the certificate in which this extension appears
///from the AuthorityInfoAccess extension, (OID = 1.3.6.1.5.5.5.7.1.1).
Map<String, String> get authorityInfoAccess {
var result = <String, String>{};
var sub = extensionObject(oid: OID.authorityInfoAccess)?.block?.lastSub()?.firstSub()?.sub;
if (sub != null) {
sub.forEach((element) {
if (element.subCount() > 1) {
result.putIfAbsent(element.subAtIndex(0).value,
() => element.subAtIndex(1).value);
}
});
}
return result;
}
List<ASN1Object> get extensionBlocks =>
block1.atIndex(X509BlockPosition.extensions)?.subAtIndex(0)?.sub;
///Gets the extension information of the given OID code or enum.
///Gets the extension information of the given OID code or enum string value.
X509Extension extensionObject({String oidValue, OID oid}) {
if (oidValue == null && oid != null) {
oidValue = oid.toValue();
@ -346,21 +387,7 @@ class X509Certificate {
///Format subject/issuer information in RFC1779
String blockDistinguishedName({@required ASN1Object block}) {
var result = "";
List<ASN1DistinguishedNames> oidNames = [
ASN1DistinguishedNames.COMMON_NAME,
ASN1DistinguishedNames.DN_QUALIFIER,
ASN1DistinguishedNames.SERIAL_NUMBER,
ASN1DistinguishedNames.GIVEN_NAME,
ASN1DistinguishedNames.SURNAME,
ASN1DistinguishedNames.ORGANIZATIONAL_UNIT_NAME,
ASN1DistinguishedNames.ORGANIZATION_NAME,
ASN1DistinguishedNames.STREET_ADDRESS,
ASN1DistinguishedNames.LOCALITY_NAME,
ASN1DistinguishedNames.STATE_OR_PROVINCE_NAME,
ASN1DistinguishedNames.COUNTRY_NAME,
ASN1DistinguishedNames.EMAIL
];
for (var oidName in oidNames) {
for (var oidName in ASN1DistinguishedNames.values) {
var oidBlock = block.findOid(oidValue: oidName.oid());
if (oidBlock != null) {
if (result.isNotEmpty) {
@ -419,6 +446,11 @@ class X509Certificate {
"nonCriticalExtensionOIDs": nonCriticalExtensionOIDs,
"encoded": encoded,
"publicKey": publicKey?.toMap(),
"subjectKeyIdentifier": subjectKeyIdentifier,
"authorityKeyIdentifier": authorityKeyIdentifier,
"certificatePolicies": certificatePolicies,
"cRLDistributionPoints": cRLDistributionPoints,
"authorityInfoAccess": authorityInfoAccess,
};
}

View File

@ -39,9 +39,9 @@ class X509Extension {
List<String> get valueAsStrings {
var result = <String>[];
var sub = <ASN1Object>[];
var sub;
try {
sub = block.sub?.last?.sub?.last?.sub;
sub = block.sub?.last?.sub?.last?.sub ?? <ASN1Object>[];
} catch (e) {}
for (var item in sub) {