@aries-framework/anoncreds-rs
Advanced tools
Comparing version 0.5.0-alpha.68 to 0.5.0-alpha.69
@@ -1,2 +0,2 @@ | ||
import type { AnonCredsIssuerService, CreateCredentialDefinitionOptions, CreateCredentialOfferOptions, CreateCredentialOptions, CreateCredentialReturn, CreateSchemaOptions, AnonCredsCredentialOffer, AnonCredsSchema, CreateCredentialDefinitionReturn } from '@aries-framework/anoncreds'; | ||
import type { AnonCredsIssuerService, CreateCredentialDefinitionOptions, CreateCredentialOfferOptions, CreateCredentialOptions, CreateCredentialReturn, CreateSchemaOptions, AnonCredsCredentialOffer, AnonCredsSchema, CreateCredentialDefinitionReturn, CreateRevocationRegistryDefinitionOptions, CreateRevocationRegistryDefinitionReturn, CreateRevocationStatusListOptions, AnonCredsRevocationStatusList, UpdateRevocationStatusListOptions } from '@aries-framework/anoncreds'; | ||
import type { AgentContext } from '@aries-framework/core'; | ||
@@ -6,4 +6,7 @@ export declare class AnonCredsRsIssuerService implements AnonCredsIssuerService { | ||
createCredentialDefinition(agentContext: AgentContext, options: CreateCredentialDefinitionOptions): Promise<CreateCredentialDefinitionReturn>; | ||
createRevocationRegistryDefinition(agentContext: AgentContext, options: CreateRevocationRegistryDefinitionOptions): Promise<CreateRevocationRegistryDefinitionReturn>; | ||
createRevocationStatusList(agentContext: AgentContext, options: CreateRevocationStatusListOptions): Promise<AnonCredsRevocationStatusList>; | ||
updateRevocationStatusList(agentContext: AgentContext, options: UpdateRevocationStatusListOptions): Promise<AnonCredsRevocationStatusList>; | ||
createCredentialOffer(agentContext: AgentContext, options: CreateCredentialOfferOptions): Promise<AnonCredsCredentialOffer>; | ||
createCredential(agentContext: AgentContext, options: CreateCredentialOptions): Promise<CreateCredentialReturn>; | ||
} |
@@ -55,2 +55,84 @@ "use strict"; | ||
} | ||
async createRevocationRegistryDefinition(agentContext, options) { | ||
const { tag, issuerId, credentialDefinition, credentialDefinitionId, maximumCredentialNumber, tailsDirectoryPath } = options; | ||
let createReturnObj; | ||
try { | ||
createReturnObj = anoncreds_shared_1.RevocationRegistryDefinition.create({ | ||
credentialDefinition: credentialDefinition, | ||
credentialDefinitionId, | ||
issuerId, | ||
maximumCredentialNumber, | ||
revocationRegistryType: 'CL_ACCUM', | ||
tag, | ||
tailsDirectoryPath, | ||
}); | ||
return { | ||
revocationRegistryDefinition: createReturnObj.revocationRegistryDefinition.toJson(), | ||
revocationRegistryDefinitionPrivate: createReturnObj.revocationRegistryDefinitionPrivate.toJson(), | ||
}; | ||
} | ||
finally { | ||
createReturnObj === null || createReturnObj === void 0 ? void 0 : createReturnObj.revocationRegistryDefinition.handle.clear(); | ||
createReturnObj === null || createReturnObj === void 0 ? void 0 : createReturnObj.revocationRegistryDefinitionPrivate.handle.clear(); | ||
} | ||
} | ||
async createRevocationStatusList(agentContext, options) { | ||
const { issuerId, revocationRegistryDefinitionId, revocationRegistryDefinition } = options; | ||
const credentialDefinitionRecord = await agentContext.dependencyManager | ||
.resolve(anoncreds_1.AnonCredsCredentialDefinitionRepository) | ||
.getByCredentialDefinitionId(agentContext, revocationRegistryDefinition.credDefId); | ||
const revocationRegistryDefinitionPrivateRecord = await agentContext.dependencyManager | ||
.resolve(anoncreds_1.AnonCredsRevocationRegistryDefinitionPrivateRepository) | ||
.getByRevocationRegistryDefinitionId(agentContext, revocationRegistryDefinitionId); | ||
let revocationStatusList; | ||
try { | ||
revocationStatusList = anoncreds_shared_1.RevocationStatusList.create({ | ||
issuanceByDefault: true, | ||
revocationRegistryDefinitionId, | ||
credentialDefinition: credentialDefinitionRecord.credentialDefinition, | ||
revocationRegistryDefinition: revocationRegistryDefinition, | ||
revocationRegistryDefinitionPrivate: revocationRegistryDefinitionPrivateRecord.value, | ||
issuerId, | ||
}); | ||
return revocationStatusList.toJson(); | ||
} | ||
finally { | ||
revocationStatusList === null || revocationStatusList === void 0 ? void 0 : revocationStatusList.handle.clear(); | ||
} | ||
} | ||
async updateRevocationStatusList(agentContext, options) { | ||
const { revocationStatusList, revocationRegistryDefinition, issued, revoked, timestamp, tailsFilePath } = options; | ||
let updatedRevocationStatusList; | ||
let revocationRegistryDefinitionObj; | ||
try { | ||
updatedRevocationStatusList = anoncreds_shared_1.RevocationStatusList.fromJson(revocationStatusList); | ||
if (timestamp && !issued && !revoked) { | ||
updatedRevocationStatusList.updateTimestamp({ | ||
timestamp, | ||
}); | ||
} | ||
else { | ||
const credentialDefinitionRecord = await agentContext.dependencyManager | ||
.resolve(anoncreds_1.AnonCredsCredentialDefinitionRepository) | ||
.getByCredentialDefinitionId(agentContext, revocationRegistryDefinition.credDefId); | ||
const revocationRegistryDefinitionPrivateRecord = await agentContext.dependencyManager | ||
.resolve(anoncreds_1.AnonCredsRevocationRegistryDefinitionPrivateRepository) | ||
.getByRevocationRegistryDefinitionId(agentContext, revocationStatusList.revRegDefId); | ||
revocationRegistryDefinitionObj = anoncreds_shared_1.RevocationRegistryDefinition.fromJson(Object.assign(Object.assign({}, revocationRegistryDefinition), { value: Object.assign(Object.assign({}, revocationRegistryDefinition.value), { tailsLocation: tailsFilePath }) })); | ||
updatedRevocationStatusList.update({ | ||
credentialDefinition: credentialDefinitionRecord.credentialDefinition, | ||
revocationRegistryDefinition: revocationRegistryDefinitionObj, | ||
revocationRegistryDefinitionPrivate: revocationRegistryDefinitionPrivateRecord.value, | ||
issued: options.issued, | ||
revoked: options.revoked, | ||
timestamp: timestamp !== null && timestamp !== void 0 ? timestamp : -1, // FIXME: this should be fixed in anoncreds-rs wrapper | ||
}); | ||
} | ||
return updatedRevocationStatusList.toJson(); | ||
} | ||
finally { | ||
updatedRevocationStatusList === null || updatedRevocationStatusList === void 0 ? void 0 : updatedRevocationStatusList.handle.clear(); | ||
revocationRegistryDefinitionObj === null || revocationRegistryDefinitionObj === void 0 ? void 0 : revocationRegistryDefinitionObj.handle.clear(); | ||
} | ||
} | ||
async createCredentialOffer(agentContext, options) { | ||
@@ -93,8 +175,13 @@ const { credentialDefinitionId } = options; | ||
var _a; | ||
const { tailsFilePath, credentialOffer, credentialRequest, credentialValues, revocationRegistryId } = options; | ||
const { credentialOffer, credentialRequest, credentialValues, revocationRegistryDefinitionId, revocationStatusList, revocationRegistryIndex, } = options; | ||
const definedRevocationOptions = [ | ||
revocationRegistryDefinitionId, | ||
revocationStatusList, | ||
revocationRegistryIndex, | ||
].filter((e) => e !== undefined); | ||
if (definedRevocationOptions.length > 0 && definedRevocationOptions.length < 3) { | ||
throw new core_1.AriesFrameworkError('Revocation requires all of revocationRegistryDefinitionId, revocationRegistryIndex and revocationStatusList'); | ||
} | ||
let credential; | ||
try { | ||
if (revocationRegistryId || tailsFilePath) { | ||
throw new core_1.AriesFrameworkError('Revocation not supported yet'); | ||
} | ||
const attributeRawValues = {}; | ||
@@ -122,2 +209,20 @@ const attributeEncodedValues = {}; | ||
} | ||
let revocationConfiguration; | ||
if (revocationRegistryDefinitionId && revocationStatusList && revocationRegistryIndex) { | ||
const revocationRegistryDefinitionRecord = await agentContext.dependencyManager | ||
.resolve(anoncreds_1.AnonCredsRevocationRegistryDefinitionRepository) | ||
.getByRevocationRegistryDefinitionId(agentContext, revocationRegistryDefinitionId); | ||
const revocationRegistryDefinitionPrivateRecord = await agentContext.dependencyManager | ||
.resolve(anoncreds_1.AnonCredsRevocationRegistryDefinitionPrivateRepository) | ||
.getByRevocationRegistryDefinitionId(agentContext, revocationRegistryDefinitionId); | ||
if (revocationRegistryIndex >= revocationRegistryDefinitionRecord.revocationRegistryDefinition.value.maxCredNum) { | ||
revocationRegistryDefinitionPrivateRecord.state = anoncreds_1.AnonCredsRevocationRegistryState.Full; | ||
} | ||
revocationConfiguration = new anoncreds_shared_1.CredentialRevocationConfig({ | ||
registryDefinition: anoncreds_shared_1.RevocationRegistryDefinition.fromJson(revocationRegistryDefinitionRecord.revocationRegistryDefinition), | ||
registryDefinitionPrivate: anoncreds_shared_1.RevocationRegistryDefinitionPrivate.fromJson(revocationRegistryDefinitionPrivateRecord.value), | ||
statusList: anoncreds_shared_1.RevocationStatusList.fromJson(revocationStatusList), | ||
registryIndex: revocationRegistryIndex, | ||
}); | ||
} | ||
credential = anoncreds_shared_1.Credential.create({ | ||
@@ -127,6 +232,11 @@ credentialDefinition: credentialDefinitionRecord.credentialDefinition, | ||
credentialRequest: credentialRequest, | ||
revocationRegistryId, | ||
revocationRegistryId: revocationRegistryDefinitionId, | ||
attributeEncodedValues, | ||
attributeRawValues, | ||
credentialDefinitionPrivate: credentialDefinitionPrivateRecord.value, | ||
revocationConfiguration, | ||
// FIXME: duplicated input parameter? | ||
revocationStatusList: revocationStatusList | ||
? anoncreds_shared_1.RevocationStatusList.fromJson(revocationStatusList) | ||
: undefined, | ||
}); | ||
@@ -133,0 +243,0 @@ return { |
@@ -5,2 +5,3 @@ import type { AnonCredsVerifierService, VerifyProofOptions } from '@aries-framework/anoncreds'; | ||
verifyProof(agentContext: AgentContext, options: VerifyProofOptions): Promise<boolean>; | ||
private verifyTimestamps; | ||
} |
@@ -10,2 +10,3 @@ "use strict"; | ||
exports.AnonCredsRsVerifierService = void 0; | ||
const anoncreds_1 = require("@aries-framework/anoncreds"); | ||
const core_1 = require("@aries-framework/core"); | ||
@@ -18,2 +19,10 @@ const anoncreds_shared_1 = require("@hyperledger/anoncreds-shared"); | ||
try { | ||
// Check that provided timestamps correspond to the active ones from the VDR. If they are and differ from the originally | ||
// requested ones, create overrides for anoncreds-rs to consider them valid | ||
const { verified, nonRevokedIntervalOverrides } = await this.verifyTimestamps(agentContext, proof, proofRequest); | ||
// No need to call anoncreds-rs as we already know that the proof will not be valid | ||
if (!verified) { | ||
agentContext.config.logger.debug('Invalid timestamps for provided identifiers'); | ||
return false; | ||
} | ||
presentation = anoncreds_shared_1.Presentation.fromJson(proof); | ||
@@ -41,2 +50,3 @@ const rsCredentialDefinitions = {}; | ||
revocationStatusLists: lists, | ||
nonRevokedIntervalOverrides, | ||
}); | ||
@@ -48,2 +58,56 @@ } | ||
} | ||
async verifyTimestamps(agentContext, proof, proofRequest) { | ||
var _a, _b; | ||
const nonRevokedIntervalOverrides = []; | ||
// Override expected timestamps if the requested ones don't exacly match the values from VDR | ||
const globalNonRevokedInterval = proofRequest.non_revoked; | ||
const requestedNonRevokedRestrictions = []; | ||
for (const value of [ | ||
...Object.values(proofRequest.requested_attributes), | ||
...Object.values(proofRequest.requested_predicates), | ||
]) { | ||
const nonRevokedInterval = (_a = value.non_revoked) !== null && _a !== void 0 ? _a : globalNonRevokedInterval; | ||
if (nonRevokedInterval) { | ||
(_b = value.restrictions) === null || _b === void 0 ? void 0 : _b.forEach((restriction) => requestedNonRevokedRestrictions.push({ | ||
nonRevokedInterval, | ||
schemaId: restriction.schema_id, | ||
credentialDefinitionId: restriction.cred_def_id, | ||
revocationRegistryDefinitionId: restriction.rev_reg_id, | ||
})); | ||
} | ||
} | ||
for (const identifier of proof.identifiers) { | ||
if (!identifier.timestamp || !identifier.rev_reg_id) { | ||
continue; | ||
} | ||
const relatedNonRevokedRestrictionItem = requestedNonRevokedRestrictions.find((item) => item.revocationRegistryDefinitionId === item.revocationRegistryDefinitionId || | ||
item.credentialDefinitionId === identifier.cred_def_id || | ||
item.schemaId === item.schemaId); | ||
const requestedFrom = relatedNonRevokedRestrictionItem === null || relatedNonRevokedRestrictionItem === void 0 ? void 0 : relatedNonRevokedRestrictionItem.nonRevokedInterval.from; | ||
if (requestedFrom && requestedFrom > identifier.timestamp) { | ||
// Check VDR if the active revocation status list at requestedFrom was the one from provided timestamp. | ||
// If it matches, add to the override list | ||
const registry = agentContext.dependencyManager | ||
.resolve(anoncreds_1.AnonCredsRegistryService) | ||
.getRegistryForIdentifier(agentContext, identifier.rev_reg_id); | ||
const { revocationStatusList } = await registry.getRevocationStatusList(agentContext, identifier.rev_reg_id, requestedFrom); | ||
const vdrTimestamp = revocationStatusList === null || revocationStatusList === void 0 ? void 0 : revocationStatusList.timestamp; | ||
if (vdrTimestamp && vdrTimestamp === identifier.timestamp) { | ||
nonRevokedIntervalOverrides.push({ | ||
overrideRevocationStatusListTimestamp: identifier.timestamp, | ||
requestedFromTimestamp: requestedFrom, | ||
revocationRegistryDefinitionId: identifier.rev_reg_id, | ||
}); | ||
} | ||
else { | ||
agentContext.config.logger.debug(`VDR timestamp for ${requestedFrom} does not correspond to the one provided in proof identifiers. Expected: ${identifier.timestamp} and received ${vdrTimestamp}`); | ||
return { verified: false }; | ||
} | ||
} | ||
} | ||
return { | ||
verified: true, | ||
nonRevokedIntervalOverrides: nonRevokedIntervalOverrides.length ? nonRevokedIntervalOverrides : undefined, | ||
}; | ||
} | ||
}; | ||
@@ -50,0 +114,0 @@ AnonCredsRsVerifierService = __decorate([ |
@@ -5,3 +5,3 @@ { | ||
"types": "build/index", | ||
"version": "0.5.0-alpha.68+ed874ce3", | ||
"version": "0.5.0-alpha.69+c59ad59f", | ||
"files": [ | ||
@@ -28,4 +28,4 @@ "build" | ||
"dependencies": { | ||
"@aries-framework/anoncreds": "0.5.0-alpha.68+ed874ce3", | ||
"@aries-framework/core": "0.5.0-alpha.68+ed874ce3", | ||
"@aries-framework/anoncreds": "0.5.0-alpha.69+c59ad59f", | ||
"@aries-framework/core": "0.5.0-alpha.69+c59ad59f", | ||
"class-transformer": "^0.5.1", | ||
@@ -48,3 +48,3 @@ "class-validator": "0.14.0", | ||
}, | ||
"gitHead": "ed874ce38ed1a1a0f01b12958e5b14823661b06a" | ||
"gitHead": "c59ad59fbe63b6d3760d19030e0f95fb2ea8488a" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
93254
908