Skip to content

Commit

Permalink
Merge pull request #328 from holashchand/issue-1019
Browse files Browse the repository at this point in the history
[FEAT]: added support to generate did document with specific key pair
  • Loading branch information
challabeehyv authored Jun 11, 2024
2 parents 0194269 + 306ed57 commit f180784
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 19 deletions.
66 changes: 48 additions & 18 deletions services/identity-service/src/did/did.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ import { GenerateDidDTO } from './dtos/GenerateDidRequest.dto';

const { DIDDocument } = require('did-resolver');
type DIDDocument = typeof DIDDocument;

type KeysType = {
[key: string]: {
name: string;
key: any;
};
};
@Injectable()
export class DidService {
keys = {}
keys: KeysType = {
}
webDidPrefix: string;
signingAlgorithm: string;
didResolver: any;
Expand All @@ -25,9 +31,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();
Expand Down Expand Up @@ -63,50 +78,65 @@ export class DidService {
return `${this.webDidPrefix}${id}`;
}

async getVerificationKey(signingAlgorithm?: string): Promise<any> {
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<DIDDocument> {
// Create a UUID for the DID using uuidv4
const didUri: string = this.generateDidUri(doc?.method, doc?.id, doc?.webDidBaseUrl);

// 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
});
const exportedKey = await keyPair.export({
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;
Expand Down
13 changes: 12 additions & 1 deletion services/identity-service/src/did/dtos/GenerateDidRequest.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -34,6 +40,11 @@ export class GenerateDidDTO {
description: 'In case of method "web" the web url path to access the did document. It would be appended by generated uuid',
})
webDidBaseUrl?: string;
@ApiProperty({
description: 'The keypair type to be generated',
enum: VerificationKeyType
})
keyPairType?: VerificationKeyType;
}

export class GenerateDidRequestDTO {
Expand All @@ -42,5 +53,5 @@ export class GenerateDidRequestDTO {
description: 'List of generate did requests',
isArray: true
})
content: GenerateDidDTO[]
content: GenerateDidDTO[];
}

0 comments on commit f180784

Please sign in to comment.