123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
- namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.Srp
- {
- /**
- * Implements the server side SRP-6a protocol. Note that this class is stateful, and therefore NOT threadsafe.
- * This implementation of SRP is based on the optimized message sequence put forth by Thomas Wu in the paper
- * "SRP-6: Improvements and Refinements to the Secure Remote Password Protocol, 2002"
- */
- public class Srp6Server
- {
- protected BigInteger N;
- protected BigInteger g;
- protected BigInteger v;
- protected SecureRandom random;
- protected IDigest digest;
- protected BigInteger A;
- protected BigInteger privB;
- protected BigInteger pubB;
- protected BigInteger u;
- protected BigInteger S;
- protected BigInteger M1;
- protected BigInteger M2;
- protected BigInteger Key;
- public Srp6Server()
- {
- }
- /**
- * Initialises the server to accept a new client authentication attempt
- * @param N The safe prime associated with the client's verifier
- * @param g The group parameter associated with the client's verifier
- * @param v The client's verifier
- * @param digest The digest algorithm associated with the client's verifier
- * @param random For key generation
- */
- public virtual void Init(BigInteger N, BigInteger g, BigInteger v, IDigest digest, SecureRandom random)
- {
- this.N = N;
- this.g = g;
- this.v = v;
- this.random = random;
- this.digest = digest;
- }
- public virtual void Init(Srp6GroupParameters group, BigInteger v, IDigest digest, SecureRandom random)
- {
- Init(group.N, group.G, v, digest, random);
- }
- /**
- * Generates the server's credentials that are to be sent to the client.
- * @return The server's public value to the client
- */
- public virtual BigInteger GenerateServerCredentials()
- {
- BigInteger k = Srp6Utilities.CalculateK(digest, N, g);
- this.privB = SelectPrivateValue();
- this.pubB = k.Multiply(v).Mod(N).Add(g.ModPow(privB, N)).Mod(N);
- return pubB;
- }
- /**
- * Processes the client's credentials. If valid the shared secret is generated and returned.
- * @param clientA The client's credentials
- * @return A shared secret BigInteger
- * @throws CryptoException If client's credentials are invalid
- */
- public virtual BigInteger CalculateSecret(BigInteger clientA)
- {
- this.A = Srp6Utilities.ValidatePublicValue(N, clientA);
- this.u = Srp6Utilities.CalculateU(digest, N, A, pubB);
- this.S = CalculateS();
- return S;
- }
- protected virtual BigInteger SelectPrivateValue()
- {
- return Srp6Utilities.GeneratePrivateValue(digest, N, g, random);
- }
- private BigInteger CalculateS()
- {
- return v.ModPow(u, N).Multiply(A).Mod(N).ModPow(privB, N);
- }
- /**
- * Authenticates the received client evidence message M1 and saves it only if correct.
- * To be called after calculating the secret S.
- * @param M1: the client side generated evidence message
- * @return A boolean indicating if the client message M1 was the expected one.
- * @throws CryptoException
- */
- public virtual bool VerifyClientEvidenceMessage(BigInteger clientM1)
- {
- // Verify pre-requirements
- if (this.A == null || this.pubB == null || this.S == null)
- {
- throw new CryptoException("Impossible to compute and verify M1: " +
- "some data are missing from the previous operations (A,B,S)");
- }
- // Compute the own client evidence message 'M1'
- BigInteger computedM1 = Srp6Utilities.CalculateM1(digest, N, A, pubB, S);
- if (computedM1.Equals(clientM1))
- {
- this.M1 = clientM1;
- return true;
- }
- return false;
- }
- /**
- * Computes the server evidence message M2 using the previously verified values.
- * To be called after successfully verifying the client evidence message M1.
- * @return M2: the server side generated evidence message
- * @throws CryptoException
- */
- public virtual BigInteger CalculateServerEvidenceMessage()
- {
- // Verify pre-requirements
- if (this.A == null || this.M1 == null || this.S == null)
- {
- throw new CryptoException("Impossible to compute M2: " +
- "some data are missing from the previous operations (A,M1,S)");
- }
- // Compute the server evidence message 'M2'
- this.M2 = Srp6Utilities.CalculateM2(digest, N, A, M1, S);
- return M2;
- }
- /**
- * Computes the final session key as a result of the SRP successful mutual authentication
- * To be called after calculating the server evidence message M2.
- * @return Key: the mutual authenticated symmetric session key
- * @throws CryptoException
- */
- public virtual BigInteger CalculateSessionKey()
- {
- // Verify pre-requirements
- if (this.S == null || this.M1 == null || this.M2 == null)
- {
- throw new CryptoException("Impossible to compute Key: " +
- "some data are missing from the previous operations (S,M1,M2)");
- }
- this.Key = Srp6Utilities.CalculateKey(digest, N, S);
- return Key;
- }
- }
- }
- #pragma warning restore
- #endif
|