public void StartedRegistration_Equals() { StartedRegistration startedRegistration = StartedRegistration.FromJson<StartedRegistration>(JsonData); StartedRegistration sameStartedRegistration = new StartedRegistration(TestConts.SERVER_CHALLENGE_REGISTER_BASE64, TestConts.APP_ID_ENROLL); Assert.IsTrue(startedRegistration.Equals(sameStartedRegistration)); }
public bool CompleteRegistration(string userName, string deviceResponse) { if (string.IsNullOrWhiteSpace(deviceResponse)) return false; var user = _userRepository.FindUser(userName); if (user == null || user.AuthenticationRequest == null || user.AuthenticationRequest.Count == 0) return false; RegisterResponse registerResponse = RegisterResponse.FromJson<RegisterResponse>(deviceResponse); // When the user is registration they should only ever have one auth request. AuthenticationRequest authenticationRequest = user.AuthenticationRequest.First(); StartedRegistration startedRegistration = new StartedRegistration(authenticationRequest.Challenge, authenticationRequest.AppId); DeviceRegistration registration = U2F.FinishRegistration(startedRegistration, registerResponse); _userRepository.RemoveUsersAuthenticationRequests(userName); _userRepository.AddDeviceRegistration(userName, registration.AttestationCert, registration.Counter, registration.KeyHandle, registration.PublicKey); return true; }
public void AsTest() { var manager = A.Dummy<IRegistrationFinisher>(); var registration = new StartedRegistration(manager, typeof(TestType)); registration.As<ITestType1>(); A.CallTo(() => manager.FinishRegistration(typeof(ITestType1), registration)).MustHaveHappened(Repeated.Exactly.Once); }
/** * Finishes a previously started registration. * * @param startedAuthentication * @param tokenResponse the response from the token/client. * @return a DeviceRegistration object, holding information about the registered device. Servers should * persist this. */ public static DeviceRegistration FinishRegistration(StartedRegistration startedRegistration, RegisterResponse tokenResponse, HashSet<String> facets = null) { ClientData clientData = tokenResponse.GetClientData(); clientData.CheckContent(RegisterType, startedRegistration.Challenge, facets); RawRegisterResponse rawRegisterResponse = RawRegisterResponse.FromBase64(tokenResponse.RegistrationData); rawRegisterResponse.CheckSignature(startedRegistration.AppId, clientData.AsJson()); return rawRegisterResponse.CreateDevice(); }
public void U2F_FinishRegistrationNoFacets() { StartedRegistration startedRegistration = new StartedRegistration(TestConts.SERVER_CHALLENGE_REGISTER_BASE64, TestConts.APP_ID_ENROLL); RegisterResponse registerResponse = new RegisterResponse(TestConts.REGISTRATION_RESPONSE_DATA_BASE64, TestConts.CLIENT_DATA_REGISTER_BASE64); var results = U2F.FinishRegistration(startedRegistration, registerResponse); Assert.IsNotNull(results); Assert.IsNotNull(results.KeyHandle); Assert.IsNotNull(results.PublicKey); Assert.IsNotNull(results.GetAttestationCertificate()); }
public void StartedRegistration_ConstructsProperly() { StartedRegistration startedRegistration = new StartedRegistration(TestConts.SERVER_CHALLENGE_REGISTER_BASE64, TestConts.APP_ID_ENROLL); Assert.IsNotNull(startedRegistration); Assert.IsNotNull(startedRegistration.Version); Assert.IsNotNull(startedRegistration.Challenge); Assert.IsNotNull(startedRegistration.AppId); Assert.IsNotNull(startedRegistration.ToJson()); Assert.IsTrue(startedRegistration.GetHashCode() != 0); Assert.AreEqual(TestConts.SERVER_CHALLENGE_REGISTER_BASE64, startedRegistration.Challenge); Assert.AreEqual(TestConts.APP_ID_ENROLL, startedRegistration.AppId); }
public async Task <bool> CompleteRegistration(string userId, string deviceResponse, string name) { if (string.IsNullOrWhiteSpace(deviceResponse)) { return(false); } if (!UserAuthenticationRequests.ContainsKey(userId) || !UserAuthenticationRequests[userId].Any()) { return(false); } var registerResponse = RegisterResponse.FromJson <RegisterResponse>(deviceResponse); //There is only 1 request when registering device var authenticationRequest = UserAuthenticationRequests[userId].First(); var startedRegistration = new StartedRegistration(authenticationRequest.Challenge, authenticationRequest.AppId); var registration = global::U2F.Core.Crypto.U2F.FinishRegistration(startedRegistration, registerResponse); UserAuthenticationRequests.AddOrReplace(userId, new List <U2FDeviceAuthenticationRequest>()); using (var context = _contextFactory.CreateContext()) { var duplicate = context.U2FDevices.Any(device => device.ApplicationUserId.Equals(userId, StringComparison.InvariantCulture) && device.KeyHandle.Equals(registration.KeyHandle) && device.PublicKey.Equals(registration.PublicKey)); if (duplicate) { throw new InvalidOperationException("The U2F Device has already been registered with this user"); } await context.U2FDevices.AddAsync(new U2FDevice() { AttestationCert = registration.AttestationCert, Counter = Convert.ToInt32(registration.Counter), Name = name, KeyHandle = registration.KeyHandle, PublicKey = registration.PublicKey, ApplicationUserId = userId }); await context.SaveChangesAsync(); } return(true); }
private void CreateResponses() { _startedRegistration = new StartedRegistration(TestConts.SERVER_CHALLENGE_REGISTER_BASE64, TestConts.APP_ID_ENROLL); _registerResponse = new RegisterResponse(TestConts.REGISTRATION_RESPONSE_DATA_BASE64, TestConts.CLIENT_DATA_REGISTER_BASE64); _rawAuthenticateResponse = RawRegisterResponse.FromBase64(_registerResponse.RegistrationData); _deviceRegistration = _rawAuthenticateResponse.CreateDevice(); _authenticateResponse = new AuthenticateResponse(TestConts.CLIENT_DATA_AUTHENTICATE_BASE64, TestConts.SIGN_RESPONSE_DATA_BASE64, TestConts.KEY_HANDLE_BASE64); _startedAuthentication = new StartedAuthentication(TestConts.SERVER_CHALLENGE_SIGN_BASE64, TestConts.APP_ID_ENROLL, TestConts.KEY_HANDLE_BASE64); }
public void U2F_FinishRegistrationNoFacets(ICryptoService crypto) { Crypto.U2F.Crypto = crypto; StartedRegistration startedRegistration = new StartedRegistration(TestConstants.SERVER_CHALLENGE_REGISTER_BASE64, TestConstants.APP_ID_ENROLL); RegisterResponse registerResponse = new RegisterResponse(TestConstants.REGISTRATION_RESPONSE_DATA_BASE64, TestConstants.CLIENT_DATA_REGISTER_BASE64); var results = U2F.Core.Crypto.U2F.FinishRegistration(startedRegistration, registerResponse); Assert.NotNull(results); Assert.NotNull(results.KeyHandle); Assert.NotNull(results.PublicKey); Assert.NotNull(results.GetAttestationCertificate()); }
public ServerRegisterResponse GenerateServerChallenge(string username) { if (string.IsNullOrWhiteSpace(username)) { return(null); } StartedRegistration startedRegistration = U2F.StartRegistration(DemoAppId); _userRepository.SaveUserAuthenticationRequest(username, startedRegistration.AppId, startedRegistration.Challenge, startedRegistration.Version); return(new ServerRegisterResponse { AppId = startedRegistration.AppId, Challenge = startedRegistration.Challenge, Version = startedRegistration.Version }); }
public async Task <bool> CompleteRegistration(string userName, string deviceResponse) { if (string.IsNullOrWhiteSpace(deviceResponse)) { return(false); } User user = await FindUserByUsername(userName); if (user?.AuthenticationRequest == null || user.AuthenticationRequest.Count == 0) { return(false); } RegisterResponse registerResponse = RegisterResponse.FromJson <RegisterResponse>(deviceResponse); // TODO When the user is registration they should only ever have one auth request.???? AuthenticationRequest authenticationRequest = user.AuthenticationRequest.First(); StartedRegistration startedRegistration = new StartedRegistration(authenticationRequest.Challenge, authenticationRequest.AppId); DeviceRegistration registration = Core.Crypto.U2F.FinishRegistration(startedRegistration, registerResponse); user.AuthenticationRequest.Clear(); user.UpdatedOn = DateTime.Now; user.DeviceRegistrations.Add(new Device { AttestationCert = registration.AttestationCert, Counter = Convert.ToInt32(registration.Counter), CreatedOn = DateTime.Now, UpdatedOn = DateTime.Now, KeyHandle = registration.KeyHandle, PublicKey = registration.PublicKey }); int result = await _dataContext.SaveChangesAsync(); if (result > 0) { await _signInManager.SignInAsync(user, new AuthenticationProperties(), "U2F"); } return(result > 0); }
public ServerRegisterResponse GenerateServerRegistration(string userName, string password) { if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(password)) { return(null); } StartedRegistration startedRegistration = U2F.StartRegistration(DemoAppId); string hashedPassword = HashPassword(password); _userRepository.AddUser(userName, hashedPassword); _userRepository.AddAuthenticationRequest(userName, startedRegistration.AppId, startedRegistration.Challenge, startedRegistration.Version); return(new ServerRegisterResponse { AppId = startedRegistration.AppId, Challenge = startedRegistration.Challenge, Version = startedRegistration.Version }); }
public async Task <ServerRegisterResponse> GenerateServerChallenge(string username) { User user = await FindUserByUsername(username); if (user == null) { return(null); } StartedRegistration startedRegistration = Core.Crypto.U2F.StartRegistration(DemoAppId); if (user.AuthenticationRequest == null) { user.AuthenticationRequest = new List <AuthenticationRequest>(); } if (user.DeviceRegistrations == null) { user.DeviceRegistrations = new List <Device>(); } user.AuthenticationRequest.Add( new AuthenticationRequest { AppId = startedRegistration.AppId, Challenge = startedRegistration.Challenge, Version = Core.Crypto.U2F.U2FVersion }); user.UpdatedOn = DateTime.Now; await _dataContext.SaveChangesAsync(); return(new ServerRegisterResponse { AppId = startedRegistration.AppId, Challenge = startedRegistration.Challenge, Version = startedRegistration.Version }); }
private void CreateResponses() { _startedRegistration = new StartedRegistration(TestConts.SERVER_CHALLENGE_REGISTER_BASE64, TestConts.APP_ID_ENROLL); _registerResponse = new RegisterResponse(TestConts.REGISTRATION_RESPONSE_DATA_BASE64, TestConts.CLIENT_DATA_REGISTER_BASE64); _deviceRegistration = new DeviceRegistration( TestConts.KEY_HANDLE_BASE64_BYTE, TestConts.USER_PUBLIC_KEY_AUTHENTICATE_HEX, Utils.Base64StringToByteArray(TestConts.ATTESTATION_CERTIFICATE), 0); _authenticateResponse = new AuthenticateResponse( TestConts.CLIENT_DATA_AUTHENTICATE_BASE64, TestConts.SIGN_RESPONSE_DATA_BASE64, TestConts.KEY_HANDLE_BASE64); _startedAuthentication = new StartedAuthentication( TestConts.SERVER_CHALLENGE_SIGN_BASE64, TestConts.APP_SIGN_ID, TestConts.KEY_HANDLE_BASE64); }
public bool CompleteRegistration(string userName, string deviceResponse) { if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(deviceResponse)) { return(false); } RegisterResponse registerResponse = RegisterResponse.FromJson(deviceResponse); var user = _userRepository.FindUser(userName); if (user == null || user.AuthenticationRequest == null) { return(false); } StartedRegistration startedRegistration = new StartedRegistration(user.AuthenticationRequest.Challenge, user.AuthenticationRequest.AppId); DeviceRegistration registration = U2F.FinishRegistration(startedRegistration, registerResponse); _userRepository.RemoveUsersAuthenticationRequest(userName); _userRepository.AddDeviceRegistration(userName, registration.AttestationCert, registration.Counter, registration.KeyHandle, registration.PublicKey); return(true); }
public async Task <bool> FinishU2FRegistration(string userName, string deviceResponse, string deviceName, StartedRegistration startedRegistration) { if (string.IsNullOrWhiteSpace(deviceResponse)) { return(false); } var user = await dataContext.Users.FirstOrDefaultAsync(u => u.NormalizedUserName.Equals(userName)); if (user?.AuthenticationRequest?.Any() != true) { return(false); } if (string.IsNullOrWhiteSpace(deviceName)) { deviceName = Guid.NewGuid().ToString(); } var registerResponse = BaseModel.FromJson <RegisterResponse>(deviceResponse); var registration = U2F.Core.Crypto.U2F.FinishRegistration(startedRegistration, registerResponse); user.AuthenticationRequest.ToList().ForEach(a => dataContext.Remove(a)); user.DeviceRegistrations.Add(new Device { AttestationCert = registration.AttestationCert, Counter = Convert.ToInt32(registration.Counter), CreatedOn = DateTime.Now, UpdatedOn = DateTime.Now, KeyHandle = registration.KeyHandle, PublicKey = registration.PublicKey, DeviceName = deviceName }); var result = await dataContext.SaveChangesAsync(); await userManager.SetTwoFactorEnabledAsync(user, true); return(result > 0); }
protected virtual DeviceRegistration FinishRegistrationCore(StartedRegistration startedRegistration, RegisterResponse registerResponse) { return(global::U2F.Core.bitcoin.U2F.FinishRegistration(startedRegistration, registerResponse)); }
public async Task <bool> CompleteU2fRegistrationAsync(User user, int id, string name, string deviceResponse) { if (string.IsNullOrWhiteSpace(deviceResponse)) { return(false); } var challenges = await _u2fRepository.GetManyByUserIdAsync(user.Id); if (!challenges?.Any() ?? true) { return(false); } var registerResponse = BaseModel.FromJson <RegisterResponse>(deviceResponse); try { var challenge = challenges.OrderBy(i => i.Id).Last(i => i.KeyHandle == null); var startedReg = new StartedRegistration(challenge.Challenge, challenge.AppId); var reg = U2fLib.FinishRegistration(startedReg, registerResponse); await _u2fRepository.DeleteManyByUserIdAsync(user.Id); // Add device var providers = user.GetTwoFactorProviders(); if (providers == null) { providers = new Dictionary <TwoFactorProviderType, TwoFactorProvider>(); } var provider = user.GetTwoFactorProvider(TwoFactorProviderType.U2f); if (provider == null) { provider = new TwoFactorProvider(); } if (provider.MetaData == null) { provider.MetaData = new Dictionary <string, object>(); } if (provider.MetaData.Count >= 5) { // Can only register up to 5 keys return(false); } var keyId = $"Key{id}"; if (provider.MetaData.ContainsKey(keyId)) { provider.MetaData.Remove(keyId); } provider.Enabled = true; provider.MetaData.Add(keyId, new TwoFactorProvider.U2fMetaData { Name = name, KeyHandle = reg.KeyHandle == null ? null : Utils.ByteArrayToBase64String(reg.KeyHandle), PublicKey = reg.PublicKey == null ? null : Utils.ByteArrayToBase64String(reg.PublicKey), Certificate = reg.AttestationCert == null ? null : Utils.ByteArrayToBase64String(reg.AttestationCert), Compromised = false, Counter = reg.Counter }); if (providers.ContainsKey(TwoFactorProviderType.U2f)) { providers.Remove(TwoFactorProviderType.U2f); } providers.Add(TwoFactorProviderType.U2f, provider); user.SetTwoFactorProviders(providers); await UpdateTwoFactorProviderAsync(user, TwoFactorProviderType.U2f); return(true); } catch (U2fException e) { Logger.LogError(e, "Complete U2F registration error."); return(false); } }
public StartedRegistration StartRegistration(Type source) { var registration = new StartedRegistration(this, source); _startedRegistrations.Add(registration); return registration; }
/// <summary> /// Try register on all present tokens in parallel, return the first valid response /// </summary> public static Task <RegisterResponse> RegisterParallel(StartedRegistration regStart, CancellationToken cancellationToken, string facet = null) => RunParallel((tk, ct) => tk.RegisterAsync(regStart, facet, ct), cancellationToken);
public static async Task <RegisterResponse> RegisterAsync(U2FHidDevice u2fHidDevice, StartedRegistration request, string facet) { ValidateRequest(request, facet); var appParam = GetApplicationParameter(request.AppId); var clientData = GetRegistrationClientData(request.Challenge, facet); var challengeParam = GetChallengeParameter(clientData); var data = challengeParam.Concat(appParam).ToArray(); var p1 = (byte)0x03; var p2 = (byte)0x00; var response = await u2fHidDevice.SendApduAsync(Constants.INS_ENROLL, p1, p2, data); var registrationDataBase64 = Utils.ByteArrayToBase64String(response); var clientDataBase64 = Utils.ByteArrayToBase64String(Encoding.ASCII.GetBytes(clientData)); var registerResponse = new RegisterResponse(registrationDataBase64, clientDataBase64); return(registerResponse); }
protected override DeviceRegistration FinishRegistrationCore(StartedRegistration startedRegistration, RegisterResponse registerResponse) { return(GetDevReg()); }