1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 08:13:42 +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";
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");
}
}

View File

@@ -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;
}
}

View File

@@ -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<string, unknown>;
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,
});
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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<BitCredential, "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();
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<BitCredential> {
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<Bit
return {
credentialId: new CredentialId(cipherView.id),
privateKey,
origin: cipherView.fido2Key.origin,
keyType: cipherView.fido2Key.keyType,
keyCurve: cipherView.fido2Key.keyCurve,
keyValue: privateKey,
rpId: cipherView.fido2Key.rpId,
rpName: cipherView.fido2Key.rpName,
userHandle: Fido2Utils.stringToBuffer(cipherView.fido2Key.userHandle),
userName: cipherView.fido2Key.userName,
origin: cipherView.fido2Key.origin,
};
}