From da10b38171f4038cd19bf1ba98339af22112b1d5 Mon Sep 17 00:00:00 2001 From: Holash Chand Date: Mon, 3 Jun 2024 18:11:41 +0530 Subject: [PATCH] added support to generate did document with specific key pair --- .../identity-service/src/did/did.service.ts | 65 ++++++++++++++----- .../src/did/dtos/GenerateDid.dto.ts | 11 ++++ 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/services/identity-service/src/did/did.service.ts b/services/identity-service/src/did/did.service.ts index 3f7ea9636..3acda4cc1 100644 --- a/services/identity-service/src/did/did.service.ts +++ b/services/identity-service/src/did/did.service.ts @@ -7,9 +7,16 @@ import { GenerateDidDTO } from './dtos/GenerateDid.dto'; import { VaultService } from '../utils/vault.service'; import { Identity } from '@prisma/client'; import { RSAKeyPair } from "crypto-ld"; +type KeysType = { + [key: string]: { + name: string; + key: any; + }; +}; @Injectable() export class DidService { - keys = {} + keys: KeysType = { + } webDidBaseUrl: string; signingAlgorithm: string; didResolver: any; @@ -28,9 +35,18 @@ export class DidService { async init() { const {Ed25519VerificationKey2020} = await import('@digitalbazaar/ed25519-verification-key-2020'); const {Ed25519VerificationKey2018} = await import('@digitalbazaar/ed25519-verification-key-2018'); - this.keys['Ed25519Signature2020'] = Ed25519VerificationKey2020; - this.keys['Ed25519Signature2018'] = Ed25519VerificationKey2018; - this.keys['RsaSignature2018'] = RSAKeyPair; + this.keys['Ed25519Signature2020'] = { + name: 'Ed25519VerificationKey2020', + key: Ed25519VerificationKey2020 + }; + this.keys['Ed25519Signature2018'] = { + name: 'Ed25519VerificationKey2018', + key: Ed25519VerificationKey2018 + }; + this.keys['RsaSignature2018'] = { + name: 'RsaVerificationKey2018', + key: RSAKeyPair + }; const { Resolver } = await import('did-resolver'); const { getResolver } = await import('web-did-resolver'); const webResolver = getResolver(); @@ -53,6 +69,26 @@ export class DidService { return `${this.webDidBaseUrl}${id}`; } + async getVerificationKey(signingAlgorithm?: string): Promise { + if(!this.keys[signingAlgorithm]) { + await this.init(); + } + if(!this.keys[signingAlgorithm]) { + throw new NotFoundException("Signature suite not supported") + } + return this.keys[signingAlgorithm]; + } + + async getVerificationKeyByName(name?: string) { + let verificationKey = Object.values(this.keys).find((d: {name: string, key: any}) => d.name === name); + if(!verificationKey) { + await this.init(); + verificationKey = Object.values(this.keys).find((d: {name: string, key: any}) => d.name === name); + } + if(name && !verificationKey) throw new NotFoundException("Verification Key '" + name + "' not found"); + return verificationKey; + } + async generateDID(doc: GenerateDidDTO): Promise { // Create a UUID for the DID using uuidv4 const didUri: string = this.generateDidUri(doc?.method, doc?.id); @@ -60,15 +96,10 @@ export class DidService { // Create private/public key pair let authnKeys; let privateKeys: object; - let signingAlgorithm: string = this.signingAlgorithm; + let verificationKey = await this.getVerificationKeyByName(doc?.keyPairType); + if(!verificationKey) verificationKey = await this.getVerificationKey(this.signingAlgorithm); try { - if(!this.keys[signingAlgorithm]) { - await this.init(); - } - if(!this.keys[signingAlgorithm]) { - throw new NotFoundException("Signature suite not supported") - } - const keyPair = await this.keys[signingAlgorithm].generate({ + const keyPair = await (verificationKey as any)?.key.generate({ id: `${didUri}#key-0`, controller: didUri }); @@ -76,27 +107,27 @@ export class DidService { publicKey: true, privateKey: true, includeContext: true }); let privateKey = {}; - if(signingAlgorithm === "Ed25519Signature2020") { + if(verificationKey?.name === "Ed25519VerificationKey2020") { const {privateKeyMultibase, ...rest } = exportedKey; authnKeys = rest; privateKey = {privateKeyMultibase}; - } else if(signingAlgorithm === "Ed25519Signature2018") { + } else if(verificationKey?.name === "Ed25519VerificationKey2018") { const {privateKeyBase58, ...rest } = exportedKey; authnKeys = rest; privateKey = {privateKeyBase58}; - } else if(signingAlgorithm === "RsaSignature2018") { + } else if(verificationKey?.name === "RsaVerificationKey2018") { const {privateKeyPem, ...rest } = exportedKey; authnKeys = {...rest}; privateKey = {privateKeyPem}; } else { - throw new NotFoundException("Signature type not found"); + throw new NotFoundException("VerificationKey type not found"); } privateKeys = { [authnKeys.id]: privateKey }; } catch (err: any) { Logger.error(`Error generating key pair: ${err}`); - throw new InternalServerErrorException('Error generating key pair'); + throw new InternalServerErrorException('Error generating key pair: ' + err.message); } const keyId = authnKeys?.id; diff --git a/services/identity-service/src/did/dtos/GenerateDid.dto.ts b/services/identity-service/src/did/dtos/GenerateDid.dto.ts index b58a24df7..9a1f3931b 100644 --- a/services/identity-service/src/did/dtos/GenerateDid.dto.ts +++ b/services/identity-service/src/did/dtos/GenerateDid.dto.ts @@ -2,6 +2,12 @@ import { ApiProperty } from '@nestjs/swagger'; const { Service } = require('did-resolver'); type Service = typeof Service; +enum VerificationKeyType { + Ed25519VerificationKey2020 = "Ed25519VerificationKey2020", + Ed25519VerificationKey2018 = "Ed25519VerificationKey2018", + RsaVerificationKey2018 = "RsaVerificationKey2018" +} + export class GenerateDidDTO { @ApiProperty({ description: @@ -22,4 +28,9 @@ export class GenerateDidDTO { }) method: string; id?: string; + @ApiProperty({ + description: 'The keypair type to be generated', + enum: VerificationKeyType + }) + keyPairType?: VerificationKeyType }