public static NatBehaviourModel Decode(BinaryReader reader) { var r = new NatBehaviourModel(); var flags0 = reader.ReadByte(); if ((flags0 & Flags0Mask_MustBeZero) != 0) { throw new NotImplementedException(); } var flags1 = reader.ReadByte(); if ((flags1 & StaticIp_LongTerm_Flags1Mask) != 0) { r.StaticIp_LongTerm = true; } if ((flags1 & PortsMappingIsStatic_LongTerm_Flags1Mask) != 0) { r.PortsMappingIsStatic_LongTerm = true; } if ((flags1 & UpnpWorks_Flags1Mask) != 0) { r.UpnpWorks = true; } if ((flags1 & PortsMappingIsStatic_ShortTerm_Flags1Mask) != 0) { r.PortsMappingIsStatic_ShortTerm = true; } if ((flags1 & IsAccessibleFromNewUnknownRequesterIp_Flags1Mask) != 0) { r.IsAccessibleFromNewUnknownRequesterIp = true; } if ((flags1 & NewUnknownRequesterBeforeLocalRequestIsBanned_Flags1Mask) != 0) { r.NewUnknownRequesterBeforeLocalRequestIsBanned = true; } if ((flags1 & IsAccessibleOnlyAfterLocalRequest_Flags1Mask) != 0) { r.IsAccessibleOnlyAfterLocalRequest = true; } if ((flags1 & PublicIpIsAccessibleFromSameIp_Flags1Mask) != 0) { r.PublicIpIsAccessibleFromSameIp = true; } return(r); }
/// <summary> /// initializes parameters to transmit direct (p2p) packets form requester A to neighbor N /// </summary> public void Decrypt_ack1_ToResponderTxParametersEncrypted_AtRequester_DeriveSharedDhSecret(Logger logger, RegisterRequestPacket req, RegisterAck1Packet ack1) { SharedDhSecret = _engine.CryptoLibrary.DeriveEcdh25519SharedSecret(LocalEcdhe25519PrivateKey, ack1.ResponderEcdhePublicKey.Ecdh25519PublicKey); #region iv, key BinaryProcedures.CreateBinaryWriter(out var ms, out var writer); req.GetSharedSignedFields(writer, true); ack1.GetSharedSignedFields(writer, false, false); var iv = _engine.CryptoLibrary.GetHashSHA256(ms.ToArray()).Take(16).ToArray(); ms.Write(SharedDhSecret, 0, SharedDhSecret.Length); var aesKey = _engine.CryptoLibrary.GetHashSHA256(ms.ToArray()); // here SHA256 is used as KDF, together with common fields from packets, including both ECDH public keys and timestamp #endregion var toNeighborTxParametersDecrypted = new byte[ack1.ToResponderTxParametersEncrypted.Length]; _engine.CryptoLibrary.ProcessAesCbcBlocks(false, aesKey, iv, ack1.ToResponderTxParametersEncrypted, toNeighborTxParametersDecrypted); // parse toNeighborTxParametersDecrypted using (var reader = new BinaryReader(new MemoryStream(toNeighborTxParametersDecrypted))) { RemoteEndpoint = BinaryProcedures.DecodeIPEndPoint(reader); RemoteNeighborToken32 = NeighborToken32.Decode(reader); RemoteNatBehaviour = NatBehaviourModel.Decode(reader); var magic16 = reader.ReadUInt16(); if (magic16 != Magic16_responderToRequester) { throw new BrokenCipherException(); } } if (logger.WriteToLog_detail_enabled) { if (logger.WriteToLog_detail_enabled) { logger.WriteToLog_detail($"decrypted remote responder endpoint={RemoteEndpoint}, remoteNeighborToken={RemoteNeighborToken32} from ACK1"); } } }