/// <summary> /// Decodes attested credential data. /// </summary> public AttestedCredentialData(BinaryReader reader) { if (reader.BaseStream.Length < _minLength) { throw new Fido2VerificationException("Not enough bytes to be a valid AttestedCredentialData"); } // First 16 bytes is AAGUID var aaguidBytes = reader.ReadBytes(Marshal.SizeOf(typeof(Guid))); if (BitConverter.IsLittleEndian) { // GUID from authenticator is big endian. If we are on a little endian system, convert. AaGuid = FromBigEndian(aaguidBytes); } else { AaGuid = new Guid(aaguidBytes); } // Byte length of Credential ID, 16-bit unsigned big-endian integer. var credentialIDLenBytes = reader.ReadBytes(sizeof(ushort)); if (BitConverter.IsLittleEndian) { // Credential ID length from authenticator is big endian. If we are on little endian system, convert. Array.Reverse(credentialIDLenBytes); } // Convert the read bytes to uint16 so we know how many bytes to read for the credential ID var credentialIDLen = BitConverter.ToUInt16(credentialIDLenBytes, 0); // Read the credential ID bytes CredentialID = reader.ReadBytes(credentialIDLen); // "Determining attested credential data's length, which is variable, involves determining // credentialPublicKey's beginning location given the preceding credentialId's length, and // then determining the credentialPublicKey's length" // Read the CBOR object from the stream CredentialPublicKey = new CredentialPublicKey(reader.BaseStream); }
/// <summary> /// Instantiates an AttestedCredentialData object from an aaguid, credentialID, and CredentialPublicKey /// </summary> /// <param name="aaguid"></param> /// <param name="credentialID"></param> /// <param name="cpk"></param> public AttestedCredentialData(Guid aaguid, byte[] credentialID, CredentialPublicKey cpk) { AaGuid = aaguid; CredentialID = credentialID; CredentialPublicKey = cpk; }