Example #1
0
 public AuthenticatorData(byte[] rpIdHash, AuthenticatorFlags flags, uint signCount, AttestedCredentialData acd, Extensions exts)
 {
     RpIdHash  = rpIdHash;
     _flags    = flags;
     SignCount = signCount;
     AttestedCredentialData = acd;
     Extensions             = exts;
 }
Example #2
0
        public AuthenticatorData(byte[] authData)
        {
            // Input validation
            if (authData == null)
            {
                throw new VerificationException("Authenticator data cannot be null");
            }
            if (authData.Length < MinLength)
            {
                throw new VerificationException($"Authenticator data is less than the minimum structure length of {MinLength}");
            }

            // Input parsing
            using (var stream = new MemoryStream(authData, false))
            {
                using (var reader = new BinaryReader(stream))
                {
                    RpIdHash = reader.ReadBytes(SHA256HashLenBytes);

                    _flags = (AuthenticatorFlags)reader.ReadByte();

                    var signCountBytes = reader.ReadBytes(sizeof(uint));
                    if (BitConverter.IsLittleEndian)
                    {
                        // Sign count is provided by the authenticator as big endian, convert if we are on little endian system
                        signCountBytes = signCountBytes.Reverse().ToArray();
                    }
                    SignCount = BitConverter.ToUInt32(signCountBytes, 0);

                    // Attested credential data is only present if the AT flag is set
                    if (HasAttestedCredentialData)
                    {
                        // Decode attested credential data, which starts at the next byte past the minimum length of the structure.
                        AttestedCredentialData = new AttestedCredentialData(reader);
                    }

                    // Extensions data is only present if the ED flag is set
                    if (HasExtensionsData)
                    {
                        // "CBORObject.Read: This method will read from the stream until the end
                        // of the CBOR object is reached or an error occurs, whichever happens first."
                        //
                        // Read the CBOR object from the stream
                        var ext = Neos.IdentityServer.MultiFactor.WebAuthN.Library.Cbor.CBORObject.Read(reader.BaseStream);

                        // Encode the CBOR object back to a byte array.
                        Extensions = new Extensions(ext.EncodeToBytes());
                    }
                    // There should be no bytes left over after decoding all data from the structure
                    if (stream.Position != stream.Length)
                    {
                        throw new VerificationException("Leftover bytes decoding AuthenticatorData");
                    }
                }
            }
        }
        public AuthenticatorData(byte[] authData)
        {
            // Input validation
            if (authData is null)
            {
                throw new Fido2VerificationException("Authenticator data cannot be null");
            }

            if (authData.Length < MinLength)
            {
                throw new Fido2VerificationException($"Authenticator data is less than the minimum structure length of {MinLength}");
            }

            // Input parsing
            var reader = new MemoryReader(authData);

            RpIdHash = reader.ReadBytes(SHA256HashLenBytes);

            _flags = (AuthenticatorFlags)reader.ReadByte();

            SignCount = reader.ReadUInt32BigEndian();

            // Attested credential data is only present if the AT flag is set
            if (HasAttestedCredentialData)
            {
                // Decode attested credential data, which starts at the next byte past the minimum length of the structure.
                AttestedCredentialData = new AttestedCredentialData(authData.AsMemory(reader.Position), out int bytesRead);

                reader.Advance(bytesRead);
            }

            // Extensions data is only present if the ED flag is set
            if (HasExtensionsData)
            {
                // Read the CBOR object
                var ext = CborObject.Decode(authData.AsMemory(reader.Position), out int bytesRead);

                reader.Advance(bytesRead);

                // Encode the CBOR object back to a byte array.
                Extensions = new Extensions(ext.Encode());
            }

            // There should be no bytes left over after decoding all data from the structure
            if (reader.RemainingBytes != 0)
            {
                throw new Fido2VerificationException("Leftover bytes decoding AuthenticatorData");
            }
        }
        public AuthenticatorData(byte[] authData)
        {
            // Input validation
            Validator.AssertNotNull(authData, "authData");
            Validator.AssertMinLength(authData, MinLength, "authData");

            // Input parsing
            using (var stream = new MemoryStream(authData, false))
            {
                using (var reader = new BinaryReader(stream))
                {
                    RpIdHash = reader.ReadBytes(SHA256HashLenBytes);

                    Flags = (AuthenticatorFlags)reader.ReadByte();

                    var signCountBytes = reader.ReadBytes(sizeof(UInt32));
                    if (BitConverter.IsLittleEndian)
                    {
                        // Sign count is provided by the authenticator as big endian, convert if we are on little endian system
                        signCountBytes = signCountBytes.Reverse().ToArray();
                    }
                    SignCount = BitConverter.ToUInt32(signCountBytes, 0);

                    // Attested credential data is only present if the AT flag is set
                    if (Flags.HasFlag(AuthenticatorFlags.AT))
                    {
                        // Decode attested credential data, which starts at the next byte past the minimum length of the structure.
                        AttestedCredentialData = new AttestedCredentialData(reader);
                    }

                    // Extensions data is only present if the ED flag is set
                    if (Flags.HasFlag(AuthenticatorFlags.ED))
                    {
                        // "CBORObject.Read: This method will read from the stream until the end
                        // of the CBOR object is reached or an error occurs, whichever happens first."
                        //
                        // Read the CBOR object from the stream
                        var ext = PeterO.Cbor.CBORObject.Read(reader.BaseStream);

                        // Encode the CBOR object back to a byte array.
                        Extensions = new Extensions(ext.EncodeToBytes());
                    }
                    // There should be no bytes left over after decoding all data from the structure
                    Validator.Equals(stream.Position, stream.Length);
                }
            }
        }