Skip to content

Commit

Permalink
fix: create custom class to verify bitstring position more precisely. (
Browse files Browse the repository at this point in the history
  • Loading branch information
elribonazo authored Jun 21, 2024
1 parent 38de286 commit efb771d
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/pollux/Pollux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import { HttpStatusCode } from "axios";
import { JsonLd, RemoteDocument } from "jsonld/jsonld-spec";
import { VerificationKeyType } from "../castor/types";
import { revocationJsonldDocuments } from "../domain/models/revocation";
import { Bitstring } from "./utils/Bitstring";

/**
* Implementation of Pollux
Expand Down Expand Up @@ -165,6 +166,7 @@ export default class Pollux implements IPollux {
private extractEncodedList(body: JWTStatusListResponse): Uint8Array {
try {
const encodedList = Buffer.from(body.credentialSubject.encodedList, 'base64');

return this._pako.ungzip(encodedList);
} catch (err) {
throw new PolluxError.InvalidRevocationStatusResponse(`Couldn't ungzip base64 encoded list, err: ${(err as Error).message}`)
Expand Down Expand Up @@ -264,8 +266,8 @@ export default class Pollux implements IPollux {
throw new PolluxError.InvalidRevocationStatusResponse(`CredentialStatus invalid signature`);
}
const statusListDecoded = this.extractEncodedList(revocation)
const isRevoked = statusListDecoded[statusListIndex] !== 0
return isRevoked
const bitstring = new Bitstring({ buffer: statusListDecoded })
return bitstring.get(statusListIndex + 1)
}
throw new PolluxError.InvalidRevocationStatusResponse(`CredentialStatus proof type not supported`);
} catch (err) {
Expand Down
56 changes: 56 additions & 0 deletions src/pollux/utils/Bitstring.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

export class Bitstring {
bits: Uint8Array;
length: number;
leftToRightIndexing: boolean;

constructor({
buffer,
leftToRightIndexing
}: {
buffer: Uint8Array;
leftToRightIndexing?: boolean;
}) {
if (!buffer) {
throw new Error('Only one of "length" or "buffer" must be given.');
}
this.bits = new Uint8Array(buffer.buffer);
this.length = buffer.length * 8;
this.leftToRightIndexing = leftToRightIndexing ?? false;
}

set(position: number, on: boolean): void {
const { length, leftToRightIndexing } = this;
const { index, bit } = _parsePosition(position, length, leftToRightIndexing);
if (on) {
this.bits[index] |= bit;
} else {
this.bits[index] &= 0xff ^ bit;
}
}

get(position: number): boolean {
const { length, leftToRightIndexing } = this;
const { index, bit } = _parsePosition(position, length, leftToRightIndexing);
return !!(this.bits[index] & bit);
}


}

function _parsePosition(
position: number,
length: number,
leftToRightIndexing: boolean
): { index: number; bit: number } {
if (position >= length) {
throw new Error(
`Position "${position}" is out of range "0-${length - 1}".`
);
}
const index = Math.floor(position / 8);
const rem = position % 8;
const shift = leftToRightIndexing ? 7 - rem : rem;
const bit = 1 << shift;
return { index, bit };
}

1 comment on commit efb771d

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lines Statements Branches Functions
Coverage: 75%
75.28% (2772/3682) 64.87% (1343/2070) 80.49% (718/892)

JUnit

Tests Skipped Failures Errors Time
501 6 💤 0 ❌ 0 🔥 1m 15s ⏱️

Please sign in to comment.