/// <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);
            }
        }
Esempio n. 2
0
        /// <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);
            }
        }