using Esiur.Core;
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
namespace Esiur.Security.Authority.Providers
{
public class PasswordAuthenticationProvider : IAuthenticationProvider
{
///
/// Canonical protocol name used for registration and EP negotiation.
///
public const string ProtocolName = "password-sha3-v1";
public string DefaultName => ProtocolName;
///
/// Creates the salted credential stored by a server for the
/// password-sha3-v1 protocol. Call this once during account enrollment,
/// persist the returned hash and salt, and discard the plaintext password.
/// The hash is a password-equivalent protocol verifier and must be protected
/// from disclosure, logs, and client-visible data.
///
public static PasswordHash CreateCredential(byte[] password)
{
if (password == null)
throw new ArgumentNullException(nameof(password));
if (password.Length == 0)
throw new ArgumentException("A password cannot be empty.", nameof(password));
var salt = new byte[32];
using (var random = RandomNumberGenerator.Create())
random.GetBytes(salt);
var material = new byte[password.Length + salt.Length];
try
{
Buffer.BlockCopy(password, 0, material, 0, password.Length);
Buffer.BlockCopy(salt, 0, material, password.Length, salt.Length);
return new PasswordHash(
PasswordAuthenticationHandler.ComputeSha3(material),
salt);
}
finally
{
Array.Clear(material, 0, material.Length);
}
}
public IAuthenticationHandler CreateAuthenticationHandler(AuthenticationContext context)
{
var authHandler = new PasswordAuthenticationHandler(context.Mode,
context.Direction,
context.InitiatorIdentity,
context.ResponderIdentity,
context.HostName,
context.Domain,
this);
return authHandler;
}
public virtual PasswordHash GetHostedAccountCredential(string identity, string domain)
{
return new PasswordHash();
}
public virtual IdentityPassword GetSelfIdentityAndCredential(string domain, string hostname)
{
return new IdentityPassword();
}
public virtual byte[] GetSelfCredential(string identity, string domain, string hostname)
{
return null;
}
public virtual AsyncReply Login(Session session)
{
return new AsyncReply(false);
}
public virtual AsyncReply Logout(Session session)
{
return new AsyncReply(false);
}
}
}