コード例 #1
0
        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();
        }
コード例 #2
0
        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);
                }
            }
        }
コード例 #3
0
 public SecureChannelHandshakeHello(SecureChannelCipherSuite supportedCiphers, SecureChannelOptions options)
     : base(SecureChannelCode.None)
 {
     _version          = 1;
     _nonce            = BinaryNumber.GenerateRandomNumber256();
     _supportedCiphers = supportedCiphers;
     _options          = options;
 }
コード例 #4
0
        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);
        }
コード例 #5
0
        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;
            }
        }
コード例 #6
0
        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
        }
コード例 #7
0
        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.");
            }
        }