1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-16 10:45:20 +01:00

[EC-598] feat: add fido2Key to cipher

This commit is contained in:
Andreas Coroiu 2023-01-03 15:49:32 +01:00
parent 0225093c11
commit cb07b2121e
No known key found for this signature in database
GPG Key ID: E70B5FFC81DFEC1A
10 changed files with 158 additions and 1 deletions

View File

@ -3,4 +3,5 @@ export enum CipherType {
SecureNote = 2,
Card = 3,
Identity = 4,
Fido2Key = 5,
}

View File

@ -0,0 +1,20 @@
import { BaseResponse } from "../response/base.response";
export class Fido2KeyApi extends BaseResponse {
key: string;
rpId: string;
origin: string;
userHandle: string;
constructor(data: any = null) {
super(data);
if (data == null) {
return;
}
this.key = this.getResponseProperty("Key");
this.rpId = this.getResponseProperty("RpId");
this.origin = this.getResponseProperty("Origin");
this.userHandle = this.getResponseProperty("UserHandle");
}
}

View File

@ -4,6 +4,7 @@ import { CipherResponse } from "../response/cipher.response";
import { AttachmentData } from "./attachment.data";
import { CardData } from "./card.data";
import { Fido2KeyData } from "./fido2-key.data";
import { FieldData } from "./field.data";
import { IdentityData } from "./identity.data";
import { LoginData } from "./login.data";
@ -26,6 +27,7 @@ export class CipherData {
secureNote?: SecureNoteData;
card?: CardData;
identity?: IdentityData;
fido2Key?: Fido2KeyData;
fields?: FieldData[];
attachments?: AttachmentData[];
passwordHistory?: PasswordHistoryData[];
@ -68,6 +70,9 @@ export class CipherData {
case CipherType.Identity:
this.identity = new IdentityData(response.identity);
break;
case CipherType.Fido2Key:
this.fido2Key = new Fido2KeyData(response.fido2Key);
break;
default:
break;
}

View File

@ -0,0 +1,19 @@
import { Fido2KeyApi } from "../api/fido2-key.api";
export class Fido2KeyData {
key: string;
rpId: string;
origin: string;
userHandle: string;
constructor(data?: Fido2KeyApi) {
if (data == null) {
return;
}
this.key = data.key;
this.rpId = data.rpId;
this.origin = data.origin;
this.userHandle = data.userHandle;
}
}

View File

@ -12,6 +12,7 @@ import { Attachment } from "./attachment";
import { Card } from "./card";
import Domain from "./domain-base";
import { EncString } from "./enc-string";
import { Fido2Key } from "./fido2-key";
import { Field } from "./field";
import { Identity } from "./identity";
import { Login } from "./login";
@ -38,6 +39,7 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
identity: Identity;
card: Card;
secureNote: SecureNote;
fido2Key: Fido2Key;
attachments: Attachment[];
fields: Field[];
passwordHistory: Password[];
@ -94,6 +96,9 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
case CipherType.Identity:
this.identity = new Identity(obj.identity);
break;
case CipherType.Fido2Key:
this.fido2Key = new Fido2Key(obj.fido2Key);
break;
default:
break;
}
@ -143,6 +148,9 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
case CipherType.Identity:
model.identity = await this.identity.decrypt(this.organizationId, encKey);
break;
case CipherType.Fido2Key:
model.fido2Key = await this.fido2Key.decrypt(this.organizationId, encKey);
break;
default:
break;
}
@ -228,6 +236,9 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
case CipherType.Identity:
c.identity = this.identity.toIdentityData();
break;
case CipherType.Fido2Key:
c.fido2Key = this.fido2Key.toFido2KeyData();
break;
default:
break;
}
@ -281,6 +292,9 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
case CipherType.SecureNote:
domain.secureNote = SecureNote.fromJSON(obj.secureNote);
break;
case CipherType.Fido2Key:
domain.fido2Key = Fido2Key.fromJSON(obj.fido2Key);
break;
default:
break;
}

View File

@ -0,0 +1,78 @@
import { Jsonify } from "type-fest";
import { Fido2KeyData } from "../data/fido2-key.data";
import { Fido2KeyView } from "../view/fido2-key.view";
import Domain from "./domain-base";
import { EncString } from "./enc-string";
import { SymmetricCryptoKey } from "./symmetric-crypto-key";
export class Fido2Key extends Domain {
key: EncString; // PCKS#8
rpId: EncString;
origin: EncString;
userHandle: EncString;
// extensions: Record<string, unknown>;
constructor(obj?: Fido2KeyData) {
super();
if (obj == null) {
return;
}
this.buildDomainModel(
this,
obj,
{
key: null,
rpId: null,
origin: null,
userHandle: null,
},
[]
);
}
decrypt(orgId: string, encKey?: SymmetricCryptoKey): Promise<Fido2KeyView> {
return this.decryptObj(
new Fido2KeyView(),
{
key: null,
rpId: null,
origin: null,
userHandle: null,
},
orgId,
encKey
);
}
toFido2KeyData(): Fido2KeyData {
const i = new Fido2KeyData();
this.buildDataModel(this, i, {
key: null,
rpId: null,
origin: null,
userHandle: null,
});
return i;
}
static fromJSON(obj: Jsonify<Fido2Key>): Fido2Key {
if (obj == null) {
return null;
}
const key = EncString.fromJSON(obj.key);
const rpId = EncString.fromJSON(obj.rpId);
const origin = EncString.fromJSON(obj.origin);
const userHandle = EncString.fromJSON(obj.userHandle);
return Object.assign(new Fido2Key(), obj, {
key,
rpId,
origin,
userHandle,
});
}
}

View File

@ -1,5 +1,6 @@
import { CipherRepromptType } from "../../enums/cipherRepromptType";
import { CardApi } from "../api/card.api";
import { Fido2KeyApi } from "../api/fido2-key.api";
import { FieldApi } from "../api/field.api";
import { IdentityApi } from "../api/identity.api";
import { LoginApi } from "../api/login.api";
@ -21,6 +22,7 @@ export class CipherResponse extends BaseResponse {
card: CardApi;
identity: IdentityApi;
secureNote: SecureNoteApi;
fido2Key: Fido2KeyApi;
favorite: boolean;
edit: boolean;
viewPassword: boolean;
@ -74,6 +76,11 @@ export class CipherResponse extends BaseResponse {
this.secureNote = new SecureNoteApi(secureNote);
}
const fido2Key = this.getResponseProperty("Fido2Key");
if (fido2Key != null) {
this.fido2Key = new Fido2KeyApi(fido2Key);
}
const fields = this.getResponseProperty("Fields");
if (fields != null) {
this.fields = fields.map((f: any) => new FieldApi(f));

View File

@ -10,6 +10,7 @@ import { Cipher } from "../domain/cipher";
import { AttachmentView } from "./attachment.view";
import { CardView } from "./card.view";
import { Fido2KeyView } from "./fido2-key.view";
import { FieldView } from "./field.view";
import { IdentityView } from "./identity.view";
import { LoginView } from "./login.view";
@ -35,6 +36,7 @@ export class CipherView implements View, InitializerMetadata {
identity = new IdentityView();
card = new CardView();
secureNote = new SecureNoteView();
fido2Key = new Fido2KeyView();
attachments: AttachmentView[] = null;
fields: FieldView[] = null;
passwordHistory: PasswordHistoryView[] = null;

View File

@ -0,0 +1,7 @@
export class Fido2KeyView {
id: string;
key: string;
rpId: string;
origin: string;
userHandle: string;
}

View File

@ -84,7 +84,7 @@ export class Fido2Service implements Fido2ServiceAbstraction {
})
);
this.credentials.set(credentialId.encoded, {
await this.saveCredential({
credentialId,
keyPair,
origin: params.origin,
@ -170,6 +170,10 @@ export class Fido2Service implements Fido2ServiceAbstraction {
return credential;
}
private async saveCredential(credential: BitCredential): Promise<void> {
this.credentials.set(credential.credentialId.encoded, credential);
}
private getCredentialByRp(rpId: string): BitCredential | undefined {
for (const credential of this.credentials.values()) {
if (credential.rpId === rpId) {