public AuthenticatorData(byte[] rpIdHash, AuthenticatorFlags flags, uint signCount, AttestedCredentialData acd, Extensions exts) { RpIdHash = rpIdHash; _flags = flags; SignCount = signCount; AttestedCredentialData = acd; Extensions = exts; }
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); } } }