예제 #1
0
        private void VerifyAssert(ReadOnlySpan <byte> authData, ReadOnlySpan <byte> signature, FidoExtensions extensions)
        {
            byte[] keyBytes = null;
            using (var fin = new StreamReader(File.OpenRead(PublicKey))) {
                var reader = new PemReader(fin);
                if (Type == KeyType.ECDSA)
                {
                    ECPublicKeyParameters parameters = (ECPublicKeyParameters)reader.ReadObject();
                    var x = parameters.Q.XCoord.ToBigInteger().ToByteArray();
                    var y = parameters.Q.YCoord.ToBigInteger().ToByteArray();
                    keyBytes = new byte[64];

                    // Why?  There seems to be an extra byte at the beginning sometimes
                    Array.Copy(x, x.Length - 32, keyBytes, 0, 32);
                    Array.Copy(y, y.Length - 32, keyBytes, 32, 32);
                }
                else if (Type == KeyType.RSA)
                {
                    RsaKeyParameters parameters = (RsaKeyParameters)reader.ReadObject();
                    var mod = parameters.Modulus.ToByteArray();
                    var e   = parameters.Exponent.ToByteArray();
                    keyBytes = new byte[mod.Length + e.Length];
                    mod.CopyTo(keyBytes, 0);
                    e.CopyTo(keyBytes, mod.Length);
                }
                else if (Type == KeyType.EDDSA)
                {
                    throw new NotSupportedException("Original example includes this but not sure why, it doesn't seem supported");
                }
                else
                {
                    throw new NotSupportedException("Unsupported key type");
                }
            }

            using (var assert = new FidoAssertion()) {
                assert.SetClientData(Cd);
                assert.Rp    = "localhost";
                assert.Count = 1;
                assert.SetAuthData(authData, 0);
                assert.SetExtensions(extensions);
                if (UserPresenceRequired)
                {
                    assert.SetUserPresenceRequired(true);
                }

                if (UserVerificationRequired)
                {
                    assert.SetUserVerificationRequired(true);
                }

                assert.SetSignature(signature, 0);
                assert.Verify(0, FromKeyType(Type), keyBytes);
            }
        }
예제 #2
0
        private void OnExecute()
        {
            Fido2Settings.Flags = FidoFlags.Debug;
            var ext = HMACSalt != null ? FidoExtensions.HmacSecret : FidoExtensions.None;

            using (var assert = new FidoAssertion()) {
                using (var dev = new FidoDevice()) {
                    dev.Open(Device);
                    if (ForceU2F)
                    {
                        dev.ForceU2F();
                    }

                    if (CredentialId != null)
                    {
                        var credId = File.ReadAllBytes(CredentialId);
                        assert.AllowCredential(credId);
                    }

                    assert.ClientDataHash = Cdh;
                    assert.Rp             = "localhost";
                    assert.SetExtensions(ext);
                    assert.SetOptions(UserPresenceRequired, UserVerificationRequired);
                    dev.GetAssert(assert, Pin);
                    dev.Close();
                }

                if (assert.Count != 1)
                {
                    throw new Exception($"{assert.Count} signatures required");
                }

                VerifyAssert(assert[0].AuthData, assert[0].Signature, ext);

                if (HMACSecret != null)
                {
                    File.WriteAllBytes(HMACSecret, assert[0].HmacSecret.ToArray());
                }
            }
        }
예제 #3
0
        private void VerifyAssert(ReadOnlySpan <byte> authData, ReadOnlySpan <byte> signature, FidoExtensions extensions)
        {
            var ext = HMACSalt != null ? FidoExtensions.HmacSecret : FidoExtensions.None;

            byte[] keyBytes = null;
            using (var fin = new StreamReader(File.OpenRead(PublicKey))) {
                var reader = new PemReader(fin);
                if (Type == KeyType.ECDSA)
                {
                    ECPublicKeyParameters parameters = (ECPublicKeyParameters)reader.ReadObject();
                    var x = parameters.Q.XCoord.ToBigInteger().ToByteArray();
                    var y = parameters.Q.YCoord.ToBigInteger().ToByteArray();
                    keyBytes = new byte[x.Length + y.Length - 1];
                    x.CopyTo(keyBytes, 0);

                    // Why?  There seems to be an extra byte at the beginning
                    Array.Copy(y, 1, keyBytes, x.Length, y.Length - 1);
                }
                else
                {
                    RsaKeyParameters parameters = (RsaKeyParameters)reader.ReadObject();
                    var mod = parameters.Modulus.ToByteArray();
                    var e   = parameters.Exponent.ToByteArray();
                    keyBytes = new byte[mod.Length + e.Length];
                    mod.CopyTo(keyBytes, 0);
                    e.CopyTo(keyBytes, mod.Length);
                }
            }

            using (var assert = new FidoAssertion()) {
                assert.ClientDataHash = Cdh;
                assert.Rp             = "localhost";
                assert.Count          = 1;
                assert.SetAuthData(authData, 0);
                assert.SetExtensions(ext);
                assert.SetOptions(UserPresenceRequired, UserVerificationRequired);
                assert.SetSignature(signature, 0);
                assert.Verify(0, FromKeyType(Type), keyBytes);
            }
        }
예제 #4
0
        private void OnExecute()
        {
            Fido2Settings.Flags = FidoFlags.Debug;
            var ext = FidoExtensions.None;

            if (HMACSalt != null)
            {
                ext |= FidoExtensions.HmacSecret;
            }
            if (BlobKey != null)
            {
                ext |= FidoExtensions.LargeBlobKey;
            }

            using (var assert = new FidoAssertion()) {
                using (var dev = new FidoDevice()) {
                    dev.Open(Device);
                    if (ForceU2F)
                    {
                        dev.ForceU2F();
                    }

                    assert.SetClientData(Cd);
                    assert.Rp = "localhost";
                    assert.SetExtensions(ext);
                    if (UserPresenceRequired)
                    {
                        assert.SetUserPresenceRequired(true);
                    }

                    if (UserVerificationRequired)
                    {
                        assert.SetUserVerificationRequired(true);
                    }

                    if (Timeout != 0)
                    {
                        dev.SetTimeout(TimeSpan.FromSeconds(Timeout));
                    }

                    if (CredentialId != null)
                    {
                        var credId = File.ReadAllBytes(CredentialId);
                        assert.AllowCredential(credId);
                    }

                    dev.GetAssert(assert, Pin);
                    dev.Close();
                }

                if (assert.Count != 1)
                {
                    throw new Exception($"{assert.Count} signatures required");
                }

                if (Pin != null)
                {
                    UserVerificationRequired = true;
                }

                VerifyAssert(assert[0].AuthData, assert[0].Signature, ext);

                if (HMACSecret != null)
                {
                    File.WriteAllBytes(HMACSecret, assert[0].HmacSecret.ToArray());
                }
            }
        }
예제 #5
0
        //View the c# versions of the c examples from Yubico here:
        //https://github.com/borrrden/Fido2Net/blob/master/Examples/assert/Assert/Program.cs
        //This will help explain how to eg retrieve hmac secrets
        private static AssertionResult DoAssertion(string devicePath, bool useHmacExtension, string rp, FidoCose algorithmType, string pin, MakeCredentialResult credential, MakeCredentialResult credential2, byte[] salt, byte[] salt2, bool requireUp, bool requireUv)
        {
            var ext = useHmacExtension ? FidoExtensions.HmacSecret : FidoExtensions.None;

            using (var assert = new FidoAssertion())
            {
                using (var dev = new FidoDevice())
                {
                    dev.Open(devicePath);

                    if (credential.CredentialId != null)
                    {
                        assert.AllowCredential(Convert.FromBase64String(credential.CredentialId));
                    }

                    if (credential2.CredentialId != null)
                    {
                        assert.AllowCredential(Convert.FromBase64String(credential2.CredentialId));
                    }

                    assert.ClientDataHash = Cdh;
                    assert.Rp             = rp;
                    assert.SetExtensions(ext);

                    if (useHmacExtension)
                    {
                        assert.SetHmacSalt(salt, 0);
                        if (credential2.CredentialId != null)
                        {
                            assert.SetHmacSalt(salt2, 1);
                        }
                    }

                    if (requireUv)
                    {
                        assert.SetOptions(requireUp, requireUv);
                    }

                    dev.GetAssert(assert, pin);
                    dev.Close();
                }

                if (assert.Count != 1)
                {
                    throw new Exception($"{assert.Count} signatures required");
                }

                var authData     = assert[0].AuthData;
                var signature    = assert[0].Signature;
                var credentialId = Convert.ToBase64String(assert[0].Id.ToArray());
                var verifiedKey  = "";

                using (var verify = new FidoAssertion())
                {
                    verify.ClientDataHash = Cdh;
                    verify.Rp             = rp;
                    verify.Count          = 1;
                    verify.SetAuthData(authData, 0);
                    verify.SetExtensions(ext);

                    if (requireUv)
                    {
                        verify.SetOptions(requireUp, requireUv);
                    }

                    verify.SetSignature(signature, 0);

                    //Get the correct public id
                    string publicKey = string.Empty;

                    if (credential.CredentialId == credentialId)
                    {
                        publicKey = credential.PublicKey;
                    }
                    else if (credential2.CredentialId == credentialId)
                    {
                        publicKey = credential2.PublicKey;
                    }

                    if (string.IsNullOrEmpty(publicKey))
                    {
                        throw new ApplicationException("Credential not found in assertion.");
                    }

                    //Now verify with the public key
                    verify.Verify(0, algorithmType, Convert.FromBase64String(publicKey));
                    verifiedKey = credential.PublicKey;
                }

                AssertionResult result;

                result.HmacSecret = (useHmacExtension) ? assert[0].HmacSecret.ToArray() : new Byte[] { };
                result.Valid      = !String.IsNullOrEmpty(verifiedKey);
                result.PublicKey  = verifiedKey;

                return(result);
            }
        }
예제 #6
0
        //View the c# versions of the c examples from Yubico here:
        //https://github.com/borrrden/Fido2Net/blob/master/Examples/assert/Assert/Program.cs
        //This will help explain how to eg retrieve hmac secrets
        private static AssertionResult DoAssertion(string devicePath, bool useHmacExtension, string rp, FidoCose algorithmType, string pin, string credentialId, string publicKey, bool requireUp, bool requireUv)
        {
            var ext = useHmacExtension ? FidoExtensions.HmacSecret : FidoExtensions.None;

            using (var assert = new FidoAssertion())
            {
                using (var dev = new FidoDevice())
                {
                    dev.Open(devicePath);

                    if (credentialId != null)
                    {
                        assert.AllowCredential(Convert.FromBase64String(credentialId));
                    }

                    assert.ClientDataHash = Cdh;
                    assert.Rp             = rp;
                    assert.SetExtensions(ext);

                    if (useHmacExtension)
                    {
                        assert.SetHmacSalt(Salt, 0);
                    }

                    if (requireUv)
                    {
                        assert.SetOptions(requireUp, requireUv);
                    }

                    dev.GetAssert(assert, pin);

                    //Find the generated secret (somehow)


                    dev.Close();
                }

                if (assert.Count != 1)
                {
                    throw new Exception($"{assert.Count} signatures required");
                }

                var authData  = assert[0].AuthData;
                var signature = assert[0].Signature;

                using (var verify = new FidoAssertion())
                {
                    verify.ClientDataHash = Cdh;
                    verify.Rp             = rp;
                    verify.Count          = 1;
                    verify.SetAuthData(authData, 0);
                    verify.SetExtensions(ext);

                    if (requireUv)
                    {
                        verify.SetOptions(requireUp, requireUv);
                    }

                    verify.SetSignature(signature, 0);

                    verify.Verify(0, algorithmType, Convert.FromBase64String(publicKey));
                }

                AssertionResult result;

                result.HmacSecret = (useHmacExtension) ? assert[0].HmacSecret.ToArray() : new Byte[] { };
                result.Valid      = true;

                return(result);
            }
        }