public RawAuthenticatorMakeCredentialOptions(AuthenticatorMakeCredentialOptions makeOptions)
        {
            ExcludeCredentialsList = new RawCredentialsList(makeOptions.ExcludeCredentials);

            if (makeOptions.ExcludeCredentialsEx?.Count > 0)
            {
                _excludeCredentialsExList = new RawCredentialExList(makeOptions.ExcludeCredentialsEx);
                ExcludeCredentialsExListPtr = Marshal.AllocHGlobal(Marshal.SizeOf<RawCredentialExList>());
                Marshal.StructureToPtr(_excludeCredentialsExList, ExcludeCredentialsExListPtr, false);
            }

            CancellationId = IntPtr.Zero;
            if (makeOptions.CancellationId.HasValue)
            {
                CancellationId = Marshal.AllocHGlobal(Marshal.SizeOf<Guid>());
                Marshal.StructureToPtr(makeOptions.CancellationId.Value, CancellationId, false);
            }

            TimeoutMilliseconds = makeOptions.TimeoutMilliseconds;
            AuthenticatorAttachment = makeOptions.AuthenticatorAttachment;
            UserVerificationRequirement = makeOptions.UserVerificationRequirement;
            AttestationConveyancePreference = makeOptions.AttestationConveyancePreference;
            RequireResidentKey = makeOptions.RequireResidentKey;

            Extensions = new RawWebauthnExtensions { Count = 0, Extensions = IntPtr.Zero }; //TODO
        }
Exemplo n.º 2
0
        public RawAuthenticatorGetAssertionOptions(AuthenticatorGetAssertionOptions getOptions)
        {
            AllowCredentialsList = new RawCredentialsList(getOptions.AllowedCredentials);

            if (getOptions.AllowedCredentialsEx?.Count > 0)
            {
                _allowedCredentialsExList = new RawCredentialExList(getOptions.AllowedCredentialsEx);
                AllowCredentialsExListPtr = Marshal.AllocHGlobal(Marshal.SizeOf <RawCredentialExList>());
                Marshal.StructureToPtr(_allowedCredentialsExList, AllowCredentialsExListPtr, false);
            }

            CancellationId = IntPtr.Zero;
            if (getOptions.CancellationId.HasValue)
            {
                CancellationId = Marshal.AllocHGlobal(Marshal.SizeOf <Guid>());
                Marshal.StructureToPtr(getOptions.CancellationId.Value, CancellationId, false);
            }

            U2fAppId            = getOptions.U2fAppId;
            U2fAppIdUsedBoolPtr = Marshal.AllocHGlobal(Marshal.SizeOf <bool>());

            TimeoutMilliseconds         = getOptions.TimeoutMilliseconds;
            AuthenticatorAttachment     = getOptions.AuthenticatorAttachment;
            UserVerificationRequirement = getOptions.UserVerificationRequirement;

            Extensions = new RawWebauthnExtensions {
                Count = 0, Extensions = IntPtr.Zero
            };                                                                              //TODO
        }
Exemplo n.º 3
0
        /// <summary>
        /// GetLoginAssertionsOptions method implementation
        /// </summary>
        private string GetLoginAssertionsOptions(AuthenticationContext ctx)
        {
            try
            {
                List <MFAPublicKeyCredentialDescriptor> existingCredentials = new List <MFAPublicKeyCredentialDescriptor>();

                if (!string.IsNullOrEmpty(ctx.UPN))
                {
                    var user = RuntimeRepository.GetUser(Config, ctx.UPN);
                    if (user == null)
                    {
                        throw new ArgumentException("Username was not registered");
                    }
                    existingCredentials = RuntimeRepository.GetCredentialsByUser(Config, user).Select(c => c.Descriptor).ToList();
                }

                AuthenticationExtensionsClientInputs exts = new AuthenticationExtensionsClientInputs()
                {
                    SimpleTransactionAuthorization  = "FIDO",
                    GenericTransactionAuthorization = new TxAuthGenericArg
                    {
                        ContentType = "text/plain",
                        Content     = new byte[] { 0x46, 0x49, 0x44, 0x4F }
                    },
                    UserVerificationIndex = this.UserVerificationIndex,
                    Location = this.Location,
                    UserVerificationMethod = this.UserVerificationMethod,
                    EnforceCredProtect     = this.EnforceCredProtect,
                    CredProtect            = this.CredProtect,
                    HmacSecret             = this.HmacSecret
                };

                UserVerificationRequirement uv      = this.UserVerificationRequirement.ToEnum <UserVerificationRequirement>();
                AssertionOptions            options = _webathn.GetAssertionOptions(existingCredentials.ToCore(), uv, exts);
                string result = options.ToJson();
                ctx.AssertionOptions = result;
                return(result);
            }
            catch (Exception e)
            {
                Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, e.Message), EventLogEntryType.Error, 5000);
                string result = (new AssertionOptions {
                    Status = "error", ErrorMessage = string.Format("{0}{1}", e.Message, e.InnerException != null ? " (" + e.InnerException.Message + ")" : "")
                }).ToJson();
                ctx.AssertionOptions = result;
                return(result);
            }
        }
        /// <summary>
        /// GetLoginAssertionsOptions method implementation
        /// </summary>
        private string GetLoginAssertionsOptions(AuthenticationContext ctx)
        {
            try
            {
                List <MFAPublicKeyCredentialDescriptor> existingCredentials = new List <MFAPublicKeyCredentialDescriptor>();
                if (!string.IsNullOrEmpty(ctx.UPN))
                {
                    var user = RuntimeRepository.GetUser(Config, ctx.UPN);
                    if (user == null)
                    {
                        throw new ArgumentException("Username was not registered");
                    }
                    existingCredentials = RuntimeRepository.GetCredentialsByUser(Config, user).Select(c => c.Descriptor).ToList();
                }

                AuthenticationExtensionsClientInputs exts = new AuthenticationExtensionsClientInputs()
                {
                    Extensions             = this.Extentions,
                    UserVerificationMethod = this.UserVerificationMethod,
                };

                UserVerificationRequirement uv      = this.UserVerificationRequirement;
                AssertionOptions            options = null;
                if (existingCredentials.Count > 0)
                {
                    options = _webathn.GetAssertionOptions(existingCredentials.ToCore(), uv, exts);
                }
                else
                {
                    options = _webathn.GetAssertionOptions(null, uv, exts);
                }

                string result = options.ToJson();
                ctx.AssertionOptions = result;
                return(result);
            }
            catch (Exception e)
            {
                Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, e.Message), EventLogEntryType.Error, 5000);
                string result = (new AssertionOptions {
                    Status = "error", ErrorMessage = string.Format("{0} / {1}", e.Message, e.InnerException != null ? " (" + e.InnerException.Message + ")" : "")
                }).ToJson();
                ctx.AssertionOptions = result;
                return(result);
            }
        }
Exemplo n.º 5
0
        public JsonResult MakeCredentialOptions([FromForm] string username, [FromForm] string attType, [FromForm] string authType, [FromForm] bool requireResidentKey, [FromForm] string userVerification)
        {
            try
            {
                // 1. Get user from DB by username (in our example, auto create missing users)
                var user = DemoStorage.GetOrAddUser(username, () => new User
                {
                    DisplayName = "Display " + username,
                    Name        = username,
                    Id          = Encoding.UTF8.GetBytes(username) // byte representation of userID is required
                });

                // 2. Get user existing keys by username
                List <PublicKeyCredentialDescriptor> existingKeys = DemoStorage.GetCredentialsByUser(user).Select(c => c.Descriptor).ToList();

                // 3. Create options
                var authenticatorSelection = new AuthenticatorSelection
                {
                    AuthenticatorAttachment = !string.IsNullOrEmpty(authType) ? AuthenticatorAttachment.Parse(authType) : null,
                    RequireResidentKey      = requireResidentKey,
                    UserVerification        = UserVerificationRequirement.Parse(userVerification)
                };
                var options = _lib.RequestNewCredential(user, existingKeys, authenticatorSelection, AttestationConveyancePreference.Parse(attType));

                // 4. Temporarily store options, session/in-memory cache/redis/db
                HttpContext.Session.SetString("fido2.attestationOptions", options.ToJson());

                // 5. return options to client
                return(Json(options));
            }
            catch (Exception e)
            {
                return(Json(new CredentialCreateOptions {
                    Status = "error", ErrorMessage = FormatException(e)
                }));
            }
        }
Exemplo n.º 6
0
 internal static AssertionOptions Create(Fido2.Configuration config, byte[] challenge, IEnumerable <PublicKeyCredentialDescriptor> allowedCredentials, UserVerificationRequirement userVerification, AuthenticationExtensionsClientInputs extensions)
 {
     return(new AssertionOptions()
     {
         Status = "ok",
         ErrorMessage = string.Empty,
         Challenge = challenge,
         Timeout = config.Timeout,
         RpId = config.ServerDomain,
         AllowCredentials = allowedCredentials ?? new List <PublicKeyCredentialDescriptor>(),
         UserVerification = userVerification,
         Extensions = extensions
     });
 }
Exemplo n.º 7
0
        /// <summary>
        /// Returns AssertionOptions including a challenge to the browser/authr to assert existing credentials and authenticate a user.
        /// </summary>
        /// <returns></returns>
        public AssertionOptions GetAssertionOptions(IEnumerable <PublicKeyCredentialDescriptor> allowedCredentials, UserVerificationRequirement userVerification)
        {
            var challenge = new byte[Config.ChallengeSize];

            _crypto.GetBytes(challenge);

            var options = AssertionOptions.Create(Config, challenge, allowedCredentials, userVerification);

            return(options);
        }
Exemplo n.º 8
0
 public AuthenticatorSelection()
 {
     requireResidentKey      = false;
     authenticatorAttachment = "";
     userVerification        = UserVerificationRequirement.preferred;
 }
        /// <summary>
        /// GetRegisterCredentialOptions method implementation
        /// </summary>
        private string GetRegisterCredentialOptions(AuthenticationContext ctx)
        {
            try
            {
                if (string.IsNullOrEmpty(ctx.UPN))
                {
                    throw new ArgumentNullException(ctx.UPN);
                }
                string attType  = this.ConveyancePreference;                                      // none, direct, indirect
                string authType = this.Attachement;                                               // <empty>, platform, cross-platform
                UserVerificationRequirement userVerification = this.UserVerificationRequirement;  // preferred, required, discouraged
                bool requireResidentKey = this.RequireResidentKey;                                // true,false

                MFAWebAuthNUser user = RuntimeRepository.GetUser(Config, ctx.UPN);
                if (user != null)
                {
                    List <MFAPublicKeyCredentialDescriptor> existingKeys = RuntimeRepository.GetCredentialsByUser(Config, user).Select(c => c.Descriptor).ToList();

                    // 3. Create options
                    AuthenticatorSelection authenticatorSelection = new AuthenticatorSelection
                    {
                        RequireResidentKey = requireResidentKey,
                        UserVerification   = userVerification
                    };
                    if (!string.IsNullOrEmpty(authType))
                    {
                        authenticatorSelection.AuthenticatorAttachment = authType.ToEnum <AuthenticatorAttachment>();
                    }

                    AuthenticationExtensionsClientInputs exts = new AuthenticationExtensionsClientInputs()
                    {
                        Extensions             = this.Extentions,
                        UserVerificationMethod = this.UserVerificationMethod
                    };
                    CredentialCreateOptions options = null;

                    if (existingKeys.Count > 0)
                    {
                        options = _webathn.GetRegisterCredentialOptions(user.ToCore(), existingKeys.ToCore(), authenticatorSelection, attType.ToEnum <AttestationConveyancePreference>(), exts);
                    }
                    else
                    {
                        options = _webathn.GetRegisterCredentialOptions(user.ToCore(), null, authenticatorSelection, attType.ToEnum <AttestationConveyancePreference>(), exts);
                    }
                    string result = options.ToJson();
                    ctx.CredentialOptions = result;
                    return(result);
                }
                else
                {
                    Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, "User does not exists !"), EventLogEntryType.Error, 5000);
                    string result = (new CredentialMakeResult {
                        Status = "error", ErrorMessage = string.Format("{0}", "User does not exists !")
                    }).ToJson();
                    ctx.CredentialOptions = result;
                    return(result);
                }
            }
            catch (Exception e)
            {
                Log.WriteEntry(string.Format("{0}\r\n{1}", ctx.UPN, e.Message), System.Diagnostics.EventLogEntryType.Error, 5000);
                string result = (new CredentialMakeResult {
                    Status = "error", ErrorMessage = string.Format("{0}{1}", e.Message, e.InnerException != null ? " (" + e.InnerException.Message + ")" : "")
                }).ToJson();
                ctx.CredentialOptions = result;
                return(result);
            }
        }
        public static PublicKeyCredentialCreationOptions ConvertToPublicKeyCredentialCreationOptions(IFido2Client fido2Client,
                                                                                                     ServerPublicKeyCredentialCreationOptionsResponse response)
        {
            PublicKeyCredentialCreationOptions.Builder builder = new PublicKeyCredentialCreationOptions.Builder();

            string name = response.Rp.Name;
            PublicKeyCredentialRpEntity entity = new PublicKeyCredentialRpEntity(name, name, null);

            builder.SetRp(entity);

            string id = response.User.Id;

            try
            {
                builder.SetUser(new PublicKeyCredentialUserEntity(id, System.Text.Encoding.UTF8.GetBytes(id)));
            }
            catch (UnsupportedEncodingException e)
            {
                Log.Error(Tag, e.Message, e);
            }

            builder.SetChallenge(ByteUtils.Base64ToByte(response.Challenge));

            if (response.PubKeyCredParams != null)
            {
                List <PublicKeyCredentialParameters>  parameters = new List <PublicKeyCredentialParameters>();
                ServerPublicKeyCredentialParameters[] serverPublicKeyCredentialParameters = response.PubKeyCredParams;
                foreach (ServerPublicKeyCredentialParameters param in serverPublicKeyCredentialParameters)
                {
                    try
                    {
                        PublicKeyCredentialParameters parameter = new PublicKeyCredentialParameters(
                            PublicKeyCredentialType.PublicKey, Algorithm.FromCode(param.Alg));
                        parameters.Add(parameter);
                    }
                    catch (System.Exception e)
                    {
                        Log.Error(Tag, e.Message, e);
                    }
                }
                builder.SetPubKeyCredParams(parameters);
            }

            if (response.ExcludeCredentials != null)
            {
                List <PublicKeyCredentialDescriptor>  descriptors       = new List <PublicKeyCredentialDescriptor>();
                ServerPublicKeyCredentialDescriptor[] serverDescriptors = response.ExcludeCredentials;
                foreach (ServerPublicKeyCredentialDescriptor desc in serverDescriptors)
                {
                    List <AuthenticatorTransport> transports = new List <AuthenticatorTransport>();
                    if (desc.Transports != null)
                    {
                        try
                        {
                            transports.Add(AuthenticatorTransport.FromValue(desc.Transports));
                        }
                        catch (System.Exception e)
                        {
                            Log.Error(Tag, e.Message, e);
                        }
                    }
                    PublicKeyCredentialDescriptor descriptor = new PublicKeyCredentialDescriptor(
                        PublicKeyCredentialType.PublicKey, ByteUtils.Base64ToByte(desc.Id), transports);
                    descriptors.Add(descriptor);
                }
                builder.SetExcludeList(descriptors);
            }

            Attachment attachment = null;

            if (response.AuthenticatorSelection != null)
            {
                ServerAuthenticatorSelectionCriteria selectionCriteria = response.AuthenticatorSelection;
                if (selectionCriteria.AuthenticatorAttachment != null)
                {
                    try
                    {
                        attachment = Attachment.FromValue(selectionCriteria.AuthenticatorAttachment);
                    }
                    catch (System.Exception e)
                    {
                        Log.Error(Tag, e.Message, e);
                    }
                }

                bool residentKey = selectionCriteria.IsRequireResidentKey;

                UserVerificationRequirement requirement = null;
                if (selectionCriteria.UserVerification != null)
                {
                    try
                    {
                        requirement = UserVerificationRequirement.FromValue(selectionCriteria.UserVerification);
                    }
                    catch (System.Exception e)
                    {
                        Log.Error(Tag, e.Message, e);
                    }
                }

                AuthenticatorSelectionCriteria fido2Selection =
                    new AuthenticatorSelectionCriteria(attachment, (Java.Lang.Boolean)residentKey, requirement);
                builder.SetAuthenticatorSelection(fido2Selection);
            }

            // attestation
            if (response.Attestation != null)
            {
                try
                {
                    AttestationConveyancePreference preference =
                        AttestationConveyancePreference.FromValue(response.Attestation);
                    builder.SetAttestation(preference);
                }
                catch (System.Exception e)
                {
                    Log.Error(Tag, e.Message, e);
                }
            }

            Dictionary <string, Java.Lang.Object> extensions = new Dictionary <string, Java.Lang.Object>();

            if (response.Extensions != null)
            {
                extensions.AddRangeOverride(response.Extensions);
            }

            // Specify a platform authenticator and related extension items. You can specify a platform
            // authenticator or not as needed.
            if (Attachment.Platform.Equals(attachment))
            {
                UseSelectedPlatformAuthenticator(fido2Client, extensions);
            }
            builder.SetExtensions(extensions);
            builder.SetTimeoutSeconds((Java.Lang.Long)response.Timeout);
            return(builder.Build());
        }