Skip to content

Commit

Permalink
Update branch from master
Browse files Browse the repository at this point in the history
  • Loading branch information
aseigler committed Oct 15, 2022
2 parents 611707a + 686895b commit e1e5373
Show file tree
Hide file tree
Showing 132 changed files with 13,876 additions and 11,774 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -331,4 +331,5 @@ ASALocalRun/
/results
/Test/coverage.netcoreapp3.1.cobertura.xml

.DS_Store
/testEnvironments.json
4 changes: 4 additions & 0 deletions Demo/Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ public async Task<JsonResult> MakeCredential([FromBody] AuthenticatorAttestation
AaGuid = success.Result.Aaguid
});

// Remove Certificates from success because System.Text.Json cannot serialize them properly. See https://github.com/passwordless-lib/fido2-net-lib/issues/328
success.Result.AttestationCertificate = null;
success.Result.AttestationCertificateChain = null;

// 4. return "ok" to the client
return Json(success);
}
Expand Down
2 changes: 1 addition & 1 deletion Demo/Pages/usernameless.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
<p>In this flow the Relying Party should tell the Authenticator to do User Verification (set UserVerification to required) via Biometrics/pin, thus the authentication is MFA (Something the user has - the private key - and something the user knows/is - the PIN or biometrics). However in scenarios where security requirements are very low we we could discourage user verification to minimize the user interaction needed to sign in. If discouraged, only user presence will be checked (Any human is present at the device).</p>

<p>
Read the source code for this demo here: <a href="@Url.ToGithub("Fido2Demo/wwwroot/js/usernameless.register.js")">usernameless.register.js</a> and <a href="@Url.ToGithub("Fido2Demo/wwwroot/js/usernameless.login.js")">usernameless.login.js</a>
Read the source code for this demo here: <a href="@Url.ToGithub("Demo/wwwroot/js/usernameless.register.js")">usernameless.register.js</a> and <a href="@Url.ToGithub("Demo/wwwroot/js/usernameless.login.js")">usernameless.login.js</a>
</p>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion Demo/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:4729/"
"applicationUrl": "http://localhost:4729/;https://localhost:44329/"
}
}
}
2 changes: 1 addition & 1 deletion Demo/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void ConfigureServices(IServiceCollection services)
{
options.ServerDomain = Configuration["fido2:serverDomain"];
options.ServerName = "FIDO2 Test";
options.Origins = new HashSet<string> { Configuration["fido2:origin"] };
options.Origins = Configuration.GetSection("fido2:origins").Get<HashSet<string>>();
options.TimestampDriftTolerance = Configuration.GetValue<int>("fido2:timestampDriftTolerance");
options.MDSCacheDirPath = Configuration["fido2:MDSCacheDirPath"];
})
Expand Down
2 changes: 1 addition & 1 deletion Demo/appsettings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"fido2": {
"serverDomain": "localhost",
"origin": "https://localhost:44329",
"origins": [ "https://localhost:44329" ],
"timestampDriftTolerance": 300000
},
"Logging": {
Expand Down
11 changes: 4 additions & 7 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
<Project>
<!-- Package Metadata -->
<PropertyGroup>
<VersionPrefix>2.0.2</VersionPrefix>
<VersionPrefix>3.0.0</VersionPrefix>
<VersionSuffix>
</VersionSuffix>
<Description>FIDO2 .NET library (WebAuthn)</Description>
<RepositoryUrl>https://github.com/abergs/fido2-net-lib</RepositoryUrl>
<RepositoryUrl>https://github.com/passwordless-lib/fido2-net-lib</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>fido2 webauthn</PackageTags>
<PackageReleaseNotes>Initial release</PackageReleaseNotes>
<PackageProjectUrl>https://github.com/abergs/fido2-net-lib</PackageProjectUrl>
<PackageProjectUrl>https://github.com/passwordless-lib/fido2-net-lib</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>

<!-- Global Variables -->
<PropertyGroup>
<SupportedTargetFrameworks>net6.0</SupportedTargetFrameworks>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

<!-- Language + Compiler Settings-->
<PropertyGroup>
<LangVersion>10</LangVersion>
</PropertyGroup>

<!--MISC-->
<PropertyGroup>
<!-- Avoid annoying build warnings when packing using the solution file -->
<IsPackable>false</IsPackable>
<!-- Avoid annoying build warnings when packing using the solution file -->
<IsTestProject>false</IsTestProject>
</PropertyGroup>
</Project>
</Project>
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The quickest way to get started with FIDO2 and WebAuthn is with the [Passwordles

### Purpose

<img align="right" width="100px" src="https://dotnetfoundation.org/img/logo_big.svg" />
<img align="right" width="100px" src="https://user-images.githubusercontent.com/357283/188737052-4735ba0a-08b5-47e8-9b2c-02c8829d2413.png" />
Our purpose is to enable passwordless sign in for all .NET apps (asp, core, native).

To provide a developer friendly and well tested [.NET](https://dotnet.microsoft.com/) [FIDO2 Server](https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-server-v2.0-rd-20180702.html) / [WebAuthn relying party](https://www.w3.org/TR/webauthn/#relying-party) library for the easy validation of [registration](https://www.w3.org/TR/webauthn/#usecase-registration) ([attestation](https://www.w3.org/TR/webauthn/#attestation)) and [authentication](https://www.w3.org/TR/webauthn/#usecase-authentication) ([assertion](https://www.w3.org/TR/webauthn/#authentication-assertion)) of [FIDO2](https://fidoalliance.org/fido2/) / [WebAuthn](https://www.w3.org/TR/webauthn/) credentials, in order to increase the adoption of the technology, ultimately defeating phishing attacks.
Expand Down Expand Up @@ -56,7 +56,7 @@ Read more:
-[Windows Hello](https://docs.microsoft.com/en-us/microsoft-edge/dev-guide/windows-integration/web-authentication)
-[Face ID and Touch ID for the Web](https://webkit.org/blog/11312/meet-face-id-and-touch-id-for-the-web/) (aka "Apple Hello")
- ✅ All currently referenced cryptographic algorithms for FIDO2 Server ([spec](https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-server-v2.0-rd-20180702.html#other))
- ✅ All current attestation formats: "packed", "tpm", "android-key", "android-safetynet", "fido-u2f", "apple", and "none" ([spec](https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-server-v2.0-rd-20180702.html))
- ✅ All current attestation formats: "packed", "tpm", "android-key", "android-safetynet", "fido-u2f", "apple", "apple-appattest", and "none" ([spec](https://www.iana.org/assignments/webauthn/webauthn.xhtml))
- ✅ FIDO2 Server attestation validation via FIDO Metadata Service V3 ([spec](https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html))
- ✅ WebAuthn extensions ([spec](https://www.w3.org/TR/webauthn/#extensions))
- ✅ Examples & demos
Expand Down Expand Up @@ -211,6 +211,8 @@ See [Contributing](CONTRIBUTING.md) for information about contributing to the pr
This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community.
For more information see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).

For security and penetration testing, please see our [Vulnerability Disclosure Program](./VDP.md)

## Contributors

### Code Contributors
Expand Down
81 changes: 81 additions & 0 deletions Src/Fido2.Ctap2/Cbor/CborHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using Fido2NetLib.Cbor;
using Fido2NetLib.Objects;

namespace Fido2NetLib.Ctap2;

internal sealed class CborHelper
{
public static PublicKeyCredentialDescriptor DecodePublicKeyCredentialDescriptor(CborMap map)
{
var result = new PublicKeyCredentialDescriptor();

foreach (var (key, value) in map)
{
switch ((string)key)
{
case "id":
result.Id = (byte[])value;
break;
case "type" when (value is CborTextString { Value: "public-key" }):
result.Type = PublicKeyCredentialType.PublicKey;
break;
}
}

return result;
}

public static PublicKeyCredentialUserEntity DecodePublicKeyCredentialUserEntity(CborMap map)
{
var result = new PublicKeyCredentialUserEntity();

foreach (var (key, value) in map)
{
switch ((string)key)
{
case "id":
result.Id = (byte[])value;
break;
case "name":
result.Name = (string)value;
break;
case "displayName":
result.DisplayName = (string)value;
break;
case "icon":
result.Icon = (string)value;
break;
}
}

return result;
}

public static string[] ToStringArray(CborObject cborObject)
{
var cborArray = (CborArray)cborObject;

var result = new string[cborArray.Length];

for (int i = 0; i < cborArray.Length; i++)
{
result[i] = (string)cborArray[i];
}

return result;
}

public static int[] ToInt32Array(CborObject cborObject)
{
var cborArray = (CborArray)cborObject;

var result = new int[cborArray.Length];

for (int i = 0; i < cborArray.Length; i++)
{
result[i] = (int)cborArray[i];
}

return result;
}
}
16 changes: 16 additions & 0 deletions Src/Fido2.Ctap2/Cbor/CborMember.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Fido2NetLib.Ctap2;

public sealed class CborMember : Attribute
{
public object _key;

public CborMember(byte key)
{
_key = key;
}

public CborMember(string key)
{
_key = key;
}
}
104 changes: 104 additions & 0 deletions Src/Fido2.Ctap2/Commands/AuthenticatorClientPinCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using Fido2NetLib.Cbor;
using Fido2NetLib.Objects;

namespace Fido2NetLib.Ctap2;

public sealed class AuthenticatorClientPinCommand : CtapCommand
{
public AuthenticatorClientPinCommand(
uint pinProtocol,
AuthenticatorClientPinSubCommand subCommand,
CredentialPublicKey? keyAgreement = null,
byte[]? pinAuth = null,
byte[]? newPinEnc = null,
byte[]? pinHashEnc = null)
{

PinProtocol = pinProtocol;
SubCommand = subCommand;
KeyAgreement = keyAgreement;
PinAuth = pinAuth;
NewPinEnc = newPinEnc;
PinHashEnc = pinHashEnc;
}

/// <summary>
/// Required PIN protocol version chosen by the client
/// </summary>
[CborMember(0x01)]
public uint PinProtocol { get; }

/// <summary>
/// The authenticator Client PIN sub command currently being requested.
/// </summary>
[CborMember(0x02)]
public AuthenticatorClientPinSubCommand SubCommand { get; }

/// <summary>
/// Public key of platformKeyAgreementKey.
/// The COSE_Key-encoded public key MUST contain the optional "alg" parameter and MUST NOT contain any other optional parameters.
/// The "alg" parameter MUST contain a COSEAlgorithmIdentifier value.
/// </summary>
[CborMember(0x03)]
public CredentialPublicKey? KeyAgreement { get; }

/// <summary>
/// First 16 bytes of HMAC-SHA-256 of encrypted contents using sharedSecret.
/// </summary>
[CborMember(0x04)]
public byte[]? PinAuth { get; }

/// <summary>
/// Encrypted new PIN using sharedSecret.
/// </summary>
[CborMember(0x05)]
public byte[]? NewPinEnc { get; }

/// <summary>
/// Encrypted first 16 bytes of SHA-256 of PIN using sharedSecret.
/// </summary>
[CborMember(0x06)]
public byte[]? PinHashEnc { get; }

public override CtapCommandType Type => CtapCommandType.AuthenticatorClientPin;

protected override CborObject? GetParameters()
{
var cbor = new CborMap
{
{ 0x01, PinProtocol },
{ 0x02, (int)SubCommand }
};

if (KeyAgreement != null)
{
cbor.Add(0x03, KeyAgreement.GetCborObject());
}

if (PinAuth != null)
{
cbor.Add(0x04, PinAuth);
}

if (NewPinEnc != null)
{
cbor.Add(0x05, NewPinEnc);
}

if (PinHashEnc != null)
{
cbor.Add(0x06, PinHashEnc);
}

return cbor;
}
}

public enum AuthenticatorClientPinSubCommand
{
GetRetries = 0x01,
GetKeyAgreement = 0x02,
SetPin = 0x03,
ChangePin = 0x04,
GetPinToken = 0x05,
}
Loading

0 comments on commit e1e5373

Please sign in to comment.