-
Notifications
You must be signed in to change notification settings - Fork 128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue #65 ValidateTwoFactorPin always returns false, if the secretKey parameter is base32 encoded string - fixed #66
Changes from all commits
b5ea257
ff44a79
3cdfd22
b759503
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,26 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFrameworks>netcoreapp3.0;net452</TargetFrameworks> | ||
<TargetFrameworks>netcoreapp3.0;net452;net5</TargetFrameworks> | ||
|
||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" /> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" /> | ||
<PackageReference Include="Shouldly" Version="3.0.2" /> | ||
<PackageReference Include="xunit" Version="2.4.0" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> | ||
<PackageReference Include="coverlet.collector" Version="1.0.1" /> | ||
<PackageReference Include="xunit" Version="2.4.1" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3"> | ||
<PrivateAssets>all</PrivateAssets> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
</PackageReference> | ||
<PackageReference Include="coverlet.collector" Version="3.0.3"> | ||
<PrivateAssets>all</PrivateAssets> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
</PackageReference> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Google.Authenticator\Google.Authenticator.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
using System; | ||
using Xunit; | ||
using Shouldly; | ||
|
||
|
@@ -10,7 +9,13 @@ public class QRCodeTest | |
public void CanGenerateQRCode() | ||
{ | ||
var subject = new TwoFactorAuthenticator(); | ||
var setupCodeInfo = subject.GenerateSetupCode("issuer","[email protected]","secret", false, 2); | ||
var setupCodeInfo = subject.GenerateSetupCode( | ||
"issuer", | ||
"[email protected]", | ||
"secret", | ||
false, | ||
2); | ||
|
||
setupCodeInfo.QrCodeSetupImageUrl.ShouldNotBeNull(); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,41 +16,39 @@ public static byte[] ToBytes(string input) | |
{ | ||
if (string.IsNullOrEmpty(input)) | ||
{ | ||
throw new ArgumentNullException("input"); | ||
throw new ArgumentNullException(nameof(input)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't remove {} here :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done :) |
||
} | ||
|
||
input = input.TrimEnd('='); //remove padding characters | ||
int byteCount = input.Length * 5 / 8; //this must be TRUNCATED | ||
byte[] returnArray = new byte[byteCount]; | ||
var byteCount = input.Length * 5 / 8; //this must be TRUNCATED | ||
var returnArray = new byte[byteCount]; | ||
|
||
byte curByte = 0, bitsRemaining = 8; | ||
int mask = 0, arrayIndex = 0; | ||
int mask, arrayIndex = 0; | ||
|
||
foreach (char c in input) | ||
foreach (var c in input) | ||
{ | ||
int cValue = CharToValue(c); | ||
var cValue = CharToValue(c); | ||
|
||
if (bitsRemaining > 5) | ||
{ | ||
mask = cValue << (bitsRemaining - 5); | ||
curByte = (byte)(curByte | mask); | ||
curByte = (byte) (curByte | mask); | ||
bitsRemaining -= 5; | ||
} | ||
else | ||
{ | ||
mask = cValue >> (5 - bitsRemaining); | ||
curByte = (byte)(curByte | mask); | ||
curByte = (byte) (curByte | mask); | ||
returnArray[arrayIndex++] = curByte; | ||
curByte = (byte)(cValue << (3 + bitsRemaining)); | ||
curByte = (byte) (cValue << (3 + bitsRemaining)); | ||
bitsRemaining += 3; | ||
} | ||
} | ||
|
||
//if we didn't end with a full byte | ||
if (arrayIndex != byteCount) | ||
{ | ||
returnArray[arrayIndex] = curByte; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't remove {} here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done :) |
||
} | ||
|
||
return returnArray; | ||
} | ||
|
@@ -64,29 +62,29 @@ public static string ToString(byte[] input) | |
{ | ||
if (input == null || input.Length == 0) | ||
{ | ||
throw new ArgumentNullException("input"); | ||
throw new ArgumentNullException(nameof(input)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't remove {} here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
} | ||
|
||
int charCount = (int)Math.Ceiling(input.Length / 5d) * 8; | ||
char[] returnArray = new char[charCount]; | ||
var charCount = (int) Math.Ceiling(input.Length / 5d) * 8; | ||
var returnArray = new char[charCount]; | ||
|
||
byte nextChar = 0, bitsRemaining = 5; | ||
int arrayIndex = 0; | ||
var arrayIndex = 0; | ||
|
||
foreach (byte b in input) | ||
foreach (var b in input) | ||
{ | ||
nextChar = (byte)(nextChar | (b >> (8 - bitsRemaining))); | ||
nextChar = (byte) (nextChar | (b >> (8 - bitsRemaining))); | ||
returnArray[arrayIndex++] = ValueToChar(nextChar); | ||
|
||
if (bitsRemaining < 4) | ||
{ | ||
nextChar = (byte)((b >> (3 - bitsRemaining)) & 31); | ||
nextChar = (byte) ((b >> (3 - bitsRemaining)) & 31); | ||
returnArray[arrayIndex++] = ValueToChar(nextChar); | ||
bitsRemaining += 5; | ||
} | ||
|
||
bitsRemaining -= 3; | ||
nextChar = (byte)((b << bitsRemaining) & 31); | ||
nextChar = (byte) ((b << bitsRemaining) & 31); | ||
} | ||
|
||
//if we didn't end with a full char | ||
|
@@ -101,41 +99,42 @@ public static string ToString(byte[] input) | |
|
||
private static int CharToValue(char c) | ||
{ | ||
int value = (int)c; | ||
var value = (int) c; | ||
|
||
//65-90 == uppercase letters | ||
if (value < 91 && value > 64) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't remove {} here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
{ | ||
return value - 65; | ||
} | ||
|
||
//50-55 == numbers 2-7 | ||
if (value < 56 && value > 49) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't remove {} here |
||
{ | ||
return value - 24; | ||
} | ||
|
||
//97-122 == lowercase letters | ||
if (value < 123 && value > 96) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't remove {} here |
||
{ | ||
return value - 97; | ||
} | ||
|
||
throw new ArgumentException("Character is not a Base32 character.", "c"); | ||
throw new ArgumentException("Character is not a Base32 character.", nameof(c)); | ||
} | ||
|
||
private static char ValueToChar(byte b) | ||
{ | ||
if (b < 26) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't remove {} here |
||
{ | ||
return (char)(b + 65); | ||
return (char) (b + 65); | ||
} | ||
|
||
if (b < 32) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't remove {} here |
||
{ | ||
return (char)(b + 24); | ||
return (char) (b + 24); | ||
} | ||
|
||
throw new ArgumentException("Byte is not a value Base32 value.", "b"); | ||
throw new ArgumentException("Byte is not a value Base32 value.", nameof(b)); | ||
} | ||
|
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯