1
0
mirror of https://github.com/bitwarden/mobile.git synced 2024-11-21 11:25:56 +01:00

fix wrong signature format

This commit is contained in:
Andreas Coroiu 2024-02-16 10:57:44 +01:00
parent 7381d5278a
commit a1c9ebf01f
No known key found for this signature in database
GPG Key ID: E70B5FFC81DFEC1A
2 changed files with 18 additions and 16 deletions

View File

@ -517,7 +517,7 @@ namespace Bit.Core.Services
throw new Exception("Failed to import private key"); throw new Exception("Failed to import private key");
} }
return dsa.SignData(sigBase, HashAlgorithmName.SHA256); return dsa.SignData(sigBase, HashAlgorithmName.SHA256, DSASignatureFormat.Rfc3279DerSequence);
} }
private string GuidToStandardFormat(byte[] bytes) private string GuidToStandardFormat(byte[] bytes)

View File

@ -22,6 +22,7 @@ namespace Bit.Core.Test.Services
{ {
private readonly string _rpId = "bitwarden.com"; private readonly string _rpId = "bitwarden.com";
private readonly SutProvider<Fido2AuthenticatorService> _sutProvider = new SutProvider<Fido2AuthenticatorService>().Create(); private readonly SutProvider<Fido2AuthenticatorService> _sutProvider = new SutProvider<Fido2AuthenticatorService>().Create();
private readonly IFido2UserInterface _userInterface = Substitute.For<IFido2UserInterface>();
private List<Guid> _credentialIds; private List<Guid> _credentialIds;
private List<CipherView> _ciphers; private List<CipherView> _ciphers;
@ -54,10 +55,11 @@ namespace Bit.Core.Test.Services
requireUserVerification: false requireUserVerification: false
); );
_sutProvider.GetDependency<ICipherService>().GetAllDecryptedAsync().Returns(_ciphers); _sutProvider.GetDependency<ICipherService>().GetAllDecryptedAsync().Returns(_ciphers);
_sutProvider.GetDependency<IFido2UserInterface>().PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult { _userInterface.PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult {
CipherId = _ciphers[0].Id, CipherId = _ciphers[0].Id,
UserVerified = false UserVerified = false
}); });
_sutProvider.Sut.Init(_userInterface);
} }
public void Dispose() public void Dispose()
@ -110,7 +112,7 @@ namespace Bit.Core.Test.Services
await _sutProvider.Sut.GetAssertionAsync(_params); await _sutProvider.Sut.GetAssertionAsync(_params);
// Assert // Assert
await _sutProvider.GetDependency<IFido2UserInterface>().Received().PickCredentialAsync(Arg.Is<Fido2PickCredentialParams>( await _userInterface.Received().PickCredentialAsync(Arg.Is<Fido2PickCredentialParams>(
(pickCredentialParams) => pickCredentialParams.CipherIds.SequenceEqual(_ciphers.Select((cipher) => cipher.Id)) (pickCredentialParams) => pickCredentialParams.CipherIds.SequenceEqual(_ciphers.Select((cipher) => cipher.Id))
)); ));
} }
@ -121,7 +123,7 @@ namespace Bit.Core.Test.Services
// Arrange // Arrange
_params.AllowCredentialDescriptorList = null; _params.AllowCredentialDescriptorList = null;
var discoverableCiphers = _ciphers.Where((cipher) => cipher.Login.MainFido2Credential.DiscoverableValue).ToList(); var discoverableCiphers = _ciphers.Where((cipher) => cipher.Login.MainFido2Credential.DiscoverableValue).ToList();
_sutProvider.GetDependency<IFido2UserInterface>().PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult { _userInterface.PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult {
CipherId = discoverableCiphers[0].Id, CipherId = discoverableCiphers[0].Id,
UserVerified = false UserVerified = false
}); });
@ -130,7 +132,7 @@ namespace Bit.Core.Test.Services
await _sutProvider.Sut.GetAssertionAsync(_params); await _sutProvider.Sut.GetAssertionAsync(_params);
// Assert // Assert
await _sutProvider.GetDependency<IFido2UserInterface>().Received().PickCredentialAsync(Arg.Is<Fido2PickCredentialParams>( await _userInterface.Received().PickCredentialAsync(Arg.Is<Fido2PickCredentialParams>(
(pickCredentialParams) => pickCredentialParams.CipherIds.SequenceEqual(discoverableCiphers.Select((cipher) => cipher.Id)) (pickCredentialParams) => pickCredentialParams.CipherIds.SequenceEqual(discoverableCiphers.Select((cipher) => cipher.Id))
)); ));
} }
@ -141,7 +143,7 @@ namespace Bit.Core.Test.Services
public async Task GetAssertionAsync_RequestsUserVerification_ParamsRequireUserVerification() { public async Task GetAssertionAsync_RequestsUserVerification_ParamsRequireUserVerification() {
// Arrange // Arrange
_params.RequireUserVerification = true; _params.RequireUserVerification = true;
_sutProvider.GetDependency<IFido2UserInterface>().PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult { _userInterface.PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult {
CipherId = _ciphers[0].Id, CipherId = _ciphers[0].Id,
UserVerified = true UserVerified = true
}); });
@ -150,7 +152,7 @@ namespace Bit.Core.Test.Services
await _sutProvider.Sut.GetAssertionAsync(_params); await _sutProvider.Sut.GetAssertionAsync(_params);
// Assert // Assert
await _sutProvider.GetDependency<IFido2UserInterface>().Received().PickCredentialAsync(Arg.Is<Fido2PickCredentialParams>( await _userInterface.Received().PickCredentialAsync(Arg.Is<Fido2PickCredentialParams>(
(pickCredentialParams) => pickCredentialParams.UserVerification == true (pickCredentialParams) => pickCredentialParams.UserVerification == true
)); ));
} }
@ -167,7 +169,7 @@ namespace Bit.Core.Test.Services
await _sutProvider.Sut.GetAssertionAsync(_params); await _sutProvider.Sut.GetAssertionAsync(_params);
// Assert // Assert
await _sutProvider.GetDependency<IFido2UserInterface>().Received().PickCredentialAsync(Arg.Is<Fido2PickCredentialParams>( await _userInterface.Received().PickCredentialAsync(Arg.Is<Fido2PickCredentialParams>(
(pickCredentialParams) => pickCredentialParams.UserVerification == false (pickCredentialParams) => pickCredentialParams.UserVerification == false
)); ));
} }
@ -176,7 +178,7 @@ namespace Bit.Core.Test.Services
// Spec: If the user does not consent, return an error code equivalent to "NotAllowedError" and terminate the operation. // Spec: If the user does not consent, return an error code equivalent to "NotAllowedError" and terminate the operation.
public async Task GetAssertionAsync_ThrowsNotAllowed_UserDoesNotConsent() { public async Task GetAssertionAsync_ThrowsNotAllowed_UserDoesNotConsent() {
// Arrange // Arrange
_sutProvider.GetDependency<IFido2UserInterface>().PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult { _userInterface.PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult {
CipherId = null, CipherId = null,
UserVerified = false UserVerified = false
}); });
@ -190,7 +192,7 @@ namespace Bit.Core.Test.Services
public async Task GetAssertionAsync_ThrowsNotAllowed_NoUserVerificationWhenRequired() { public async Task GetAssertionAsync_ThrowsNotAllowed_NoUserVerificationWhenRequired() {
// Arrange // Arrange
_params.RequireUserVerification = true; _params.RequireUserVerification = true;
_sutProvider.GetDependency<IFido2UserInterface>().PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult { _userInterface.PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult {
CipherId = _selectedCipher.Id, CipherId = _selectedCipher.Id,
UserVerified = false UserVerified = false
}); });
@ -205,7 +207,7 @@ namespace Bit.Core.Test.Services
// Arrange // Arrange
_selectedCipher.Reprompt = CipherRepromptType.Password; _selectedCipher.Reprompt = CipherRepromptType.Password;
_params.RequireUserVerification = false; _params.RequireUserVerification = false;
_sutProvider.GetDependency<IFido2UserInterface>().PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult { _userInterface.PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult {
CipherId = _selectedCipher.Id, CipherId = _selectedCipher.Id,
UserVerified = false UserVerified = false
}); });
@ -264,7 +266,7 @@ namespace Bit.Core.Test.Services
_selectedCipher.Login.MainFido2Credential.CounterValue = 9000; _selectedCipher.Login.MainFido2Credential.CounterValue = 9000;
_selectedCipher.Login.MainFido2Credential.KeyValue = CoreHelpers.Base64UrlEncode(keyPair.ExportPkcs8PrivateKey()); _selectedCipher.Login.MainFido2Credential.KeyValue = CoreHelpers.Base64UrlEncode(keyPair.ExportPkcs8PrivateKey());
_sutProvider.GetDependency<ICryptoFunctionService>().HashAsync(_params.RpId, CryptoHashAlgorithm.Sha256).Returns(rpIdHashMock); _sutProvider.GetDependency<ICryptoFunctionService>().HashAsync(_params.RpId, CryptoHashAlgorithm.Sha256).Returns(rpIdHashMock);
_sutProvider.GetDependency<IFido2UserInterface>().PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult { _userInterface.PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()).Returns(new Fido2PickCredentialResult {
CipherId = _selectedCipher.Id, CipherId = _selectedCipher.Id,
UserVerified = true UserVerified = true
}); });
@ -281,9 +283,9 @@ namespace Bit.Core.Test.Services
Assert.Equal(Guid.Parse(_selectedCipher.Login.MainFido2Credential.CredentialId).ToByteArray(), result.SelectedCredential.Id); Assert.Equal(Guid.Parse(_selectedCipher.Login.MainFido2Credential.CredentialId).ToByteArray(), result.SelectedCredential.Id);
Assert.Equal(CoreHelpers.Base64UrlDecode(_selectedCipher.Login.MainFido2Credential.UserHandle), result.SelectedCredential.UserHandle); Assert.Equal(CoreHelpers.Base64UrlDecode(_selectedCipher.Login.MainFido2Credential.UserHandle), result.SelectedCredential.UserHandle);
Assert.Equal(rpIdHashMock, rpIdHash); Assert.Equal(rpIdHashMock, rpIdHash);
Assert.Equal(new byte[] { 0b00000101 }, flags); // UP = true, UV = true Assert.Equal(new byte[] { 0b00011101 }, flags); // UP = true, UV = true, BS = true, BE = true
Assert.Equal(new byte[] { 0, 0, 0x23, 0x29 }, counter); // 9001 in binary big-endian format Assert.Equal(new byte[] { 0, 0, 0x23, 0x29 }, counter); // 9001 in binary big-endian format
Assert.True(keyPair.VerifyData(authData.Concat(_params.Hash).ToArray(), result.Signature, HashAlgorithmName.SHA256), "Signature verification failed"); Assert.True(keyPair.VerifyData(authData.Concat(_params.Hash).ToArray(), result.Signature, HashAlgorithmName.SHA256, DSASignatureFormat.Rfc3279DerSequence), "Signature verification failed");
} }
[Fact] [Fact]
@ -304,10 +306,10 @@ namespace Bit.Core.Test.Services
var result = await _sutProvider.Sut.GetAssertionAsync(_params); var result = await _sutProvider.Sut.GetAssertionAsync(_params);
// Assert // Assert
await _sutProvider.GetDependency<IFido2UserInterface>().DidNotReceive().PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>()); await _userInterface.DidNotReceive().PickCredentialAsync(Arg.Any<Fido2PickCredentialParams>());
var authData = result.AuthenticatorData; var authData = result.AuthenticatorData;
var flags = authData.Skip(32).Take(1); var flags = authData.Skip(32).Take(1);
Assert.Equal(new byte[] { 0b00000000 }, flags); // UP = false, UV = false Assert.Equal(new byte[] { 0b00011000 }, flags); // UP = false, UV = false, BE = true, BS = true
} }
[Fact] [Fact]