public async Task <ActionResult> Index(LoginViewModel model)
        {
            using (var hash = SHA256.Create())
            {
                if (!ModelState.IsValid)
                {
                    return(View(model));
                }

                var result = await _signinManager.Value.PasswordSignInAsync(
                    Base62.Encode(hash.ComputeHash(Encoding.UTF8.GetBytes(model.Email))),
                    model.Password, false, false);

                switch (result)
                {
                case SignInStatus.LockedOut:
                case SignInStatus.RequiresVerification:
                    throw new NotImplementedException();

                case SignInStatus.Success:
                    return(RedirectToRoute("Default"));

                case SignInStatus.Failure:
                    ModelState.AddModelError("", "Username or password was incorrect.");
                    model.Password = "";
                    return(View(model));

                default:
                    throw new NotImplementedException();
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Branca specification-level token generation
        /// </summary>
        /// <param name="payload">The payload to be encrypted into the Branca token</param>
        /// <param name="key">32-byte private key used to encrypt and decrypt the Branca token</param>
        /// <returns>Base62 encoded Branca Token</returns>
        public virtual string CreateToken(string payload, byte[] key)
        {
            if (string.IsNullOrWhiteSpace(payload))
            {
                throw new ArgumentNullException(nameof(payload));
            }
            if (!IsValidKey(key))
            {
                throw new InvalidOperationException("Invalid encryption key");
            }

            var nonce = new byte[24];

            RandomNumberGenerator.Create().GetBytes(nonce);

            var timestamp = Convert.ToUInt32(DateTimeOffset.UtcNow.ToUnixTimeSeconds());

            // header
            var header = new byte[29];

            using (var stream = new MemoryStream(header))
            {
                // version
                stream.WriteByte(0xBA);

                // timestamp
                stream.Write(BitConverter.GetBytes(timestamp), 0, 4);

                // nonce
                stream.Write(nonce, 0, nonce.Length);
            }

            var keyMaterial = new KeyParameter(key);
            var parameters  = new ParametersWithIV(keyMaterial, nonce);

            var engine = new XChaChaEngine();

            engine.Init(true, parameters);

            var plaintextBytes = Encoding.UTF8.GetBytes(payload);
            var ciphertext     = new byte[plaintextBytes.Length + 16];

            engine.ProcessBytes(plaintextBytes, 0, plaintextBytes.Length, ciphertext, 0);

            var poly = new Poly1305();

            poly.Init(keyMaterial);
            poly.BlockUpdate(header, 0, header.Length);
            poly.DoFinal(ciphertext, plaintextBytes.Length);

            var tokenBytes = new byte[header.Length + ciphertext.Length];

            Buffer.BlockCopy(header, 0, tokenBytes, 0, header.Length);
            Buffer.BlockCopy(ciphertext, 0, tokenBytes, header.Length, ciphertext.Length);

            return(Base62.Encode(tokenBytes));
        }
Beispiel #3
0
        public IActionResult Encode([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "encoder/encode")] HttpRequest req)
        {
            if (!req.QueryString.HasValue ||
                !long.TryParse(req.QueryString.Value.TrimStart('?'), out var number))
            {
                return(new BadRequestObjectResult(Properties.Resources.Encoder_MissingEncodeQuery));
            }

            return(new OkObjectResult(Base62.Encode(number)));
        }
Beispiel #4
0
        public void ValidateToken_CiphertextModification_ExpectSecurityTokenException()
        {
            var handler = new BrancaTokenHandler();

            var token   = handler.CreateToken("test", key);
            var decoded = Base62.Decode(token);

            decoded[decoded.Length - 17] ^= 1; // Last byte before the Poly1305 tag

            Assert.Throws <CryptographicException>(() => handler.DecryptToken(Base62.Encode(decoded), key));
        }
Beispiel #5
0
        public void WithRandomBytes_ExpectCorrectValuesEncoded()
        {
            var bytes = new byte[128];
            var rng   = RandomNumberGenerator.Create();

            rng.GetBytes(bytes);

            var encodedBytes = Base62.Encode(bytes);

            Base62.Decode(encodedBytes).Should().BeEquivalentTo(bytes);
        }
Beispiel #6
0
 public Request(
     string personId,
     int amount,
     string description,
     string[]?keywords = default)
     : this()
 {
     IsReadOnly = false;
     // Requests only need to be unique within a person, so we use that as the prefix to disambiguate
     // multiple requests at the same UtcNow. The high-precision time also helps make that unique too.
     Raise(new RequestCreated(personId + "-" + Base62.Encode(PreciseTime.UtcNow.Ticks), amount, description, keywords, personId: personId));
 }
Beispiel #7
0
        public Link CreateShortUrl(string url)
        {
            Link link = new Link();

            link.Redir = url;
            db.Links.Add(link);
            db.SaveChanges();
            // Now we generate a Base36 string for the DB id:
            link.Hash = Base62.Encode(link.Id);
            db.SaveChanges();
            return(link);
        }
Beispiel #8
0
        public void WithUtf8Characters_ExpectCorrectValuesEncoded(string testValue, string expectedResult)
        {
            var testBytes = System.Text.Encoding.UTF8.GetBytes(testValue);

            var result = Base62.Encode(testBytes);

            result.Should().Be(expectedResult);

            var decodedBytes = Base62.Decode(result);

            decodedBytes.Should().BeEquivalentTo(testBytes);
        }
Beispiel #9
0
 static void Main(string[] args)
 {
     for (int i = 0; i < 100; i++)
     {
         string str = Base62.Encode(i);
         Console.Write($"{str}:{Base62.Decode(str)}\t");
         if (i % 10 == 0)
         {
             Console.WriteLine();
         }
     }
     Console.ReadKey();
 }
Beispiel #10
0
        public static string Compress(string url, Dictionary <string, string> hostConversions = null)
        {
            InitHuffmanTree();

            Url oUrl = Url.CreateFromString(url);

            // "Compress" protocol
            if (oUrl.Protocol == "http" || oUrl.Protocol == null)
            {
                oUrl.Protocol = "#";
            }
            else if (oUrl.Protocol == "https")
            {
                oUrl.Protocol = "$";
            }
            else if (oUrl.Protocol == "ftp")
            {
                oUrl.Protocol = "F";
            }
            else
            {
                throw new Exception(string.Format("Unkown protocol \"{0}\"", oUrl.Protocol));
            }

            if (hostConversions != null)
            {
                // "Compress" hosts
                string[] urlHostParts = oUrl.Host.Split('.');
                for (int i = 0; i < urlHostParts.Length; i++)
                {
                    foreach (KeyValuePair <string, string> hostConversion in hostConversions)
                    {
                        if (urlHostParts[i] == hostConversion.Key)
                        {
                            urlHostParts[i] = hostConversion.Value;
                            break;
                        }
                    }
                }
                oUrl.Host = string.Join(".", urlHostParts);
            }

            url = oUrl.ToShortString();

            // Reduce entropy
            byte[] urlBytes = Encoding.ASCII.GetBytes(url);
            urlBytes = _huffmanTree.Encode(urlBytes);
            urlBytes = ChecksumAdd(urlBytes);
            return(Base62.Encode(urlBytes));
        }
        /// <summary>
        /// Branca specification-level token generation
        /// </summary>
        /// <param name="payload">The payload to be encrypted into the Branca token</param>
        /// <param name="timestamp">The timestamp included in the Branca token (iat: issued at)</param>
        /// <param name="key">32-byte private key used to encrypt and decrypt the Branca token</param>
        /// <returns>Base62 encoded Branca Token</returns>
        public virtual string CreateToken(string payload, uint timestamp, byte[] key)
        {
            if (string.IsNullOrWhiteSpace(payload))
            {
                throw new ArgumentNullException(nameof(payload));
            }
            if (!IsValidKey(key))
            {
                throw new InvalidOperationException("Invalid encryption key");
            }

            var nonce = new byte[24];

            using (var rng = RandomNumberGenerator.Create())
            {
                rng.GetBytes(nonce);
            }

            // header
            var header = new byte[29];

            using (var stream = new MemoryStream(header))
            {
                // version
                stream.WriteByte(0xBA);

                // timestamp (big endian uint32)
                stream.Write(BitConverter.GetBytes(timestamp).Reverse().ToArray(), 0, 4);

                // nonce
                stream.Write(nonce, 0, nonce.Length);
            }

            var plaintext  = Encoding.UTF8.GetBytes(payload);
            var ciphertext = new byte[plaintext.Length];
            var tag        = new byte[TagLength];

            new XChaCha20Poly1305(key).Encrypt(nonce, plaintext, ciphertext, tag, header);

            var tokenBytes = new byte[header.Length + ciphertext.Length + TagLength];

            Buffer.BlockCopy(header, 0, tokenBytes, 0, header.Length);
            Buffer.BlockCopy(ciphertext, 0, tokenBytes, header.Length, ciphertext.Length);
            Buffer.BlockCopy(tag, 0, tokenBytes, tokenBytes.Length - TagLength, tag.Length);

            return(Base62.Encode(tokenBytes));
        }
Beispiel #12
0
        public void WhenSerializingRequestCreated_ThenCanDeserialize()
        {
            var serializer = new Serializer();

            var expected = new RequestCreated(Constants.Donee.Id + "-" + Base62.Encode(PreciseTime.UtcNow.Ticks), 0, "");

            var json = serializer.Serialize(expected);

#if DEBUG
            output.WriteLine(json);
#endif

            var actual = serializer.Deserialize <RequestCreated>(json);

            Assert.Equal(expected.PersonId, actual.PersonId);
            Assert.Equal(expected.RequestId, actual.RequestId);
        }
Beispiel #13
0
        public async Task <ActionResult> Index(RegistrationViewModel model)
        {
            using (var hash = SHA256.Create())
            {
                if (!ModelState.IsValid)
                {
                    return(View(model));
                }

                var user = new User
                {
                    UserName  = Base62.Encode(hash.ComputeHash(Encoding.UTF8.GetBytes(model.Email))),
                    Email     = model.Email,
                    FirstName = model.FirstName,
                    LastName  = model.LastName
                };

                if (!(await _userManager.CreateAsync(user, model.Password)).IsValid(ModelState))
                {
                    foreach (var value in ModelState.Values)
                    {
                        if (value.Errors.Any(error => error.ErrorMessage.Contains("already taken")))
                        {
                            ModelState.Clear();
                            ModelState.AddModelError("", $"{model.Email} is already taken.");
                            break;
                        }
                    }

                    return(View(model));
                }

                await _signinManager.SignInAsync(user, false, false);

                if (!(await _userManager.UpdateAsync(user)).IsValid(ModelState))
                {
                    return(View(model));
                }

                return(RedirectToRoute("Default"));
            }
        }
Beispiel #14
0
        public void when_output_path_not_exists_then_creates_it()
        {
            task.Contents = new[]
            {
                // Need at least one dependency or content file for the generation to succeed.
                new TaskItem("Newtonsoft.Json", new Metadata
                {
                    { MetadataName.PackageId, "package" },
                    { MetadataName.PackFolder, PackFolderKind.Dependency },
                    { MetadataName.Version, "8.0.0" },
                    { MetadataName.TargetFramework, "net45" }
                }),
            };

            task.EmitPackage = "true";
            task.TargetPath  = Path.Combine(Base62.Encode(DateTime.Now.Ticks), "output.nupkg");

            Assert.True(task.Execute());
            Assert.True(File.Exists(task.TargetPath));
        }
Beispiel #15
0
        /// <summary>Returns a string representation of the value of this instance of the <see cref="Uuid64"/> class, according to the provided format specifier and culture-specific format information.</summary>
        /// <param name="format">A single format specifier that indicates how to format the value of this Guid. The format parameter can be "D", "N", "Z", "R", "X" or "B". If format is null or an empty string (""), "D" is used.</param>
        /// <param name="formatProvider">An object that supplies culture-specific formatting information. Only used for the "R" format.</param>
        /// <returns>The value of this <see cref="Uuid64"/>, using the specified format.</returns>
        /// <example>
        /// <p>The <b>D</b> format encodes the value as two groups of 8 hexadecimal digits, separated by an hyphen: "01234567-89abcdef" (17 characters).</p>
        /// <p>The <b>X</b> format encodes the value as a single group of 16 hexadecimal digits: "0123456789abcdef" (16 characters).</p>
        /// <p>The <b>B</b> format is equivalent to the <b>D</b> format, but surrounded with '{' and '}': "{01234567-89abcdef}" (19 characters).</p>
        /// <p>The <b>R</b> format encodes the value as a decimal number "1234567890" (1 to 20 characters) which can be parsed as an UInt64 without loss.</p>
        /// <p>The <b>C</b> format uses a compact base-62 encoding that preserves lexicographical ordering, composed of digits, uppercase alpha and lowercase alpha, suitable for compact representation that can fit in a querystring.</p>
        /// <p>The <b>Z</b> format is equivalent to the <b>C</b> format, but with extra padding so that the string is always 11 characters long.</p>
        /// </example>
        public string ToString(string format, IFormatProvider formatProvider)
        {
            if (string.IsNullOrEmpty(format))
            {
                format = "D";
            }

            switch (format)
            {
            case "D":
            {                     // Default format is "xxxxxxxx-xxxxxxxx"
                return(Encode16(m_value, separator: true, quotes: false, upper: true));
            }

            case "d":
            {                     // Default format is "xxxxxxxx-xxxxxxxx"
                return(Encode16(m_value, separator: true, quotes: false, upper: false));
            }

            case "C":
            case "c":
            {                     // base 62, compact, no padding
                return(Base62.Encode(m_value, padded: false));
            }

            case "Z":
            case "z":
            {                     // base 62, padded with '0' up to 11 chars
                return(Base62.Encode(m_value, padded: true));
            }

            case "R":
            case "r":
            {                     // Integer: "1234567890"
                return(m_value.ToString(null, formatProvider ?? CultureInfo.InvariantCulture));
            }

            case "X":             //TODO: Guid.ToString("X") returns "{0x.....,0x.....,...}"
            case "N":
            {                     // "XXXXXXXXXXXXXXXX"
                return(Encode16(m_value, separator: false, quotes: false, upper: true));
            }

            case "x":             //TODO: Guid.ToString("X") returns "{0x.....,0x.....,...}"
            case "n":
            {                     // "xxxxxxxxxxxxxxxx"
                return(Encode16(m_value, separator: false, quotes: false, upper: false));
            }

            case "B":
            {                     // "{xxxxxxxx-xxxxxxxx}"
                return(Encode16(m_value, separator: true, quotes: true, upper: true));
            }

            case "b":
            {                     // "{xxxxxxxx-xxxxxxxx}"
                return(Encode16(m_value, separator: true, quotes: true, upper: false));
            }

            default:
            {
                throw new FormatException("Invalid " + nameof(Uuid64) + " format specification.");
            }
            }
        }
        public async Task <ActionResult> ExternalLoginCallbackAsync([CanBeNull] string salt, [CanBeNull] string redirectUri)
        {
            try
            {
                var info = await _authenticationManager.Value.GetExternalLoginInfoAsync();

                if (info == null)
                {
                    Logger.Error("An unsuccessful login occurred with an external login service.");
                    ModelState.AddModelError("", "Unable to login with that external login service.");
                    return(View("Index", new LoginViewModel {
                        Salt = salt, RedirectUri = redirectUri
                    }));
                }

                var name = JsonConvert.DeserializeAnonymousType(info.ExternalIdentity.FindFirst("name").Value,
                                                                new { givenName = "", familyName = "" });

                var result = await _signinManager.Value.ExternalSignInAsync(info, false);

                switch (result)
                {
                case SignInStatus.LockedOut:
                case SignInStatus.RequiresVerification:
                    throw new NotImplementedException($"{result} not implemented");

                case SignInStatus.Success:
                    return(Success(salt, redirectUri));

                case SignInStatus.Failure:
                    info.Email = info.Email ?? info.ExternalIdentity.FindFirst("preferred_username")?.Value;

                    var user = new User
                    {
                        UserName  = Base62.Encode(Base64.UrlSafeDecode(new RandomStringFactory().Generate())),
                        Email     = info.Email,
                        FirstName = name.givenName,
                        LastName  = name.familyName
                    };

                    if (!(await _userManager.Value.CreateAsync(user)).IsValid(ModelState))
                    {
                        return(View("Index", new LoginViewModel {
                            Salt = salt, RedirectUri = redirectUri
                        }));
                    }

                    if (!(await _userManager.Value.AddLoginAsync(user.Id, info.Login)).IsValid(ModelState))
                    {
                        return(View("Index", new LoginViewModel {
                            Salt = salt, RedirectUri = redirectUri
                        }));
                    }

                    if (!(await _userManager.Value.UpdateAsync(user)).IsValid(ModelState))
                    {
                        return(View("Index", new LoginViewModel {
                            Salt = salt, RedirectUri = redirectUri
                        }));
                    }

                    await _signinManager.Value.SignInAsync(user, false, false);

                    return(Success(salt, redirectUri));

                default:
                    throw new NotImplementedException($"{result} not implemented");
                }
            }
            catch (DbEntityValidationException e)
            {
                Logger.Error(JsonConvert.SerializeObject(e.EntityValidationErrors.Select(error => new { error.Entry.Entity, error.ValidationErrors })));
                throw;
            }
        }
        public void DecryptToken_WhenTokenHasIncorrectVersion_ExpectSecurityTokenException()
        {
            var bytes = new byte[120];

            new Random().NextBytes(bytes);
            bytes[0] = 0x00;

            Assert.Throws <SecurityTokenException>(() =>
                                                   new BrancaTokenHandler().DecryptToken(Base62.Encode(bytes), validKey));
        }