示例#1
0
 private bool ResyncCheck(ref Device devices, string[] codes, long counter)
 {
     for (int i = 0; i < codes.Length; i++)
     {
         string code = Generate(Decrypt(devices.Key), counter + i);
         if (code != codes[i]) return false;
     }
     return true;
 }
示例#2
0
        internal bool TryGet(string ident, out Device devices)
        {
            devices = null;
            if (ident == null) return false;

            foreach (var d in _db)
            {
                if (d.Ident != ident) continue;
                devices = d;
                return true;
            }
            //devices not found, returning false.
            return false;
        }
示例#3
0
 internal bool HasMaxFailures(ref Device devices)
 {
     if (MaxAttempts == 0 || devices.Failures < MaxAttempts) return false;
     devices.Failures++;
     return true;
 }
示例#4
0
        /// <summary>
        /// Resyncs a remote devices with the local devices database.
        /// You can enter multiple codes, for the resync to succeed, all the
        /// codes need to be verified. Its more secure to use multiple codes.
        /// 
        /// If is successfully syncs it use the call back for you to unlock the
        /// device and set the correct counter.
        /// </summary>
        ///<param name="device">device that you want to resync</param>
        ///<param name="codes">list of codes that should be verified</param>
        ///<param name="counter">start counter, meaning on what interval should se start resync'ing</param>
        ///<param name="updateDevice">call back delegate for when the resync was successfull, we need to update the device differently depending on HOTP/TOTP</param>
        ///<param name="window">overrides global window for the resync. Set to -1 to use the default window</param>
        ///<exception cref="ArgumentNullException">If codes or ident is null</exception>
        ///<exception cref="ArgumentOutOfRangeException">If window is less than -1</exception>
        /// <exception cref="OtpDecryptionException">if key failed to decrypt</exception>
        ///<returns>true if resync was successfull</returns>
        /// <remarks>
        /// Background info (RFC4226):
        /// As we suggested for the resynchronization to enter a short sequence
        /// (say, 2 or 3) of HOTP values, we could generalize the concept to the
        /// protocol, and add a parameter L that would define the length of the
        /// HOTP sequence to enter.
        ///
        /// Per default, the value L SHOULD be set to 1, but if security needs to
        /// be increased, users might be asked (possibly for a short period of
        /// time, or a specific operation) to enter L HOTP values.
        ///
        /// This is another way, without increasing the HOTP length or using
        /// alphanumeric values to tighten security.
        ///
        /// Note: The system MAY also be programmed to request synchronization on
        /// a regular basis (e.g., every night, twice a week, etc.) and to
        /// achieve this purpose, ask for a sequence of L HOTP values.
        /// </remarks>
        internal bool Resync(Device device, string[] codes, long counter, UpdateDevice updateDevice, int window = -1)
        {
            for (int i = 0; i <= window; i++)
            {
                //check forward in totp/hotp counter
                if (Generate(Decrypt(device.Key), counter + i) == codes[0] && ResyncCheck(ref device, codes, counter + i))
                {
                        updateDevice(ref device, counter + i + codes.Length); //delegate to update devices.
                        return true;
                }

                //check backwards in totp/hotp counter
                if (Generate(Decrypt(device.Key), counter - i) == codes[0] && ResyncCheck(ref device, codes, counter - i))
                {
                    updateDevice(ref device, counter - i + codes.Length); //delegate to update devices.
                    return true;
                }
            }
            return false;
        }
示例#5
0
 internal void DoThrottling(ref Device devices)
 {
     if (devices.Failures == 0 || !EnableThrottling) return;
     Thread.Sleep(ThrottlingDelay * devices.Failures);
 }
        private VerifyResult UpdateDevice(ref Device devices, int newOffset, long currentCounter)
        {
            if (CheckUsedCounter(ref devices, newOffset + currentCounter)) return VerifyResult.FailedUsedCode;

            devices.TotpOffset = newOffset; //set offset from devices + the current offset.
            devices.Failures = 0;
            return VerifyResult.Success;
        }
 private void UpdateDevice(ref Device devices, long counter)
 {
     devices.TotpOffset = (int) (counter - GetCurrentTimeInterval(TimeStep));
     devices.Failures = 0;
     devices.TotpUsedCounter = new List<long>();
 }
        private bool CheckUsedCounter(ref Device devices, long counter)
        {
            if (devices.TotpUsedCounter == null) devices.TotpUsedCounter = new List<long>();

            //make sure we can only use a counter once.
            if (devices.TotpUsedCounter.Contains(counter))
            {
                devices.Failures++;
                return true;
            }
            devices.TotpUsedCounter.Add(counter);
            return false;
        }
 private static void UpdateDevice(ref Device devices, long counter)
 {
     devices.HotpCounter = counter;
     devices.Failures = 0;
 }