Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ export enum CredentialParsingError {
NotFound = "NotFound",
NotFoundExtends = "NotFoundExtends",
IntegrityMissing = "IntegrityMissing",
JwtVcIssuerMismatch = "JwtVcIssuerMismatch",
IntegrityFail = "IntegrityFail",
SchemaFail = "SchemaFail",
SchemaShapeFail = "SchemaShapeFail",
JwtVcIssuerFail = "JwtVcIssuerFail",
FailFetchIssuerMetadata = "FailFetchIssuerMetadata",
FailSchemaIssuerMetadata = "FailSchemaIssuerMetadata",
}
Expand All @@ -26,10 +24,8 @@ export const CredentialParsingWarnings = new Set<CredentialParsingError>([
CredentialParsingError.NotFound,
CredentialParsingError.NotFoundExtends,
CredentialParsingError.IntegrityMissing,
CredentialParsingError.JwtVcIssuerMismatch,
CredentialParsingError.IntegrityFail,
CredentialParsingError.SchemaFail,
CredentialParsingError.JwtVcIssuerFail,
CredentialParsingError.FailFetchIssuerMetadata,
CredentialParsingError.FailSchemaIssuerMetadata,
]);
Expand Down
50 changes: 0 additions & 50 deletions src/utils/getSdJwtVcMetadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,20 +169,6 @@ describe("getSdJwtVcMetadata - vct url failure cases", () => {
};
}


it("warning on /jwt-vc-issuer mismatch", async () => {
const payload = { ...validPayload, iss: "https://attacker.com" };
const credential = `${encodeBase64Url({})}.${encodeBase64Url(payload)}.sig`;
const result = await getSdJwtVcMetadata(context, createHttpClient(), credential, payload);
if ('warnings' in result) {
expect(result.warnings.some(w => w.code === 'JwtVcIssuerMismatch')).toBe(true);

} else {
throw new Error(`Expected result to be success with warnings`);
}
});


it("warning when fetching main vct fails", async () => {
const payload = { ...validPayload };
const credential = `${encodeBase64Url({})}.${encodeBase64Url(payload)}.sig`;
Expand Down Expand Up @@ -384,42 +370,6 @@ describe("getSdJwtVcMetadata - vct url failure cases", () => {
}
});


it("warning with JwtVcIssuerFail when .well-known/jwt-vc-issuer fetch fails", async () => {
const payload = {
iss: "https://issuer.com",
vct: "https://issuer.com/child.json",
"vct#integrity": generateSRIFromObject(childMetadata)
};

const credential = `${encodeBase64Url({})}.${encodeBase64Url(payload)}.sig`;

const httpClient = createHttpClient({
childMetadataOverride: childMetadata
});

httpClient.get = async (url: string) => {
if (url.endsWith("/.well-known/jwt-vc-issuer")) {
return { status: 404, data: null };
}
if (url.endsWith("child.json")) {
return { status: 200, data: childMetadata };
}
if (url.endsWith("parent.json")) {
return { status: 200, data: parentMetadata };
}
return { status: 404, data: null };
};

const result = await getSdJwtVcMetadata(context, httpClient, credential, payload);
if ('warnings' in result) {
expect(result.warnings.some(w => w.code === 'JwtVcIssuerFail')).toBe(true);

} else {
throw new Error(`Expected result to be success with warnings`);
}
});

});

function createHttpClient(): HttpClient {
Expand Down
33 changes: 0 additions & 33 deletions src/utils/getSdJwtVcMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,32 +291,6 @@ async function fetchAndMergeMetadata(
return merged;
}

export async function resolveIssuerMetadata(httpClient: any, issuerUrl: string): Promise<{ code: CredentialParsingError } | undefined> {
try {
const issUrl = new URL(issuerUrl);

const result = await httpClient.get(`${issUrl.origin}/.well-known/jwt-vc-issuer`, {}, { useCache: true }) as {
data: { issuer: string };
};

if (
result &&
typeof result === 'object' &&
('data' in result) &&
typeof (result as any).data === 'object' &&
typeof (result as any).data.issuer === 'string'
) {
if (result.data.issuer !== issUrl.origin) {
return { code: CredentialParsingError.JwtVcIssuerMismatch };
}
}

return undefined;
} catch (err) {
return { code: CredentialParsingError.JwtVcIssuerFail };
}
}

function isValidHttpUrl(value: string): boolean {
try {
const url = new URL(value);
Expand Down Expand Up @@ -355,13 +329,6 @@ export async function getSdJwtVcMetadata(context: Context, httpClient: HttpClien
const vct = credentialPayload.vct;
if (vct && typeof vct === 'string' && isValidHttpUrl(vct)) {

// Check jwt-vc-issuer by iss
const checkIssuer = await resolveIssuerMetadata(httpClient, credentialPayload.iss);
if (checkIssuer) {
const resultCode = handleMetadataCode(checkIssuer.code, warnings);
if (resultCode) return resultCode;
}

try {
const vctIntegrity = credentialPayload['vct#integrity'] as string | undefined;
const mergedMetadata = await fetchAndMergeMetadata(context, httpClient, vct, undefined, new Set(), vctIntegrity, credentialPayload, warnings);
Expand Down