1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 16:23:44 +00:00

[EC-598] feat: allow storage of more information

This commit is contained in:
Andreas Coroiu
2023-01-05 16:19:42 +01:00
parent 4168f49911
commit da163992d7
6 changed files with 108 additions and 38 deletions

View File

@@ -1,10 +1,14 @@
import { BaseResponse } from "../response/base.response"; import { BaseResponse } from "../response/base.response";
export class Fido2KeyApi extends BaseResponse { export class Fido2KeyApi extends BaseResponse {
key: string; keyType: "ECDSA";
keyCurve: "P-256";
keyValue: string;
rpId: string; rpId: string;
origin: string; rpName: string;
userHandle: string; userHandle: string;
userName: string;
origin: string;
constructor(data: any = null) { constructor(data: any = null) {
super(data); super(data);
@@ -12,9 +16,12 @@ export class Fido2KeyApi extends BaseResponse {
return; 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.rpId = this.getResponseProperty("RpId");
this.origin = this.getResponseProperty("Origin");
this.userHandle = this.getResponseProperty("UserHandle"); this.userHandle = this.getResponseProperty("UserHandle");
this.userName = this.getResponseProperty("UserName");
this.origin = this.getResponseProperty("Origin");
} }
} }

View File

@@ -1,19 +1,27 @@
import { Fido2KeyApi } from "../api/fido2-key.api"; import { Fido2KeyApi } from "../api/fido2-key.api";
export class Fido2KeyData { export class Fido2KeyData {
key: string; keyType: "ECDSA";
keyCurve: "P-256";
keyValue: string;
rpId: string; rpId: string;
origin: string; rpName: string;
userHandle: string; userHandle: string;
userName: string;
origin: string;
constructor(data?: Fido2KeyApi) { constructor(data?: Fido2KeyApi) {
if (data == null) { if (data == null) {
return; return;
} }
this.key = data.key; this.keyType = data.keyType;
this.keyCurve = data.keyCurve;
this.keyValue = data.keyValue;
this.rpId = data.rpId; this.rpId = data.rpId;
this.origin = data.origin; this.rpName = data.rpName;
this.userHandle = data.userHandle; this.userHandle = data.userHandle;
this.userName = data.userName;
this.origin = data.origin;
} }
} }

View File

@@ -8,11 +8,14 @@ import { EncString } from "./enc-string";
import { SymmetricCryptoKey } from "./symmetric-crypto-key"; import { SymmetricCryptoKey } from "./symmetric-crypto-key";
export class Fido2Key extends Domain { export class Fido2Key extends Domain {
key: EncString; // PCKS#8 keyType: EncString;
keyCurve: EncString;
keyValue: EncString;
rpId: EncString; rpId: EncString;
origin: EncString; rpName: EncString;
userHandle: EncString; userHandle: EncString;
// extensions: Record<string, unknown>; userName: EncString;
origin: EncString;
constructor(obj?: Fido2KeyData) { constructor(obj?: Fido2KeyData) {
super(); super();
@@ -24,10 +27,14 @@ export class Fido2Key extends Domain {
this, this,
obj, obj,
{ {
key: null, keyType: null,
keyCurve: null,
keyValue: null,
rpId: null, rpId: null,
origin: null, rpName: null,
userHandle: null, userHandle: null,
userName: null,
origin: null,
}, },
[] []
); );
@@ -37,10 +44,14 @@ export class Fido2Key extends Domain {
return this.decryptObj( return this.decryptObj(
new Fido2KeyView(), new Fido2KeyView(),
{ {
key: null, keyType: null,
keyCurve: null,
keyValue: null,
rpId: null, rpId: null,
origin: null, rpName: null,
userHandle: null, userHandle: null,
userName: null,
origin: null,
}, },
orgId, orgId,
encKey encKey
@@ -50,10 +61,14 @@ export class Fido2Key extends Domain {
toFido2KeyData(): Fido2KeyData { toFido2KeyData(): Fido2KeyData {
const i = new Fido2KeyData(); const i = new Fido2KeyData();
this.buildDataModel(this, i, { this.buildDataModel(this, i, {
key: null, keyType: null,
keyCurve: null,
keyValue: null,
rpId: null, rpId: null,
origin: null, rpName: null,
userHandle: null, userHandle: null,
userName: null,
origin: null,
}); });
return i; return i;
} }
@@ -63,16 +78,24 @@ export class Fido2Key extends Domain {
return null; 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 rpId = EncString.fromJSON(obj.rpId);
const origin = EncString.fromJSON(obj.origin); const rpName = EncString.fromJSON(obj.rpName);
const userHandle = EncString.fromJSON(obj.userHandle); const userHandle = EncString.fromJSON(obj.userHandle);
const userName = EncString.fromJSON(obj.userName);
const origin = EncString.fromJSON(obj.origin);
return Object.assign(new Fido2Key(), obj, { return Object.assign(new Fido2Key(), obj, {
key, keyType,
keyCurve,
keyValue,
rpId, rpId,
origin, rpName,
userHandle, userHandle,
userName,
origin,
}); });
} }
} }

View File

@@ -125,14 +125,24 @@ export class CipherRequest {
break; break;
case CipherType.Fido2Key: case CipherType.Fido2Key:
this.fido2Key = new Fido2KeyApi(); this.fido2Key = new Fido2KeyApi();
this.fido2Key.key = this.fido2Key.keyType =
cipher.fido2Key.key != null ? cipher.fido2Key.key.encryptedString : null; cipher.fido2Key.keyType != null
this.fido2Key.origin = ? (cipher.fido2Key.keyType.encryptedString as "ECDSA")
cipher.fido2Key.origin != null ? cipher.fido2Key.origin.encryptedString : null; : 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 = this.fido2Key.rpId =
cipher.fido2Key.rpId != null ? cipher.fido2Key.rpId.encryptedString : null; cipher.fido2Key.rpId != null ? cipher.fido2Key.rpId.encryptedString : null;
this.fido2Key.userHandle = this.fido2Key.userHandle =
cipher.fido2Key.userHandle != null ? cipher.fido2Key.userHandle.encryptedString : null; 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; break;
default: default:
break; break;

View File

@@ -1,10 +1,14 @@
import { ItemView } from "./item.view"; import { ItemView } from "./item.view";
export class Fido2KeyView extends ItemView { export class Fido2KeyView extends ItemView {
key: string; keyType: "ECDSA";
keyCurve: "P-256";
keyValue: string;
rpId: string; rpId: string;
origin: string; rpName: string;
userHandle: string; userHandle: string;
userName: string;
origin: string;
get subTitle(): string { get subTitle(): string {
return null; return null;

View File

@@ -25,10 +25,14 @@ const STANDARD_ATTESTATION_FORMAT = "packed";
interface BitCredential { interface BitCredential {
credentialId: CredentialId; credentialId: CredentialId;
privateKey: CryptoKey; keyType: "ECDSA";
keyCurve: "P-256";
keyValue: CryptoKey;
rpId: string; rpId: string;
origin: string; rpName: string;
userHandle: Uint8Array; userHandle: Uint8Array;
userName: string;
origin: string;
} }
const KeyUsages: KeyUsage[] = ["sign"]; const KeyUsages: KeyUsage[] = ["sign"];
@@ -68,10 +72,14 @@ export class Fido2Service implements Fido2ServiceAbstraction {
); );
const credentialId = await this.saveCredential({ const credentialId = await this.saveCredential({
privateKey: keyPair.privateKey, keyType: "ECDSA",
keyCurve: "P-256",
keyValue: keyPair.privateKey,
origin: params.origin, origin: params.origin,
rpId: params.rp.id, rpId: params.rp.id,
rpName: params.rp.name,
userHandle: Fido2Utils.stringToBuffer(params.user.id), userHandle: Fido2Utils.stringToBuffer(params.user.id),
userName: params.user.displayName,
}); });
const authData = await generateAuthData({ const authData = await generateAuthData({
@@ -163,7 +171,7 @@ export class Fido2Service implements Fido2ServiceAbstraction {
const signature = await generateSignature({ const signature = await generateSignature({
authData, authData,
clientData, clientData,
privateKey: credential.privateKey, privateKey: credential.keyValue,
}); });
return { return {
@@ -200,16 +208,22 @@ export class Fido2Service implements Fido2ServiceAbstraction {
private async saveCredential( private async saveCredential(
credential: Omit<BitCredential, "credentialId"> credential: Omit<BitCredential, "credentialId">
): Promise<CredentialId> { ): Promise<CredentialId> {
const pcks8Key = await crypto.subtle.exportKey("pkcs8", credential.privateKey); const pcks8Key = await crypto.subtle.exportKey("pkcs8", credential.keyValue);
const view = new CipherView(); const view = new CipherView();
view.type = CipherType.Fido2Key; view.type = CipherType.Fido2Key;
view.name = credential.origin; view.name = credential.origin;
view.fido2Key = new Fido2KeyView(); view.fido2Key = new Fido2KeyView();
view.fido2Key.key = Fido2Utils.bufferToString(pcks8Key);
view.fido2Key.origin = credential.origin; 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.rpId = credential.rpId;
view.fido2Key.rpName = credential.rpName;
view.fido2Key.userHandle = Fido2Utils.bufferToString(credential.userHandle); view.fido2Key.userHandle = Fido2Utils.bufferToString(credential.userHandle);
view.fido2Key.userName = credential.userName;
view.fido2Key.origin = credential.origin;
const cipher = await this.cipherService.encrypt(view); const cipher = await this.cipherService.encrypt(view);
await this.cipherService.createWithServer(cipher); await this.cipherService.createWithServer(cipher);
@@ -238,13 +252,13 @@ interface AuthDataParams {
} }
async function mapCipherViewToBitCredential(cipherView: CipherView): Promise<BitCredential> { async function mapCipherViewToBitCredential(cipherView: CipherView): Promise<BitCredential> {
const keyBuffer = Fido2Utils.stringToBuffer(cipherView.fido2Key.key); const keyBuffer = Fido2Utils.stringToBuffer(cipherView.fido2Key.keyValue);
const privateKey = await crypto.subtle.importKey( const privateKey = await crypto.subtle.importKey(
"pkcs8", "pkcs8",
keyBuffer, keyBuffer,
{ {
name: "ECDSA", name: cipherView.fido2Key.keyType,
namedCurve: "P-256", namedCurve: cipherView.fido2Key.keyCurve,
}, },
true, true,
KeyUsages KeyUsages
@@ -252,10 +266,14 @@ async function mapCipherViewToBitCredential(cipherView: CipherView): Promise<Bit
return { return {
credentialId: new CredentialId(cipherView.id), credentialId: new CredentialId(cipherView.id),
privateKey, keyType: cipherView.fido2Key.keyType,
origin: cipherView.fido2Key.origin, keyCurve: cipherView.fido2Key.keyCurve,
keyValue: privateKey,
rpId: cipherView.fido2Key.rpId, rpId: cipherView.fido2Key.rpId,
rpName: cipherView.fido2Key.rpName,
userHandle: Fido2Utils.stringToBuffer(cipherView.fido2Key.userHandle), userHandle: Fido2Utils.stringToBuffer(cipherView.fido2Key.userHandle),
userName: cipherView.fido2Key.userName,
origin: cipherView.fido2Key.origin,
}; };
} }