From da163992d73ee020dc719b29a64ec12f663c8ae1 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Thu, 5 Jan 2023 16:19:42 +0100 Subject: [PATCH] [EC-598] feat: allow storage of more information --- libs/common/src/models/api/fido2-key.api.ts | 15 ++++-- libs/common/src/models/data/fido2-key.data.ts | 16 ++++-- libs/common/src/models/domain/fido2-key.ts | 49 ++++++++++++++----- .../src/models/request/cipher.request.ts | 18 +++++-- libs/common/src/models/view/fido2-key.view.ts | 8 ++- .../src/services/fido2/fido2.service.ts | 40 ++++++++++----- 6 files changed, 108 insertions(+), 38 deletions(-) diff --git a/libs/common/src/models/api/fido2-key.api.ts b/libs/common/src/models/api/fido2-key.api.ts index 08d4715d0e7..cca96ef7413 100644 --- a/libs/common/src/models/api/fido2-key.api.ts +++ b/libs/common/src/models/api/fido2-key.api.ts @@ -1,10 +1,14 @@ import { BaseResponse } from "../response/base.response"; export class Fido2KeyApi extends BaseResponse { - key: string; + keyType: "ECDSA"; + keyCurve: "P-256"; + keyValue: string; rpId: string; - origin: string; + rpName: string; userHandle: string; + userName: string; + origin: string; constructor(data: any = null) { super(data); @@ -12,9 +16,12 @@ export class Fido2KeyApi extends BaseResponse { return; } - this.key = this.getResponseProperty("Key"); + this.keyType = this.getResponseProperty("KeyType"); + this.keyCurve = this.getResponseProperty("KeyCurve"); + this.keyValue = this.getResponseProperty("keyValue"); this.rpId = this.getResponseProperty("RpId"); - this.origin = this.getResponseProperty("Origin"); this.userHandle = this.getResponseProperty("UserHandle"); + this.userName = this.getResponseProperty("UserName"); + this.origin = this.getResponseProperty("Origin"); } } diff --git a/libs/common/src/models/data/fido2-key.data.ts b/libs/common/src/models/data/fido2-key.data.ts index 6392339836c..8798ffb910b 100644 --- a/libs/common/src/models/data/fido2-key.data.ts +++ b/libs/common/src/models/data/fido2-key.data.ts @@ -1,19 +1,27 @@ import { Fido2KeyApi } from "../api/fido2-key.api"; export class Fido2KeyData { - key: string; + keyType: "ECDSA"; + keyCurve: "P-256"; + keyValue: string; rpId: string; - origin: string; + rpName: string; userHandle: string; + userName: string; + origin: string; constructor(data?: Fido2KeyApi) { if (data == null) { return; } - this.key = data.key; + this.keyType = data.keyType; + this.keyCurve = data.keyCurve; + this.keyValue = data.keyValue; this.rpId = data.rpId; - this.origin = data.origin; + this.rpName = data.rpName; this.userHandle = data.userHandle; + this.userName = data.userName; + this.origin = data.origin; } } diff --git a/libs/common/src/models/domain/fido2-key.ts b/libs/common/src/models/domain/fido2-key.ts index b1fd93e672a..4694d739c4b 100644 --- a/libs/common/src/models/domain/fido2-key.ts +++ b/libs/common/src/models/domain/fido2-key.ts @@ -8,11 +8,14 @@ import { EncString } from "./enc-string"; import { SymmetricCryptoKey } from "./symmetric-crypto-key"; export class Fido2Key extends Domain { - key: EncString; // PCKS#8 + keyType: EncString; + keyCurve: EncString; + keyValue: EncString; rpId: EncString; - origin: EncString; + rpName: EncString; userHandle: EncString; - // extensions: Record; + userName: EncString; + origin: EncString; constructor(obj?: Fido2KeyData) { super(); @@ -24,10 +27,14 @@ export class Fido2Key extends Domain { this, obj, { - key: null, + keyType: null, + keyCurve: null, + keyValue: null, rpId: null, - origin: null, + rpName: null, userHandle: null, + userName: null, + origin: null, }, [] ); @@ -37,10 +44,14 @@ export class Fido2Key extends Domain { return this.decryptObj( new Fido2KeyView(), { - key: null, + keyType: null, + keyCurve: null, + keyValue: null, rpId: null, - origin: null, + rpName: null, userHandle: null, + userName: null, + origin: null, }, orgId, encKey @@ -50,10 +61,14 @@ export class Fido2Key extends Domain { toFido2KeyData(): Fido2KeyData { const i = new Fido2KeyData(); this.buildDataModel(this, i, { - key: null, + keyType: null, + keyCurve: null, + keyValue: null, rpId: null, - origin: null, + rpName: null, userHandle: null, + userName: null, + origin: null, }); return i; } @@ -63,16 +78,24 @@ export class Fido2Key extends Domain { return null; } - const key = EncString.fromJSON(obj.key); + const keyType = EncString.fromJSON(obj.keyType); + const keyCurve = EncString.fromJSON(obj.keyCurve); + const keyValue = EncString.fromJSON(obj.keyValue); const rpId = EncString.fromJSON(obj.rpId); - const origin = EncString.fromJSON(obj.origin); + const rpName = EncString.fromJSON(obj.rpName); const userHandle = EncString.fromJSON(obj.userHandle); + const userName = EncString.fromJSON(obj.userName); + const origin = EncString.fromJSON(obj.origin); return Object.assign(new Fido2Key(), obj, { - key, + keyType, + keyCurve, + keyValue, rpId, - origin, + rpName, userHandle, + userName, + origin, }); } } diff --git a/libs/common/src/models/request/cipher.request.ts b/libs/common/src/models/request/cipher.request.ts index 6eb9203981f..e2e43a23087 100644 --- a/libs/common/src/models/request/cipher.request.ts +++ b/libs/common/src/models/request/cipher.request.ts @@ -125,14 +125,24 @@ export class CipherRequest { break; case CipherType.Fido2Key: this.fido2Key = new Fido2KeyApi(); - this.fido2Key.key = - cipher.fido2Key.key != null ? cipher.fido2Key.key.encryptedString : null; - this.fido2Key.origin = - cipher.fido2Key.origin != null ? cipher.fido2Key.origin.encryptedString : null; + this.fido2Key.keyType = + cipher.fido2Key.keyType != null + ? (cipher.fido2Key.keyType.encryptedString as "ECDSA") + : null; + this.fido2Key.keyCurve = + cipher.fido2Key.keyCurve != null + ? (cipher.fido2Key.keyCurve.encryptedString as "P-256") + : null; + this.fido2Key.keyValue = + cipher.fido2Key.keyValue != null ? cipher.fido2Key.keyValue.encryptedString : null; this.fido2Key.rpId = cipher.fido2Key.rpId != null ? cipher.fido2Key.rpId.encryptedString : null; this.fido2Key.userHandle = cipher.fido2Key.userHandle != null ? cipher.fido2Key.userHandle.encryptedString : null; + this.fido2Key.userName = + cipher.fido2Key.userName != null ? cipher.fido2Key.userName.encryptedString : null; + this.fido2Key.origin = + cipher.fido2Key.origin != null ? cipher.fido2Key.origin.encryptedString : null; break; default: break; diff --git a/libs/common/src/models/view/fido2-key.view.ts b/libs/common/src/models/view/fido2-key.view.ts index aa7b4309dcc..7b019105ae8 100644 --- a/libs/common/src/models/view/fido2-key.view.ts +++ b/libs/common/src/models/view/fido2-key.view.ts @@ -1,10 +1,14 @@ import { ItemView } from "./item.view"; export class Fido2KeyView extends ItemView { - key: string; + keyType: "ECDSA"; + keyCurve: "P-256"; + keyValue: string; rpId: string; - origin: string; + rpName: string; userHandle: string; + userName: string; + origin: string; get subTitle(): string { return null; diff --git a/libs/common/src/services/fido2/fido2.service.ts b/libs/common/src/services/fido2/fido2.service.ts index af7510ba0a9..d24ba9f51a4 100644 --- a/libs/common/src/services/fido2/fido2.service.ts +++ b/libs/common/src/services/fido2/fido2.service.ts @@ -25,10 +25,14 @@ const STANDARD_ATTESTATION_FORMAT = "packed"; interface BitCredential { credentialId: CredentialId; - privateKey: CryptoKey; + keyType: "ECDSA"; + keyCurve: "P-256"; + keyValue: CryptoKey; rpId: string; - origin: string; + rpName: string; userHandle: Uint8Array; + userName: string; + origin: string; } const KeyUsages: KeyUsage[] = ["sign"]; @@ -68,10 +72,14 @@ export class Fido2Service implements Fido2ServiceAbstraction { ); const credentialId = await this.saveCredential({ - privateKey: keyPair.privateKey, + keyType: "ECDSA", + keyCurve: "P-256", + keyValue: keyPair.privateKey, origin: params.origin, rpId: params.rp.id, + rpName: params.rp.name, userHandle: Fido2Utils.stringToBuffer(params.user.id), + userName: params.user.displayName, }); const authData = await generateAuthData({ @@ -163,7 +171,7 @@ export class Fido2Service implements Fido2ServiceAbstraction { const signature = await generateSignature({ authData, clientData, - privateKey: credential.privateKey, + privateKey: credential.keyValue, }); return { @@ -200,16 +208,22 @@ export class Fido2Service implements Fido2ServiceAbstraction { private async saveCredential( credential: Omit ): Promise { - const pcks8Key = await crypto.subtle.exportKey("pkcs8", credential.privateKey); + const pcks8Key = await crypto.subtle.exportKey("pkcs8", credential.keyValue); const view = new CipherView(); view.type = CipherType.Fido2Key; view.name = credential.origin; view.fido2Key = new Fido2KeyView(); - view.fido2Key.key = Fido2Utils.bufferToString(pcks8Key); view.fido2Key.origin = credential.origin; + + view.fido2Key.keyType = credential.keyType; + view.fido2Key.keyCurve = credential.keyCurve; + view.fido2Key.keyValue = Fido2Utils.bufferToString(pcks8Key); view.fido2Key.rpId = credential.rpId; + view.fido2Key.rpName = credential.rpName; view.fido2Key.userHandle = Fido2Utils.bufferToString(credential.userHandle); + view.fido2Key.userName = credential.userName; + view.fido2Key.origin = credential.origin; const cipher = await this.cipherService.encrypt(view); await this.cipherService.createWithServer(cipher); @@ -238,13 +252,13 @@ interface AuthDataParams { } async function mapCipherViewToBitCredential(cipherView: CipherView): Promise { - const keyBuffer = Fido2Utils.stringToBuffer(cipherView.fido2Key.key); + const keyBuffer = Fido2Utils.stringToBuffer(cipherView.fido2Key.keyValue); const privateKey = await crypto.subtle.importKey( "pkcs8", keyBuffer, { - name: "ECDSA", - namedCurve: "P-256", + name: cipherView.fido2Key.keyType, + namedCurve: cipherView.fido2Key.keyCurve, }, true, KeyUsages @@ -252,10 +266,14 @@ async function mapCipherViewToBitCredential(cipherView: CipherView): Promise