public MeshNode(MeshNodeType type, byte[] privateKey, SecureChannelCipherSuite supportedCiphers, ushort localServicePort, string profileDisplayName, string profileFolder, string downloadFolder, TorController torController) { _type = type; _privateKey = privateKey; _supportedCiphers = supportedCiphers; _localServicePort = localServicePort; _profileDateModified = DateTime.UtcNow; _profileDisplayName = profileDisplayName; if (_type == MeshNodeType.Anonymous) { _enableUPnP = false; _allowInboundInvitations = true; _allowOnlyLocalInboundInvitations = true; } else { _enableUPnP = true; _allowInboundInvitations = true; _allowOnlyLocalInboundInvitations = false; } _profileFolder = profileFolder; _downloadFolder = downloadFolder; GenerateNewUserId(); //start connection manager _connectionManager = new ConnectionManager(this, torController); InitAnnounceTimer(); }
private BinaryNumber GetPskAuthValue(SecureChannelCipherSuite cipher, byte[] ephemeralPublicKey, byte[] serverNonce, byte[] clientNonce, byte[] psk) { using (MemoryStream mS = new MemoryStream()) { mS.Write(ephemeralPublicKey, 0, ephemeralPublicKey.Length); mS.Write(serverNonce, 0, serverNonce.Length); mS.Write(clientNonce, 0, clientNonce.Length); mS.Position = 0; if (psk == null) { psk = new byte[] { } } ; switch (cipher) { case SecureChannelCipherSuite.DHE2048_ANON_WITH_AES256_CBC_HMAC_SHA256: case SecureChannelCipherSuite.DHE2048_RSA2048_WITH_AES256_CBC_HMAC_SHA256: using (HMAC hmac = new HMACSHA256(psk)) { return(new BinaryNumber(hmac.ComputeHash(mS))); } default: throw new SecureChannelException(SecureChannelCode.NoMatchingCipherAvailable, null, null); } } }
public SecureChannelHandshakeHello(SecureChannelCipherSuite supportedCiphers, SecureChannelOptions options) : base(SecureChannelCode.None) { _version = 1; _nonce = BinaryNumber.GenerateRandomNumber256(); _supportedCiphers = supportedCiphers; _options = options; }
public SecureChannelServerStream(Stream stream, EndPoint remotePeerEP, EndPoint viaRemotePeerEP, int renegotiateAfterBytesSent, int renegotiateAfterSeconds, SecureChannelCipherSuite supportedCiphers, SecureChannelOptions options, byte[] preSharedKey, BinaryNumber userId, byte[] privateKey, IEnumerable <BinaryNumber> trustedUserIds) : base(remotePeerEP, viaRemotePeerEP, renegotiateAfterBytesSent, renegotiateAfterSeconds) { _supportedCiphers = supportedCiphers; _options = options; _preSharedKey = preSharedKey; _userId = userId; _privateKey = privateKey; _trustedUserIds = trustedUserIds; Start(stream); }
public SecureChannelHandshakeHello(Stream s) : base(s) { int version = s.ReadByte(); switch (version) { case -1: throw new EndOfStreamException(); case 1: _version = (byte)version; _nonce = new BinaryNumber(s); _supportedCiphers = (SecureChannelCipherSuite)s.ReadByte(); _options = (SecureChannelOptions)s.ReadByte(); break; default: _version = (byte)version; break; } }
private void ProtocolV1(WriteBufferedStream bufferedStream, SecureChannelHandshakeHello clientHello) { #region 1. hello handshake check //select crypto option SecureChannelCipherSuite availableCiphers = _supportedCiphers & clientHello.SupportedCiphers; if (availableCiphers == SecureChannelCipherSuite.None) { throw new SecureChannelException(SecureChannelCode.NoMatchingCipherAvailable, _remotePeerEP, _remotePeerUserId); } else if (availableCiphers.HasFlag(SecureChannelCipherSuite.DHE2048_RSA2048_WITH_AES256_CBC_HMAC_SHA256)) { _selectedCipher = SecureChannelCipherSuite.DHE2048_RSA2048_WITH_AES256_CBC_HMAC_SHA256; } else if (availableCiphers.HasFlag(SecureChannelCipherSuite.DHE2048_ANON_WITH_AES256_CBC_HMAC_SHA256)) { _selectedCipher = SecureChannelCipherSuite.DHE2048_ANON_WITH_AES256_CBC_HMAC_SHA256; } else { throw new SecureChannelException(SecureChannelCode.NoMatchingCipherAvailable, _remotePeerEP, _remotePeerUserId); } //match options if (_options != clientHello.Options) { throw new SecureChannelException(SecureChannelCode.NoMatchingOptionsAvailable, _remotePeerEP, _remotePeerUserId); } //write server hello SecureChannelHandshakeHello serverHello = new SecureChannelHandshakeHello(_selectedCipher, _options); serverHello.WriteTo(bufferedStream); #endregion #region 2. key exchange KeyAgreement keyAgreement; switch (_selectedCipher) { case SecureChannelCipherSuite.DHE2048_ANON_WITH_AES256_CBC_HMAC_SHA256: case SecureChannelCipherSuite.DHE2048_RSA2048_WITH_AES256_CBC_HMAC_SHA256: keyAgreement = new DiffieHellman(DiffieHellmanGroupType.RFC3526_GROUP14_2048BIT, KeyAgreementKeyDerivationFunction.Hmac, KeyAgreementKeyDerivationHashAlgorithm.SHA256); break; default: throw new SecureChannelException(SecureChannelCode.NoMatchingCipherAvailable, _remotePeerEP, _remotePeerUserId); } //send server key exchange data SecureChannelHandshakeKeyExchange serverKeyExchange = new SecureChannelHandshakeKeyExchange(keyAgreement, serverHello, clientHello, _preSharedKey); serverKeyExchange.WriteTo(bufferedStream); bufferedStream.Flush(); //read client key exchange data SecureChannelHandshakeKeyExchange clientKeyExchange = new SecureChannelHandshakeKeyExchange(bufferedStream); if (_options.HasFlag(SecureChannelOptions.PRE_SHARED_KEY_AUTHENTICATION_REQUIRED)) { if (!clientKeyExchange.IsPskAuthValid(serverHello, clientHello, _preSharedKey)) { throw new SecureChannelException(SecureChannelCode.PskAuthenticationFailed, _remotePeerEP, _remotePeerUserId); } } #endregion #region 3. enable encryption EnableEncryption(bufferedStream, serverHello, clientHello, keyAgreement, clientKeyExchange); #endregion #region 4. UserId based authentication switch (_selectedCipher) { case SecureChannelCipherSuite.DHE2048_RSA2048_WITH_AES256_CBC_HMAC_SHA256: if (_options.HasFlag(SecureChannelOptions.CLIENT_AUTHENTICATION_REQUIRED)) { //read client auth SecureChannelHandshakeAuthentication clientAuth = new SecureChannelHandshakeAuthentication(this); _remotePeerUserId = clientAuth.UserId; //authenticate client if (!clientAuth.IsSignatureValid(clientKeyExchange, serverHello, clientHello)) { throw new SecureChannelException(SecureChannelCode.PeerAuthenticationFailed, _remotePeerEP, _remotePeerUserId); } //check if client is trusted if (!clientAuth.IsTrustedUserId(_trustedUserIds)) { throw new SecureChannelException(SecureChannelCode.UntrustedRemotePeerUserId, _remotePeerEP, _remotePeerUserId); } } //write server auth new SecureChannelHandshakeAuthentication(serverKeyExchange, serverHello, clientHello, _userId, _privateKey).WriteTo(this); this.Flush(); break; case SecureChannelCipherSuite.DHE2048_ANON_WITH_AES256_CBC_HMAC_SHA256: break; //no auth for ANON default: throw new SecureChannelException(SecureChannelCode.NoMatchingCipherAvailable, _remotePeerEP, _remotePeerUserId); } #endregion }
private void InitMeshNode(BinaryReader bR, TorController torController) { switch (bR.ReadByte()) //version { case 1: _type = (MeshNodeType)bR.ReadByte(); _privateKey = bR.ReadBuffer(); _supportedCiphers = (SecureChannelCipherSuite)bR.ReadByte(); // _userId = new BinaryNumber(bR.BaseStream); // _localServicePort = bR.ReadUInt16(); _downloadFolder = bR.ReadShortString(); // _profileDateModified = bR.ReadDate(); _profileDisplayName = bR.ReadShortString(); _profileStatus = (MeshProfileStatus)bR.ReadByte(); _profileStatusMessage = bR.ReadShortString(); // _profileImageDateModified = bR.ReadDate(); _profileDisplayImage = bR.ReadBuffer(); // _ipv4BootstrapDhtNodes = new EndPoint[bR.ReadInt32()]; for (int i = 0; i < _ipv4BootstrapDhtNodes.Length; i++) { _ipv4BootstrapDhtNodes[i] = EndPointExtension.Parse(bR); } _ipv6BootstrapDhtNodes = new EndPoint[bR.ReadInt32()]; for (int i = 0; i < _ipv6BootstrapDhtNodes.Length; i++) { _ipv6BootstrapDhtNodes[i] = EndPointExtension.Parse(bR); } _torBootstrapDhtNodes = new EndPoint[bR.ReadInt32()]; for (int i = 0; i < _torBootstrapDhtNodes.Length; i++) { _torBootstrapDhtNodes[i] = EndPointExtension.Parse(bR); } // _enableUPnP = bR.ReadBoolean(); _allowInboundInvitations = bR.ReadBoolean(); _allowOnlyLocalInboundInvitations = bR.ReadBoolean(); // if (bR.ReadBoolean()) { _proxy = new NetProxy((NetProxyType)bR.ReadByte(), bR.ReadShortString(), bR.ReadUInt16(), (bR.ReadBoolean() ? new NetworkCredential(bR.ReadShortString(), bR.ReadShortString()) : null)); } // _appData = bR.ReadBuffer(); //start connection manager _connectionManager = new ConnectionManager(this, torController); // int networkCount = bR.ReadInt32(); for (int i = 0; i < networkCount; i++) { MeshNetwork network = new MeshNetwork(_connectionManager, bR); _networks.Add(network.NetworkId, network); } InitAnnounceTimer(); break; default: throw new InvalidDataException("MeshNode format version not supported."); } }