public override void Store(Stream memory, int numberOfRatchetsToStore) { if (memory == null) { throw new ArgumentNullException(nameof(memory)); } byte versionByte = (byte)Version; bool hasInit = NextInitializationNonce != null; bool hasRatchet = Ratchets != null && Ratchets.Count != 0; bool hasEcdh = LocalEcdhRatchetStep0 != null && LocalEcdhRatchetStep1 != null; bool hasClientPublicKey = ClientPublicKey != null; if (hasInit) { versionByte |= 0b0001_0000; } if (hasRatchet) { versionByte |= 0b0010_0000; } if (hasEcdh) { versionByte |= 0b0100_0000; } if (hasClientPublicKey) { versionByte |= 0b1000_0000; } memory.WriteByte(versionByte); if (hasInit) { if (ClientInitializationNonce != null && ClientInitializationNonce.Length != MicroRatchetContext.InitializationNonceSize) { throw new InvalidOperationException($"ClientInitializationNonce must be {MicroRatchetContext.InitializationNonceSize} bytes"); } if (RootKey != null && RootKey.Length != KeySizeInBytes) { throw new InvalidOperationException($"RootKey must be {KeySizeInBytes} bytes"); } if (FirstSendHeaderKey != null && FirstSendHeaderKey.Length != KeySizeInBytes) { throw new InvalidOperationException($"FirstSendHeaderKey must be {KeySizeInBytes} bytes"); } if (FirstReceiveHeaderKey != null && FirstReceiveHeaderKey.Length != KeySizeInBytes) { throw new InvalidOperationException($"FirstReceiveHeaderKey must be {KeySizeInBytes} bytes"); } if (NextInitializationNonce != null && NextInitializationNonce.Length != MicroRatchetContext.InitializationNonceSize) { throw new InvalidOperationException($"NextInitializationNonce must be {MicroRatchetContext.InitializationNonceSize} bytes"); } if (ClientInitializationNonce != null) { memory.Write(ClientInitializationNonce, 0, MicroRatchetContext.InitializationNonceSize); } else { memory.Seek(MicroRatchetContext.InitializationNonceSize, SeekOrigin.Current); } if (RootKey != null) { memory.Write(RootKey, 0, KeySizeInBytes); } else { memory.Seek(KeySizeInBytes, SeekOrigin.Current); } if (FirstSendHeaderKey != null) { memory.Write(FirstSendHeaderKey, 0, KeySizeInBytes); } else { memory.Seek(KeySizeInBytes, SeekOrigin.Current); } if (FirstReceiveHeaderKey != null) { memory.Write(FirstReceiveHeaderKey, 0, KeySizeInBytes); } else { memory.Seek(KeySizeInBytes, SeekOrigin.Current); } if (NextInitializationNonce != null) { memory.Write(NextInitializationNonce, 0, MicroRatchetContext.InitializationNonceSize); } else { memory.Seek(MicroRatchetContext.InitializationNonceSize, SeekOrigin.Current); } } if (hasEcdh) { LocalEcdhRatchetStep0.Serialize(memory); LocalEcdhRatchetStep1.Serialize(memory); } if (hasClientPublicKey) { if (ClientPublicKey.Length != 32) { throw new InvalidOperationException("Client public key must be 32 bytes"); } memory.Write(ClientPublicKey, 0, 32); } if (hasRatchet) { WriteRatchet(memory, numberOfRatchetsToStore); } Log.Verbose($"Wrote {memory.Position} bytes of server state"); }
public override void Store(Stream memory, int numberOfRatchetsToStore) { if (memory == null) { throw new ArgumentNullException(nameof(memory)); } byte versionByte = (byte)Version; bool hasInit = InitializationNonce != null; bool hasRatchet = Ratchets != null && Ratchets.Count != 0; bool hasEcdh = LocalEcdhForInit != null; bool hasServerPubkey = ServerPublicKey != null; versionByte |= 0b0000_1000; // client bit if (hasInit) { versionByte |= 0b0001_0000; } if (hasRatchet) { versionByte |= 0b0010_0000; } if (hasEcdh) { versionByte |= 0b0100_0000; } if (hasServerPubkey) { versionByte |= 0b1000_0000; } memory.WriteByte(versionByte); if (hasInit) { if (InitializationNonce.Length != MicroRatchetContext.InitializationNonceSize) { throw new InvalidOperationException($"InitializationNonce must be {MicroRatchetContext.InitializationNonceSize} bytes"); } memory.Write(InitializationNonce, 0, MicroRatchetContext.InitializationNonceSize); } if (hasEcdh) { LocalEcdhForInit.Serialize(memory); } if (hasServerPubkey) { if (ServerPublicKey.Length != MicroRatchetContext.ExpectedPublicKeySize) { throw new InvalidOperationException($"ServerPublicKey must be {MicroRatchetContext.ExpectedPublicKeySize} bytes"); } memory.Write(ServerPublicKey, 0, MicroRatchetContext.ExpectedPublicKeySize); } if (hasRatchet) { WriteRatchet(memory, numberOfRatchetsToStore); } Log.Verbose($"Wrote {memory.Position} bytes of client state"); }