/// <summary> /// Computes the client response containing the client's public key and /// evidence. /// </summary> /// <param name="challenge">The challenge containing the protocol elements /// received from the server in response to the initial client /// response.</param> /// <returns>An array of bytes containing the client's challenge /// response.</returns> /// <exception cref="SaslException">Thrown if the server specified any /// mandatory options which are not supported.</exception> private byte[] ComputeFinalResponse(byte[] challenge) { ServerMessage1 m = ServerMessage1.Deserialize(challenge); // We don't support integrity protection or confidentiality. if (!String.IsNullOrEmpty(m.Options["mandatory"])) { throw new SaslException("Mandatory options are not supported."); } // Set up the message digest algorithm. var mda = SelectHashAlgorithm(m.Options["mda"]); HashAlgorithm = Activator.CreateInstance(mda.Item2) as HashAlgorithm; // Compute public and private key. PublicKey = Helper.ComputeClientPublicKey(m.Generator, m.SafePrimeModulus, PrivateKey); // Compute the shared key and client evidence. SharedKey = Helper.ComputeSharedKey(m.Salt, Username, Password, PublicKey, m.PublicKey, PrivateKey, m.Generator, m.SafePrimeModulus, HashAlgorithm); ClientProof = Helper.ComputeClientProof(m.SafePrimeModulus, m.Generator, Username, m.Salt, PublicKey, m.PublicKey, SharedKey, AuthId, m.RawOptions, HashAlgorithm); ClientMessage2 response = new ClientMessage2(PublicKey, ClientProof); // Let the server know which hash algorithm we are using. response.Options["mda"] = mda.Item1; // Remember the raw options string because we'll need it again // when verifying the server signature. Options = response.BuildOptionsString(); return(response.Serialize()); }
public void SerializeClientSecondMessage() { BigInteger key = BigInteger.Parse(clientPublicKey, NumberStyles.HexNumber); Mpi _publicKey = new Mpi(key); ClientMessage2 m = new ClientMessage2(_publicKey, clientProof); m.InitialVector = clientInitialVector; foreach (KeyValuePair <string, string> p in clientOptions) { m.Options.Add(p.Key, p.Value); } byte[] serialized = m.Serialize(); Assert.IsTrue(serialized.SequenceEqual(expectedClientMessage2)); }