private static FidoRegistrationData FromStream(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } using (var binaryReader = new BinaryReader(stream)) { var reservedByte = binaryReader.ReadByte(); if (reservedByte != RegistrationReservedByte) { throw new InvalidOperationException(String.Format( "Incorrect value of reserved byte (expected: 0x{0:X2} but was: 0x{1:X1})", RegistrationReservedByte, reservedByte)); } try { var publicKeyBytes = binaryReader.ReadBytes(65); var keyHandleLength = binaryReader.ReadByte(); var keyHandleBytes = binaryReader.ReadBytes(keyHandleLength); var nextChunkSize = (int)(binaryReader.BaseStream.Length - binaryReader.BaseStream.Position); var certificatePosition = binaryReader.BaseStream.Position; var certBytes = binaryReader.ReadBytes(nextChunkSize); var certificate = new FidoAttestationCertificate(certBytes); var certSize = certificate.Certificate.GetEncoded().Length; binaryReader.BaseStream.Position = certificatePosition + certSize; nextChunkSize = (int)(binaryReader.BaseStream.Length - binaryReader.BaseStream.Position); var signatureBytes = binaryReader.ReadBytes(nextChunkSize); var registerResponse = new FidoRegistrationData( new FidoPublicKey(publicKeyBytes), new FidoKeyHandle(keyHandleBytes), certificate, new FidoSignature(signatureBytes)); return(registerResponse); } catch (Exception ex) { var message = String.Format("Error parsing registration data ({0})", ex.Message); throw new InvalidOperationException(message, ex); } } }
private static FidoRegistrationData FromStream(Stream stream) { if (stream == null) throw new ArgumentNullException("stream"); using (var binaryReader = new BinaryReader(stream)) { var reservedByte = binaryReader.ReadByte(); if (reservedByte != RegistrationReservedByte) { throw new InvalidOperationException(String.Format( "Incorrect value of reserved byte (expected: 0x{0:X2} but was: 0x{1:X1})", RegistrationReservedByte, reservedByte)); } try { var publicKeyBytes = binaryReader.ReadBytes(65); var keyHandleLength = binaryReader.ReadByte(); var keyHandleBytes = binaryReader.ReadBytes(keyHandleLength); var nextChunkSize = (int)(binaryReader.BaseStream.Length - binaryReader.BaseStream.Position); var certificatePosition = binaryReader.BaseStream.Position; var certBytes = binaryReader.ReadBytes(nextChunkSize); var certificate = new FidoAttestationCertificate(certBytes); var certSize = certificate.Certificate.GetEncoded().Length; binaryReader.BaseStream.Position = certificatePosition + certSize; nextChunkSize = (int)(binaryReader.BaseStream.Length - binaryReader.BaseStream.Position); var signatureBytes = binaryReader.ReadBytes(nextChunkSize); var registerResponse = new FidoRegistrationData( new FidoPublicKey(publicKeyBytes), new FidoKeyHandle(keyHandleBytes), certificate, new FidoSignature(signatureBytes)); return registerResponse; } catch (Exception ex) { var message = String.Format("Error parsing registration data ({0})", ex.Message); throw new InvalidOperationException(message, ex); } } }
private void VerifyResponseSignature(FidoAppId appId, FidoRegistrationData registrationData, FidoClientData clientData) { if (appId == null) throw new ArgumentNullException("appId"); if (registrationData == null) throw new ArgumentNullException("registrationData"); if (clientData == null) throw new ArgumentNullException("clientData"); if (String.IsNullOrEmpty(clientData.RawJsonValue)) throw new InvalidOperationException("Client data has no JSON representation"); var signedBytes = PackBytes( new byte[] { 0 }, Helpers.Sha256(appId.ToString()), Helpers.Sha256(clientData.RawJsonValue), registrationData.KeyHandle.ToByteArray(), registrationData.UserPublicKey.ToByteArray()); VerifySignature(registrationData.AttestationCertificate, registrationData.Signature, signedBytes); }