Skip to content

Commit

Permalink
feat: Implement bit system to chek status list for sd_jwt #2531
Browse files Browse the repository at this point in the history
  • Loading branch information
bibash28 committed Mar 26, 2024
1 parent 6127e62 commit 6a2aebd
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:convert';

import 'package:altme/app/app.dart';
import 'package:altme/dashboard/dashboard.dart';
import 'package:altme/oidc4vc/verify_encoded_data.dart';
Expand Down Expand Up @@ -110,25 +109,78 @@ class CredentialDetailsCubit extends Cubit<CredentialDetailsState> {
if (status != null && status is Map<String, dynamic>) {
final statusList = status['status_list'];
if (statusList != null && statusList is Map<String, dynamic>) {
final uri = statusList['uri'];
final idx = statusList['idx'];
if (idx is int) {
final posOfBit = profileCubit.oidc4vc.getPositionOfBit(idx);
final bytes = profileCubit.oidc4vc.getByte(idx);
final isActive = profileCubit.oidc4vc.isVCActive(
bitPosition: posOfBit,
byte: bytes,

if (idx != null && idx is int && uri != null && uri is String) {
final dynamic response = await client.get(
uri,
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'accept': 'application/statuslist+jwt',
},
);

if (isActive) {
// active
} else {
// revoked
emit(
state.copyWith(
credentialStatus: CredentialStatus.revoked,
status: AppStatus.idle,
),
);
// /// verify the signature of the VC with the kid of the JWT

// /// issuer did
// final issuerDid = item.issuer;

// String? issuerKid;
// final String encodedData = response.toString();

// final Map<String, dynamic> header =
// decodeHeader(jwtDecode: jwtDecode, token: encodedData);

// if (header.containsKey('kid')) {
// issuerKid = header['kid'].toString();
// }

// final VerificationType isVerified = await verifyEncodedData(
// issuerDid,
// issuerKid,
// encodedData,
// );

// if (isVerified != VerificationType.verified) {
// emit(
// state.copyWith(
// credentialStatus: CredentialStatus.notVerified,
// status: AppStatus.idle,
// ),
// );
// return;
// }

final payload = jwtDecode.parseJwt(response.toString());
final newStatusList = payload['status_list'];
if (newStatusList != null &&
newStatusList is Map<String, dynamic>) {
final lst = newStatusList['lst'].toString();

final bytes = profileCubit.oidc4vc.getByte(idx);

// '$idx = $bytes X 8 + $posOfBit'
final decompressedBytes =
profileCubit.oidc4vc.decodeAndZlibDecompress(lst);
final byteToCheck = decompressedBytes[bytes];

final posOfBit = profileCubit.oidc4vc.getPositionOfBit(idx);
final bit = profileCubit.oidc4vc
.getBit(byte: byteToCheck, bitPosition: posOfBit);

if (bit == 0) {
// active
} else {
// revoked
emit(
state.copyWith(
credentialStatus: CredentialStatus.revoked,
status: AppStatus.idle,
),
);
return;
}
}
}
}
Expand All @@ -140,18 +192,13 @@ class CredentialDetailsCubit extends Cubit<CredentialDetailsState> {
final issuerDid = item.issuer;

String? issuerKid;
late final String encodedData;
if (item.jwt == null) {
issuerKid = item.data['proof']['verificationMethod'] as String;
} else {
encodedData = item.jwt!;
final String encodedData = item.jwt!;

final Map<String, dynamic> header =
decodeHeader(jwtDecode: jwtDecode, token: encodedData);
final Map<String, dynamic> header =
decodeHeader(jwtDecode: jwtDecode, token: encodedData);

if (header.containsKey('kid')) {
issuerKid = header['kid'].toString();
}
if (header.containsKey('kid')) {
issuerKid = header['kid'].toString();
}

final VerificationType isVerified = await verifyEncodedData(
Expand Down
22 changes: 17 additions & 5 deletions packages/oidc4vc/lib/src/oidc4vc.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// ignore_for_file: avoid_dynamic_calls, public_member_api_docs

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

import 'package:bip32/bip32.dart' as bip32;
import 'package:bip39/bip39.dart' as bip393;
Expand Down Expand Up @@ -1618,13 +1619,24 @@ class OIDC4VC {

int getByte(int index) => index ~/ 8;

bool isVCActive({
int getBit({
required int byte,
required int bitPosition,
}) {
//if bit = 0 the VC is active, if bit = 1 VC is revoked
final bit = byte & (1 << bitPosition);
final isActive = bit == 0;
return isActive;
// byte => 32 =0100000
// The bit in position 5 is set to 1 !!!
// so bit = 1
final bit = (byte & (1 << bitPosition)) != 0;
return bit ? 1 : 0;
}

List<int> decodeAndZlibDecompress(String lst) {
final paddedBase64 = lst.padRight((lst.length + 3) & ~3, '=');
final compressedBytes = base64Url.decode(paddedBase64);

final zlib = ZLibCodec();
final decompressedBytes = zlib.decode(compressedBytes);

return decompressedBytes;
}
}

0 comments on commit 6a2aebd

Please sign in to comment.