示例#1
0
        private void ProcessPreMessages(HandshakePattern handshakePattern)
        {
            foreach (var token in handshakePattern.Initiator.Tokens)
            {
                if (token == Token.S)
                {
                    state.MixHash(role == Role.Alice ? s.PublicKey : rs);
                }
            }

            foreach (var token in handshakePattern.Responder.Tokens)
            {
                if (token == Token.S)
                {
                    state.MixHash(role == Role.Alice ? rs : s.PublicKey);
                }
            }
        }
示例#2
0
        private void ProcessPreMessages(HandshakePattern handshakePattern)
        {
            foreach (var preMessage in handshakePattern.Initiator.Tokens)
            {
                if (preMessage == Token.S)
                {
                    state.MixHash(initiator ? this.s.PublicKey : rs);
                }
            }

            foreach (var preMessage in handshakePattern.Responder.Tokens)
            {
                if (preMessage == Token.S)
                {
                    state.MixHash(initiator ? rs : this.s.PublicKey);
                }
            }
        }
示例#3
0
        public HandshakeState(
            Protocol protocol,
            bool initiator,
            ReadOnlySpan <byte> prologue,
            ReadOnlySpan <byte> s,
            ReadOnlySpan <byte> rs,
            IEnumerable <byte[]> psks)
        {
            Debug.Assert(psks != null);

            if (!s.IsEmpty && s.Length != dh.DhLen)
            {
                throw new ArgumentException("Invalid local static private key.", nameof(s));
            }

            if (!rs.IsEmpty && rs.Length != dh.DhLen)
            {
                throw new ArgumentException("Invalid remote static public key.", nameof(rs));
            }

            if (s.IsEmpty && protocol.HandshakePattern.LocalStaticRequired(initiator))
            {
                throw new ArgumentException("Local static private key required, but not provided.", nameof(s));
            }

            if (!s.IsEmpty && !protocol.HandshakePattern.LocalStaticRequired(initiator))
            {
                throw new ArgumentException("Local static private key provided, but not required.", nameof(s));
            }

            if (rs.IsEmpty && protocol.HandshakePattern.RemoteStaticRequired(initiator))
            {
                throw new ArgumentException("Remote static public key required, but not provided.", nameof(rs));
            }

            if (!rs.IsEmpty && !protocol.HandshakePattern.RemoteStaticRequired(initiator))
            {
                throw new ArgumentException("Remote static public key provided, but not required.", nameof(rs));
            }

            state = new SymmetricState <CipherType, DhType, HashType>(protocol.Name);
            state.MixHash(prologue);

            this.initiator   = initiator;
            this.turnToWrite = initiator;
            this.s           = s.IsEmpty ? null : dh.GenerateKeyPair(s);
            this.rs          = rs.IsEmpty ? null : rs.ToArray();

            ProcessPreMessages(protocol.HandshakePattern);
            ProcessPreSharedKeys(protocol, psks);

            isOneWay = messagePatterns.Count == 1;
            isPsk    = protocol.Modifiers != PatternModifiers.None;
        }
示例#4
0
        public void Fallback(Protocol protocol, ProtocolConfig config)
        {
            ThrowIfDisposed();
            Exceptions.ThrowIfNull(protocol, nameof(protocol));
            Exceptions.ThrowIfNull(config, nameof(config));

            if (protocol.HandshakePattern != HandshakePattern.XX || protocol.Modifiers != PatternModifiers.Fallback)
            {
                throw new ArgumentException("The only fallback pattern currently supported is XXfallback.");
            }

            if (config.LocalStatic == null)
            {
                throw new ArgumentException("Local static private key is required for the XXfallback pattern.");
            }

            if (initiator == Role.Bob)
            {
                throw new InvalidOperationException("Fallback cannot be applied to a Bob-initiated pattern.");
            }

            if (messagePatterns.Count + 1 != this.protocol.HandshakePattern.Patterns.Count())
            {
                throw new InvalidOperationException("Fallback can only be applied after the first handshake message.");
            }

            this.protocol = null;
            initiator     = Role.Bob;
            turnToWrite   = role == Role.Bob;

            s  = dh.GenerateKeyPair(config.LocalStatic);
            rs = null;

            isPsk    = false;
            isOneWay = false;

            while (psks.Count > 0)
            {
                var psk = psks.Dequeue();
                Utilities.ZeroMemory(psk);
            }

            state.Dispose();
            state = new SymmetricState <CipherType, DhType, HashType>(protocol.Name);
            state.MixHash(config.Prologue);

            if (role == Role.Alice)
            {
                Debug.Assert(e != null && re == null);
                state.MixHash(e.PublicKey);
            }
            else
            {
                Debug.Assert(e == null && re != null);
                state.MixHash(re);
            }

            messagePatterns.Clear();

            foreach (var pattern in protocol.HandshakePattern.Patterns.Skip(1))
            {
                messagePatterns.Enqueue(pattern);
            }
        }
示例#5
0
        public HandshakeState(
            Protocol protocol,
            bool initiator,
            ReadOnlySpan <byte> prologue,
            ReadOnlySpan <byte> s,
            ReadOnlySpan <byte> rs,
            IEnumerable <byte[]> psks)
        {
            Debug.Assert(psks != null);

            if (!s.IsEmpty && s.Length != dh.DhLen)
            {
                throw new ArgumentException("Invalid local static private key.", nameof(s));
            }

            if (!rs.IsEmpty && rs.Length != dh.DhLen)
            {
                throw new ArgumentException("Invalid remote static public key.", nameof(rs));
            }

            if (s.IsEmpty && protocol.HandshakePattern.LocalStaticRequired(initiator))
            {
                throw new ArgumentException("Local static private key required, but not provided.", nameof(s));
            }

            if (!s.IsEmpty && !protocol.HandshakePattern.LocalStaticRequired(initiator))
            {
                throw new ArgumentException("Local static private key provided, but not required.", nameof(s));
            }

            if (rs.IsEmpty && protocol.HandshakePattern.RemoteStaticRequired(initiator))
            {
                throw new ArgumentException("Remote static public key required, but not provided.", nameof(rs));
            }

            if (!rs.IsEmpty && !protocol.HandshakePattern.RemoteStaticRequired(initiator))
            {
                throw new ArgumentException("Remote static public key provided, but not required.", nameof(rs));
            }

            if ((protocol.Modifiers & PatternModifiers.Fallback) != 0)
            {
                throw new ArgumentException($"Fallback modifier can only be applied by calling the {nameof(Fallback)} method.");
            }

            state = new SymmetricState <CipherType, DhType, HashType>(protocol.Name);
            state.MixHash(prologue);

            this.protocol    = protocol;
            this.role        = initiator ? Role.Alice : Role.Bob;
            this.initiator   = Role.Alice;
            this.turnToWrite = initiator;
            this.s           = s.IsEmpty ? null : dh.GenerateKeyPair(s);
            this.rs          = rs.IsEmpty ? null : rs.ToArray();

            ProcessPreMessages(protocol.HandshakePattern);
            ProcessPreSharedKeys(protocol, psks);

            var pskModifiers = PatternModifiers.Psk0 | PatternModifiers.Psk1 | PatternModifiers.Psk2 | PatternModifiers.Psk3;

            isPsk    = (protocol.Modifiers & pskModifiers) != 0;
            isOneWay = messagePatterns.Count == 1;
        }