1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-15 15:53:44 +00:00

[PM-5731] feat: return public key in DER format

This commit is contained in:
Andreas Coroiu
2024-01-29 13:50:30 +01:00
parent da7326b0cc
commit 7ca9e61e93

View File

@@ -102,7 +102,7 @@ namespace Bit.Core.Services
CredentialId = GuidToRawFormat(credentialId), CredentialId = GuidToRawFormat(credentialId),
AttestationObject = EncodeAttestationObject(authData), AttestationObject = EncodeAttestationObject(authData),
AuthData = authData, AuthData = authData,
PublicKey = Array.Empty<byte>(), PublicKey = keyPair.publicKey.ExportDer(),
PublicKeyAlgorithm = (int) Fido2AlgorithmIdentifier.ES256, PublicKeyAlgorithm = (int) Fido2AlgorithmIdentifier.ES256,
}; };
} catch (NotAllowedError) { } catch (NotAllowedError) {
@@ -286,19 +286,11 @@ namespace Bit.Core.Services
// TODO: Move this to a separate service // TODO: Move this to a separate service
private (PublicKey publicKey, byte[] privateKey) GenerateKeyPair() private (PublicKey publicKey, byte[] privateKey) GenerateKeyPair()
{ {
using (System.Security.Cryptography.ECDsa dsa = System.Security.Cryptography.ECDsa.Create()) var dsa = System.Security.Cryptography.ECDsa.Create();
{ dsa.GenerateKey(System.Security.Cryptography.ECCurve.NamedCurves.nistP256);
dsa.GenerateKey(System.Security.Cryptography.ECCurve.NamedCurves.nistP256); var privateKey = dsa.ExportPkcs8PrivateKey();
var privateKey = dsa.ExportPkcs8PrivateKey();
System.Security.Cryptography.ECParameters parameters = dsa.ExportParameters(true); return (new PublicKey(dsa), privateKey);
return (
new PublicKey {
X = parameters.Q.X,
Y = parameters.Q.Y
}, privateKey);
}
} }
private Fido2CredentialView CreateCredentialView(Fido2AuthenticatorMakeCredentialParams makeCredentialsParams, byte[] privateKey) private Fido2CredentialView CreateCredentialView(Fido2AuthenticatorMakeCredentialParams makeCredentialsParams, byte[] privateKey)
@@ -326,9 +318,9 @@ namespace Bit.Core.Services
bool userPresence, bool userPresence,
int counter, int counter,
byte[] credentialId = null, byte[] credentialId = null,
PublicKey? publicKey = null PublicKey publicKey = null
) { ) {
var isAttestation = credentialId != null && publicKey.HasValue; var isAttestation = credentialId != null && publicKey != null;
List<byte> authData = new List<byte>(); List<byte> authData = new List<byte>();
@@ -363,7 +355,7 @@ namespace Bit.Core.Services
}; };
attestedCredentialData.AddRange(credentialIdLength); attestedCredentialData.AddRange(credentialIdLength);
attestedCredentialData.AddRange(credentialId); attestedCredentialData.AddRange(credentialId);
attestedCredentialData.AddRange(publicKey.Value.ToCose()); attestedCredentialData.AddRange(publicKey.ExportCose());
authData.AddRange(attestedCredentialData); authData.AddRange(attestedCredentialData);
} }
@@ -434,12 +426,23 @@ namespace Bit.Core.Services
return Guid.Parse(guid).ToByteArray(); return Guid.Parse(guid).ToByteArray();
} }
private struct PublicKey private class PublicKey
{ {
public byte[] X { get; set; } private readonly System.Security.Cryptography.ECDsa _dsa;
public byte[] Y { get; set; }
public byte[] ToCose() public PublicKey(System.Security.Cryptography.ECDsa dsa) {
_dsa = dsa;
}
public byte[] X => _dsa.ExportParameters(false).Q.X;
public byte[] Y => _dsa.ExportParameters(false).Q.Y;
public byte[] ExportDer()
{
return _dsa.ExportSubjectPublicKeyInfo();
}
public byte[] ExportCose()
{ {
var result = new CborWriter(CborConformanceMode.Ctap2Canonical); var result = new CborWriter(CborConformanceMode.Ctap2Canonical);
result.WriteStartMap(5); result.WriteStartMap(5);