Beispiel #1
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);
            }
        }
Beispiel #2
0
        //Note: Registering a security key like this would usually happen in the browser via javascript extension
        //It could be done on behalf of the user via the MMC snapin
        private static MakeCredentialResult MakeDeviceCredential(string devicePath, bool useHmacExtension, FidoCose algorithmType, List <string> excludedCredentials, string pin, bool requireUv)
        {
            //Use these values on the commandline when manually creating a credentail using fido2-token in the Yubico libfido2 toolkit
            //var base64cdh = Convert.ToBase64String(Cdh);
            //var base64UserId = Convert.ToBase64String(UserId);

            var ext = useHmacExtension ? FidoExtensions.HmacSecret : FidoExtensions.None;

            //Instructs the authenticator to store the key material on the device. Default false in the spec.
            //var residentKey = false;

            //Instructs the authenticator to require a gesture that verifies the user to complete the request.
            //Examples of such gestures are fingerprint scan or a PIN.  Default false in the spec.
            //var userVerificationRequired = false;

            using (var cred = new FidoCredential())
            {
                using (var dev = new FidoDevice())
                {
                    dev.Open(devicePath);

                    //if (excludedCredentials != null)
                    //{
                    //    foreach (var excludedCredential in excludedCredentials)
                    //    {
                    //        var credId = Convert.FromBase64String(excludedCredential);
                    //        cred.Exclude(credId);
                    //    }
                    //}

                    cred.SetType(algorithmType);

                    cred.ClientDataHash = Cdh;

                    cred.Rp = new FidoCredentialRp
                    {
                        Id = "relyingparty",
                        //Name = "sweet home localhost"
                    };

                    cred.SetUser(new FidoCredentialUser
                    {
                        Id = UserId,
                        //DisplayName = "john smith",
                        Name = "johnsmith2"
                               //Icon = "http://secone.io/logo.png"
                    });

                    cred.SetExtensions(ext);

                    //Only set these options if we have the capability
                    if (requireUv)
                    {
                        cred.SetOptions(false, true);
                    }

                    //Make the credential, including the device pin if required
                    dev.MakeCredential(cred, pin);

                    //Seems like we are forcing a close asap even though we have a using
                    dev.Close();
                }

                //Now verify the credential was created successfully, and write out the public key information and credential id

                MakeCredentialResult result;

                using (var verify = new FidoCredential())
                {
                    verify.SetType(algorithmType);

                    verify.ClientDataHash = Cdh;
                    verify.Rp             = new FidoCredentialRp
                    {
                        Id = "relyingparty",
                        //Name = "sweet home localhost"
                    };

                    verify.AuthData = cred.AuthData;
                    verify.SetExtensions(ext);

                    if (requireUv)
                    {
                        verify.SetOptions(false, true);
                    }

                    verify.SetX509(cred.X5C);
                    verify.Signature = cred.Signature;
                    verify.Format    = cred.Format;

                    //Throws a CtapException if it fails.
                    verify.Verify();

                    //Now write out the information, because we need the public key created by the device for future assertions
                    result.PublicKey    = Convert.ToBase64String(verify.PublicKey.ToArray());
                    result.CredentialId = Convert.ToBase64String(verify.Id.ToArray());
                }

                //Also bang this out to file for future reference
                var builder = new StringBuilder();
                builder.AppendLine($"CredentialId:{result.CredentialId}");
                builder.AppendLine($"PublicKey:{result.PublicKey}");

                File.WriteAllText($"Credential.txt", builder.ToString());

                return(result);
            }
        }
Beispiel #3
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);
            }
        }