/// <summary> /// SetRegisterCredentialResult method implementation /// </summary> private int SetRegisterCredentialResult(AuthenticationContext ctx, string jsonResponse) { try { string jsonOptions = ctx.CredentialOptions; if (string.IsNullOrEmpty(jsonOptions)) { throw new ArgumentNullException(jsonOptions); } if (string.IsNullOrEmpty(jsonResponse)) { throw new ArgumentNullException(jsonResponse); } MFAWebAuthNUser user = RuntimeRepository.GetUser(Config, ctx.UPN); if (user != null) { RegisterCredentialOptions options = RegisterCredentialOptions.FromJson(jsonOptions); bool callback(IsCredentialIdUniqueToUserParams args) { var users = RuntimeRepository.GetUsersByCredentialId(Config, user, args.CredentialId); if (users.Count > 0) { return(false); } return(true); } AuthenticatorAttestationRawResponse attestationResponse = JsonConvert.DeserializeObject <AuthenticatorAttestationRawResponse>(jsonResponse); RegisterCredentialResult success = _webathn.SetRegisterCredentialResult(attestationResponse, options, callback); RuntimeRepository.AddUserCredential(Config, options.User.FromCore(), new MFAUserCredential { Descriptor = new MFAPublicKeyCredentialDescriptor(success.Result.CredentialId), PublicKey = success.Result.PublicKey, UserHandle = success.Result.User.Id, SignatureCounter = success.Result.Counter, CredType = success.Result.CredType, RegDate = DateTime.Now, AaGuid = success.Result.Aaguid }); return((int)AuthenticationResponseKind.Biometrics); } else { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"), System.Diagnostics.EventLogEntryType.Error, 5000); return((int)AuthenticationResponseKind.Error); } } catch (Exception e) { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, e.Message), System.Diagnostics.EventLogEntryType.Error, 5000); return((int)AuthenticationResponseKind.Error); } }
/// <summary> /// Verifies the response from the browser/authr after creating new credentials /// </summary> /// <param name="attestationResponse"></param> /// <param name="origChallenge"></param> /// <returns></returns> public RegisterCredentialResult SetRegisterCredentialResult(AuthenticatorAttestationRawResponse attestationResponse, RegisterCredentialOptions origChallenge, IsCredentialIdUniqueToUserDelegate isCredentialIdUniqueToUser, byte[] requestTokenBindingId = null) { var parsedResponse = AuthenticatorAttestationResponse.Parse(attestationResponse); var success = parsedResponse.VerifyCredentialCreateOptions(origChallenge, _config, isCredentialIdUniqueToUser, _metadataService, requestTokenBindingId); // todo: Set Errormessage etc. return(new RegisterCredentialResult { Status = "ok", ErrorMessage = string.Empty, Result = success }); }
public static AuthenticatorAttestationResponse Parse(AuthenticatorAttestationRawResponse rawResponse) { if (null == rawResponse || null == rawResponse.Response) { throw new VerificationException("Expected rawResponse, got null"); } if (null == rawResponse.Response.AttestationObject || 0 == rawResponse.Response.AttestationObject.Length) { throw new VerificationException("Missing AttestationObject"); } // 8. Perform CBOR decoding on the attestationObject field of the AuthenticatorAttestationResponse structure to obtain the attestation statement format fmt, the authenticator data authData, and the attestation statement attStmt. CBORObject cborAttestation; try { cborAttestation = CBORObject.DecodeFromBytes(rawResponse.Response.AttestationObject); } catch (CBORException ex) { throw new VerificationException("AttestationObject invalid CBOR", ex); } if (null == cborAttestation["fmt"] || CBORType.TextString != cborAttestation["fmt"].Type || null == cborAttestation["attStmt"] || CBORType.Map != cborAttestation["attStmt"].Type || null == cborAttestation["authData"] || CBORType.ByteString != cborAttestation["authData"].Type) { throw new VerificationException("Malformed AttestationObject"); } var response = new AuthenticatorAttestationResponse(rawResponse.Response.ClientDataJson) { Raw = rawResponse, AttestationObject = new ParsedAttestationObject() { Fmt = cborAttestation["fmt"].AsString(), AttStmt = cborAttestation["attStmt"], // convert to dictionary? AuthData = cborAttestation["authData"].GetByteString() } }; return(response); }
public static AuthenticatorAttestationResponse Parse(AuthenticatorAttestationRawResponse rawResponse) { if (null == rawResponse || null == rawResponse.Response) { throw new VerificationException("Expected rawResponse, got null"); } if (null == rawResponse.Response.AttestationObject || 0 == rawResponse.Response.AttestationObject.Length) { throw new VerificationException("Missing AttestationObject"); } CBORObject cborAttestation; try { cborAttestation = CBORObject.DecodeFromBytes(rawResponse.Response.AttestationObject); } catch (CBORException ex) { throw new VerificationException("Malformed AttestationObject", ex); } if (null == cborAttestation["fmt"] || CBORType.TextString != cborAttestation["fmt"].Type || null == cborAttestation["attStmt"] || CBORType.Map != cborAttestation["attStmt"].Type || null == cborAttestation["authData"] || CBORType.ByteString != cborAttestation["authData"].Type) { throw new VerificationException("Malformed AttestationObject"); } var response = new AuthenticatorAttestationResponse(rawResponse.Response.ClientDataJson) { Raw = rawResponse, AttestationObject = new ParsedAttestationObject() { Fmt = cborAttestation["fmt"].AsString(), AttStmt = cborAttestation["attStmt"], // convert to dictionary? AuthData = cborAttestation["authData"].GetByteString() } }; return(response); }
/// <summary> /// Verifies the response from the browser/authr after creating new credentials (MakeNewCredentialAsync) /// </summary> /// <param name="attestationResponse"></param> /// <param name="origChallenge"></param> /// <returns></returns> public async Task <CredentialMakeResult> SetRegisterCredentialResult(AuthenticatorAttestationRawResponse attestationResponse, CredentialCreateOptions origChallenge, IsCredentialIdUniqueToUserAsyncDelegate isCredentialIdUniqueToUser, byte[] requestTokenBindingId = null) { var parsedResponse = AuthenticatorAttestationResponse.Parse(attestationResponse); var success = await parsedResponse.VerifyAsync(origChallenge, _config, isCredentialIdUniqueToUser, _metadataService, requestTokenBindingId); try { return(new CredentialMakeResult { Status = "ok", ErrorMessage = string.Empty, Result = success }); } catch (Exception e) { return(new CredentialMakeResult { Status = "error", ErrorMessage = e.Message, Result = success }); } }
/// <summary> /// SetRegisterCredentialResult method implementation /// </summary> private int SetRegisterCredentialResult(AuthenticationContext ctx, string jsonResponse, out string error) { bool isDeserialized = false; try { string jsonOptions = ctx.CredentialOptions; if (string.IsNullOrEmpty(jsonOptions)) { throw new ArgumentNullException(jsonOptions); } if (string.IsNullOrEmpty(jsonResponse)) { throw new ArgumentNullException(jsonResponse); } MFAWebAuthNUser user = RuntimeRepository.GetUser(Config, ctx.UPN); if (user != null) { CredentialCreateOptions options = CredentialCreateOptions.FromJson(jsonOptions); #pragma warning disable CS1998 // Cette méthode async n'a pas d'opérateur 'await' et elle s'exécutera de façon synchrone IsCredentialIdUniqueToUserAsyncDelegate callback = async(args) => #pragma warning restore CS1998 // Cette méthode async n'a pas d'opérateur 'await' et elle s'exécutera de façon synchrone { var users = RuntimeRepository.GetUsersByCredentialId(Config, user, args.CredentialId); if (users.Count > 0) { return(false); } return(true); }; AuthenticatorAttestationRawResponse attestationResponse = JsonConvert.DeserializeObject <AuthenticatorAttestationRawResponse>(jsonResponse); isDeserialized = true; CredentialMakeResult success = _webathn.SetRegisterCredentialResult(attestationResponse, options, callback).Result; RuntimeRepository.AddUserCredential(Config, user, new MFAUserCredential { Descriptor = new MFAPublicKeyCredentialDescriptor(success.Result.CredentialId), PublicKey = success.Result.PublicKey, UserHandle = success.Result.User.Id, SignatureCounter = success.Result.Counter, CredType = success.Result.CredType, RegDate = DateTime.Now, AaGuid = success.Result.Aaguid, NickName = ctx.NickName }); error = string.Empty; return((int)AuthenticationResponseKind.Biometrics); } else { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"), System.Diagnostics.EventLogEntryType.Error, 5000); error = string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"); return((int)AuthenticationResponseKind.Error); } } catch (Exception e) { if (isDeserialized) { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, e.Message), EventLogEntryType.Error, 5000); } else { Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, jsonResponse), EventLogEntryType.Error, 5000); } error = e.Message; return((int)AuthenticationResponseKind.Error); } }