Skip to content

Commit

Permalink
refactor: Optimise code
Browse files Browse the repository at this point in the history
  • Loading branch information
bibash28 committed Apr 3, 2024
1 parent 17696d1 commit 72c930b
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 97 deletions.
9 changes: 9 additions & 0 deletions lib/app/shared/extension/string_extension.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import 'dart:convert';

import 'package:convert/convert.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

Expand Down Expand Up @@ -34,4 +37,10 @@ extension StringExtension on String {
}

Characters get characters => Characters(this);

String get char2Bytes {
final List<int> encode = utf8.encode(this);
final String bytes = hex.encode(encode);
return bytes;
}
}
97 changes: 89 additions & 8 deletions lib/app/shared/helper_functions/helper_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import 'package:key_generator/key_generator.dart';
import 'package:oidc4vc/oidc4vc.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:secure_storage/secure_storage.dart';
import 'package:pointycastle/pointycastle.dart' as pc;
import 'package:asn1lib/asn1lib.dart' as asn1lib;
import 'package:x509/x509.dart' as x509;

String generateDefaultAccountName(
int accountIndex,
Expand Down Expand Up @@ -81,23 +84,17 @@ String stringToHexPrefixedWith05({required String payload}) {
payload,
].join(' ');

final String bytes = char2Bytes(formattedInput);
final String bytes = formattedInput.char2Bytes;

const String prefix = '05';
const String stringIsHex = '0100';
final String bytesOfByteLength = char2Bytes(bytes.length.toString());
final String bytesOfByteLength = bytes.length.toString().char2Bytes;

final payloadBytes = '$prefix$stringIsHex$bytesOfByteLength$bytes';

return payloadBytes;
}

String char2Bytes(String text) {
final List<int> encode = utf8.encode(text);
final String bytes = hex.encode(encode);
return bytes;
}

Future<bool> isConnected() async {
final log = getLogger('Check Internet Connection');

Expand Down Expand Up @@ -1795,3 +1792,87 @@ List<dynamic> collectSdValues(Map<String, dynamic> data) {

return result;
}

Future<Map<String, dynamic>?> checkX509({
required String encodedData,
required String clientId,
required JWTDecode jwtDecode,
}) async {
final Map<String, dynamic> header =
decodeHeader(jwtDecode: jwtDecode, token: encodedData);

final x5c = header['x5c'];

if (x5c != null) {
if (x5c is! List) {
throw ResponseMessage(
data: {
'error': 'invalid_format',
'error_description': 'x509_san_dns scheme error',
},
);
}

//array x5c[0], it is a certificat in DER format (binary)
final certificate = x5c.firstOrNull;

if (certificate == null) {
throw ResponseMessage(
data: {
'error': 'invalid_format',
'error_description': 'x509_san_dns scheme error',
},
);
}

final decoded = base64Decode(certificate.toString());
final seq = asn1lib.ASN1Sequence.fromBytes(decoded);
final cert = x509.X509Certificate.fromAsn1(seq);

final subject = cert.tbsCertificate.subject;

if (subject == null) {
throw ResponseMessage(
data: {
'error': 'invalid_format',
'error_description': 'x509_san_dns scheme error',
},
);
}

final names = subject.names;

if (names.isEmpty) {
throw ResponseMessage(
data: {
'error': 'invalid_format',
'error_description': 'x509_san_dns scheme error',
},
);
}

final value = names[0].entries.map((element) => element.value).toList();

if (!value.contains(clientId)) {
throw ResponseMessage(
data: {
'error': 'invalid_format',
'error_description': 'x509_san_dns scheme error',
},
);
}

final publicKey = cert.publicKey;
if (publicKey is x509.RsaPublicKey) {
final BigInt modulus = BigInt.parse(publicKey.modulus.toString());
final n = base64Encode(modulus.toBytes);
final publicKeyJwk = {
'e': 'AQAB',
'kty': 'RSA',
'n': n.replaceAll('=', ''),
};
return publicKeyJwk;
}
}
return null;
}
94 changes: 5 additions & 89 deletions lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,17 @@ import 'package:altme/polygon_id/polygon_id.dart';
import 'package:altme/query_by_example/query_by_example.dart';
import 'package:altme/scan/scan.dart';
import 'package:altme/wallet/cubit/wallet_cubit.dart';
import 'package:asn1lib/asn1lib.dart' as asn1lib;
import 'package:beacon_flutter/beacon_flutter.dart';
import 'package:bloc/bloc.dart';
import 'package:credential_manifest/credential_manifest.dart';
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
import 'package:did_kit/did_kit.dart';
import 'package:dio/dio.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:jwt_decode/jwt_decode.dart';
import 'package:oidc4vc/oidc4vc.dart';
import 'package:pointycastle/pointycastle.dart' as pc;
import 'package:secure_storage/secure_storage.dart';
import 'package:x509/x509.dart' as x509;
part 'qr_code_scan_cubit.g.dart';
part 'qr_code_scan_state.dart';

Expand Down Expand Up @@ -1094,8 +1090,11 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {

if (clientIdScheme != null) {
if (clientIdScheme == 'x509_san_dns') {
publicKeyJwk =
await checkX509(clientId: clientId, encodedData: encodedData);
publicKeyJwk = await checkX509(
clientId: clientId,
encodedData: encodedData,
jwtDecode: jwtDecode,
);
}
}

Expand Down Expand Up @@ -1127,89 +1126,6 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
}
}

Future<Map<String, dynamic>?> checkX509({
required String encodedData,
required String clientId,
}) async {
final Map<String, dynamic> header =
decodeHeader(jwtDecode: jwtDecode, token: encodedData);

final x5c = header['x5c'];

if (x5c != null) {
if (x5c is! List) {
throw ResponseMessage(
data: {
'error': 'invalid_format',
'error_description': 'x509_san_dns scheme error',
},
);
}

//array x5c[0], it is a certificat in DER format (binary)
final certificate = x5c.firstOrNull;

if (certificate == null) {
throw ResponseMessage(
data: {
'error': 'invalid_format',
'error_description': 'x509_san_dns scheme error',
},
);
}

final decoded = base64Decode(certificate.toString());
final seq = asn1lib.ASN1Sequence.fromBytes(decoded);
final cert = x509.X509Certificate.fromAsn1(seq);

final subject = cert.tbsCertificate.subject;

if (subject == null) {
throw ResponseMessage(
data: {
'error': 'invalid_format',
'error_description': 'x509_san_dns scheme error',
},
);
}

final names = subject.names;

if (names.isEmpty) {
throw ResponseMessage(
data: {
'error': 'invalid_format',
'error_description': 'x509_san_dns scheme error',
},
);
}

final value = names[0].entries.map((element) => element.value).toList();

if (!value.contains(clientId)) {
throw ResponseMessage(
data: {
'error': 'invalid_format',
'error_description': 'x509_san_dns scheme error',
},
);
}

final publicKey = cert.publicKey;
if (publicKey is x509.RsaPublicKey) {
final BigInt modulus = BigInt.parse(publicKey.modulus.toString());
final n = base64Encode(modulus.toBytes);
final publicKeyJwk = {
'e': 'AQAB',
'kty': 'RSA',
'n': n.replaceAll('=', ''),
};
return publicKeyJwk;
}
}
return null;
}

/// complete SIOPV2 Flow
Future<void> completeSiopV2Flow() async {
try {
Expand Down

0 comments on commit 72c930b

Please sign in to comment.