Esempio n. 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Protocol"/> class.
        /// </summary>
        /// <param name="handshakePattern">The handshake pattern (e.q. NX or IK).</param>
        /// <param name="cipher">The cipher function (AESGCM or ChaChaPoly).</param>
        /// <param name="hash">The hash function (SHA256, SHA512, BLAKE2s, or BLAKE2b).</param>
        /// <param name="modifiers">The combination of pattern modifiers (e.q. empty, psk0, or psk1+psk2).</param>
        /// <exception cref="ArgumentNullException">
        /// Thrown if the either <paramref name="handshakePattern"/>,
        /// <paramref name="cipher"/>, or <paramref name="hash"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Thrown if <paramref name="modifiers"/> does not represent a valid combination of pattern modifiers.
        /// </exception>
        public Protocol(
            HandshakePattern handshakePattern,
            CipherFunction cipher,
            HashFunction hash,
            PatternModifiers modifiers = PatternModifiers.None)
        {
            Exceptions.ThrowIfNull(handshakePattern, nameof(handshakePattern));
            Exceptions.ThrowIfNull(cipher, nameof(cipher));
            Exceptions.ThrowIfNull(hash, nameof(hash));

            HandshakePattern = handshakePattern;
            Cipher           = cipher;
            Dh        = DhFunction.Curve25519;
            Hash      = hash;
            Modifiers = modifiers;

            Name = GetName();
        }
Esempio n. 2
0
        /// <summary>
        /// Converts the Noise protocol name to its <see cref="Protocol"/> equivalent.
        /// </summary>
        /// <param name="s">The Noise protocol name (e.q. Noise_KNpsk2_25519_ChaChaPoly_SHA512).</param>
        /// <returns>
        /// An object that is equivalent to the Noise
        /// protocol name contained in <paramref name="s"/>.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// Thrown if <paramref name="s"/> is not a valid Noise protocol name.
        /// </exception>
        public static Protocol Parse(ReadOnlySpan <char> s)
        {
            if (s.Length < MinProtocolNameLength || s.Length > MaxProtocolNameLength)
            {
                throw new ArgumentException("Invalid Noise protocol name.", nameof(s));
            }

            var splitter = new StringSplitter(s, '_');
            var noise    = splitter.Next();

            if (!noise.SequenceEqual("Noise".AsSpan()))
            {
                throw new ArgumentException("Invalid Noise protocol name.", nameof(s));
            }

            var next    = splitter.Next();
            var pattern = next.Length > 1 && Char.IsUpper(next[1]) ? next.Slice(0, 2) : next.Slice(0, 1);

            var handshakePattern = ParseHandshakePattern(pattern);
            var modifiers        = ParseModifiers(next.Slice(pattern.Length));

            var dh = DhFunction.Parse(splitter.Next());

            Debug.Assert(dh == DhFunction.Curve25519);

            var cipher = CipherFunction.Parse(splitter.Next());
            var hash   = HashFunction.Parse(splitter.Next());

            if (!splitter.Next().IsEmpty)
            {
                throw new ArgumentException("Invalid Noise protocol name.", nameof(s));
            }

            var protocol = new Protocol(handshakePattern, cipher, hash, modifiers);

            ValidateProtocolName(s, protocol);

            return(protocol);
        }