string SRPProofToServer(KPRPCMessage srpem) { SRPParams srp = srpem.srp; KPRPCMessage data2client = new KPRPCMessage(); data2client.protocol = "setup"; data2client.srp = new SRPParams(); data2client.srp.stage = "proofToClient"; data2client.version = ProtocolVersion; if (string.IsNullOrEmpty(srp.M)) { data2client.error = new Error(ErrorCode.AUTH_MISSING_PARAM, new string[] { "M" }); } else { _srp.Authenticate(srp.M); if (!_srp.Authenticated) { data2client.error = new Error(ErrorCode.AUTH_FAILED, new string[] { "Keys do not match" }); } else { data2client.srp.M2 = _srp.M2; data2client.srp.securityLevel = securityLevel; KeyContainer = new KeyContainerClass(_srp.Key, DateTime.UtcNow.AddSeconds(KeyExpirySeconds), userName, clientName); Authorised = true; // We assume the user has checked the client name as part of the initial SRP setup so it's fairly safe to use it to determine the type of client connection to which we want to promote our null connection KPRPC.PromoteNullRPCClient(this, clientName); KPRPC.InvokeMainThread(new HideAuthDialogDelegate(HideAuthDialog)); // If we've never shown the user the welcome screen and have never // known a KeeFox add-on from the previous KPRPC protocol, show it now bool welcomeDisplayed = KPRPC._host.CustomConfig.GetBool("KeePassRPC.KeeFoxWelcomeDisplayed", false); if (!welcomeDisplayed && string.IsNullOrEmpty(KPRPC._host.CustomConfig.GetString("KeePassRPC.knownClients.KeeFox Firefox add-on"))) { KPRPC.InvokeMainThread(new KeePassRPCExt.WelcomeKeeFoxUserDelegate(KPRPC.WelcomeKeeFoxUser)); } if (!welcomeDisplayed) { KPRPC._host.CustomConfig.SetBool("KeePassRPC.KeeFoxWelcomeDisplayed", true); } } } return(Jayrock.Json.Conversion.JsonConvert.ExportToString(data2client)); }
string SRPIdentifyToServer(KPRPCMessage srpem) { SRPParams srp = srpem.srp; Error error; KPRPCMessage data2client = new KPRPCMessage(); data2client.protocol = "setup"; data2client.srp = new SRPParams(); data2client.srp.stage = "identifyToClient"; data2client.version = ProtocolVersion; // Generate a new random password // SRP isn't very susceptible to brute force attacks but we get 32 bits worth of randomness just in case byte[] password = Utils.GetRandomBytes(4); string plainTextPassword = Utils.GetTypeablePassword(password); // caclulate the hash of our randomly generated password _srp.CalculatePasswordHash(plainTextPassword); if (string.IsNullOrEmpty(srp.I)) { data2client.error = new Error(ErrorCode.AUTH_MISSING_PARAM, new string[] { "I" }); } else if (string.IsNullOrEmpty(srp.A)) { data2client.error = new Error(ErrorCode.AUTH_MISSING_PARAM, new string[] { "A" }); } else { // Init relevant SRP protocol variables _srp.Setup(); // Begin the SRP handshake error = _srp.Handshake(srp.I, srp.A); if (error.code > 0) { data2client.error = error; } else { // store the username and client name for future reference userName = _srp.I; clientName = srpem.clientDisplayName; data2client.srp.s = _srp.s; data2client.srp.B = _srp.Bstr; data2client.srp.securityLevel = securityLevel; //pass the params through to the main kprpcext thread via begininvoke - that function will then create and show the form as a modal dialog string secLevel = "low"; if (srp.securityLevel == 2) { secLevel = "medium"; } else if (srp.securityLevel == 3) { secLevel = "high"; } KPRPC.InvokeMainThread(new ShowAuthDialogDelegate(ShowAuthDialog), secLevel, srpem.clientDisplayName, srpem.clientDisplayDescription, plainTextPassword); } } return(Jayrock.Json.Conversion.JsonConvert.ExportToString(data2client)); }