Esempio n. 1
1
    ///<summary>Enables the SA if it has been properly setup.</summary>
    public void Enable() {
      // If both parties setup simultaneous SAs we could end up calling this
      // twice, once as a client and the other as server, this way we only
      // go through the whole process once.
      lock(_sync) {
        if(_called_enable == 1) {
          return;
        } else if(_closed == 1) {
          throw new Exception("Cannot enable a closed SA!");
        } else if(_ldhe == null) {
          throw new Exception("Local DHE not set.");
        } else if(RDHE.Value == null) {
          throw new Exception("Remote DHE not set.");
        } else if(!_hash_verified) {
          throw new Exception("Hash is not verified!");
        } else if(TimedOut) {
          throw new Exception("Timed out on this one!");
        }
        _called_enable = 1;

        // Deriving the DHE exchange and determing the order of keys
        // Specifically, we need up to 4 keys for the sender/receiver encryption/
        // authentication codes.  So to determine the order, we say whomever has
        // the smallest gets the first set of keys.
        byte[] rdhe = (byte[]) RDHE.Value;
        RDHE = null;
        byte[] key = _dh.DecryptKeyExchange(rdhe);
        _dh.Clear();
        _dh = null;
        int i = 0;
        while(i < _ldhe.Length && _ldhe[i] == rdhe[i]) i++;
        bool same = i == _ldhe.Length;
        bool first = !same && (_ldhe[i] < rdhe[i]);
        _ldhe = null;
        // Gathering our security parameter objects
        SecurityPolicy sp = SecurityPolicy.GetPolicy(_spi);
        SymmetricAlgorithm in_sa = sp.CreateSymmetricAlgorithm();
        HashAlgorithm in_ha = sp.CreateHashAlgorithm();
        SymmetricAlgorithm out_sa = sp.CreateSymmetricAlgorithm();
        HashAlgorithm out_ha = sp.CreateHashAlgorithm();

        // Generating the total key length 
        int key_length = key.Length + 2 + (in_sa.KeySize / 8 + in_sa.BlockSize / 8) * 2;
        KeyedHashAlgorithm in_kha = in_ha as KeyedHashAlgorithm;
        KeyedHashAlgorithm out_kha = out_ha as KeyedHashAlgorithm;
        if(in_kha != null) {
          key_length += (in_kha.HashSize / 8) * 2;
        }

        // Generating a key by repeatedly hashing the DHE value and the key so far
        SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
        int usable_key_offset = key.Length;
        while(key.Length < key_length) {
          byte[] hash = sha1.ComputeHash(key);
          byte[] tmp_key = new byte[hash.Length + key.Length];
          key.CopyTo(tmp_key, 0);
          hash.CopyTo(tmp_key, key.Length);
          key = tmp_key;
        }

        // Like a sub-session ID (see DTLS)
        short epoch = (short) ((key[usable_key_offset] << 8) + key[usable_key_offset + 1]);
        usable_key_offset += 2;

        byte[] key0 = new byte[in_sa.KeySize / 8];
        Array.Copy(key, usable_key_offset, key0, 0, key0.Length);
        usable_key_offset += key0.Length;

        byte[] key1 = new byte[in_sa.KeySize / 8];
        Array.Copy(key, usable_key_offset, key1, 0, key1.Length);
        usable_key_offset += key1.Length;

        // Same may occur if we are forming a session with ourselves!
        if(same) {
          in_sa.Key = key0;
          out_sa.Key = key0;
        } else if(first) {
          in_sa.Key = key0;
          out_sa.Key = key1;
        } else {
          out_sa.Key = key0;
          in_sa.Key = key1;
        }

        if(in_kha != null) {
          byte[] hkey0 = new byte[in_kha.HashSize / 8];
          Array.Copy(key, usable_key_offset, hkey0, 0, hkey0.Length);
          usable_key_offset += hkey0.Length;

          byte[] hkey1 = new byte[in_kha.HashSize / 8];
          Array.Copy(key, usable_key_offset, hkey1, 0, hkey1.Length);
          usable_key_offset += hkey1.Length;

          if(same) {
            in_kha.Key = hkey0;
            out_kha.Key = hkey0;
          } else if(first) {
            in_kha.Key = hkey0;
            out_kha.Key = hkey1;
          } else {
            out_kha.Key = hkey0;
            in_kha.Key = hkey1;
          }
        }

        SecurityHandler sh = new SecurityHandler(in_sa, out_sa, in_ha, out_ha, epoch);
        sh.Update += UpdateSH;
        SecurityHandler to_close = _current_sh;
        if(to_close != null) {
          to_close.Close();
        }
        _current_sh = sh;
        _last_epoch = _current_epoch;
        _current_epoch = epoch;
      }
      // All finished set the state (which will probably fire an event)
      State = SAState.Active;
    }
Esempio n. 2
0
        ///<summary>This is called when we want to reset the state of the SA after
        ///an equivalent time of two timeouts has occurred.</summary>
        public bool Reset()
        {
            lock (_sync) {
                if (_incoming && _last_update != DateTime.MinValue &&
                    (_last_update.AddMilliseconds(TIMEOUT * 2) > DateTime.UtcNow ||
                     _closed == 1))
                {
                    return(false);
                }

                _last_update = DateTime.UtcNow;
                _last_called_request_update = DateTime.UtcNow;

                LocalCertificate  = new WriteOnceX509();
                RemoteCertificate = new WriteOnceX509();
                DHEWithCertificateAndCAsInHash  = new WriteOnceIdempotent <MemBlock>();
                DHEWithCertificateAndCAsOutHash = new WriteOnceIdempotent <MemBlock>();
                DHEWithCertificateHash          = new WriteOnceIdempotent <MemBlock>();
                RDHE           = new WriteOnceIdempotent <MemBlock>();
                RemoteCookie   = new WriteOnceIdempotent <MemBlock>();
                _ldhe          = null;
                _hash_verified = false;
                _called_enable = 0;
                _incoming      = true;
                _running       = true;
            }

            if (State == SAState.Active)
            {
                State = SAState.Updating;
            }

            return(true);
        }
Esempio n. 3
0
        public void Reset()
        {
            lock (_sync) {
                _last_update = DateTime.UtcNow;
                _last_called_request_update = DateTime.UtcNow;

                _local_cert  = new WriteOnceX509();
                _remote_cert = new WriteOnceX509();
                DHEWithCertificateAndCAsInHash  = new WriteOnceIdempotent <MemBlock>();
                DHEWithCertificateAndCAsOutHash = new WriteOnceIdempotent <MemBlock>();
                DHEWithCertificateHash          = new WriteOnceIdempotent <MemBlock>();
                RDHE           = new WriteOnceIdempotent <MemBlock>();
                RemoteCookie   = new WriteOnceIdempotent <MemBlock>();
                _ldhe          = null;
                _hash_verified = false;
                _called_enable = 0;
                _receiving     = true;
                _sending       = true;
            }

            UpdateState(States.Active, States.Updating);
        }
Esempio n. 4
0
        ///<summary>This is called when we want to reset the state of the SA after
        ///an equivalent time of two timeouts has occurred.</summary>
        public bool Reset()
        {
            lock (_sync) {
                DateTime now = DateTime.UtcNow;
                // State is not reset if:
                // - It has been done within the past 120 seconds
                // - This is closed
                // - A packet has been received since the last SA check
                if ((_last_update != DateTime.MinValue &&
                     _last_update.AddSeconds(120) > now &&
                     State != States.Active) ||
                    _closed == 1 ||
                    (_receiving && State == States.Active))
                {
                    return(false);
                }

                _last_update = DateTime.UtcNow;
                _last_called_request_update = DateTime.UtcNow;

                _local_cert  = new WriteOnceX509();
                _remote_cert = new WriteOnceX509();
                DHEWithCertificateAndCAsInHash  = new WriteOnceIdempotent <MemBlock>();
                DHEWithCertificateAndCAsOutHash = new WriteOnceIdempotent <MemBlock>();
                DHEWithCertificateHash          = new WriteOnceIdempotent <MemBlock>();
                RDHE           = new WriteOnceIdempotent <MemBlock>();
                RemoteCookie   = new WriteOnceIdempotent <MemBlock>();
                _ldhe          = null;
                _hash_verified = false;
                _called_enable = 0;
                _receiving     = true;
                _sending       = true;
                _just_created  = true;
            }

            UpdateState(States.Active, States.Updating);
            return(true);
        }
Esempio n. 5
0
    ///<summary>This is called when we want to reset the state of the SA after
    ///an equivalent time of two timeouts has occurred.</summary>
    public bool Reset() {
      lock(_sync) {
        if(_incoming && _last_update != DateTime.MinValue &&
            (_last_update.AddMilliseconds(TIMEOUT * 2) > DateTime.UtcNow ||
            _closed == 1))
        {
          return false;
        }
        
        _last_update = DateTime.UtcNow;
        _last_called_request_update = DateTime.UtcNow;

        LocalCertificate = new WriteOnceX509();
        RemoteCertificate = new WriteOnceX509();
        DHEWithCertificateAndCAsInHash = new WriteOnceIdempotent<MemBlock>();
        DHEWithCertificateAndCAsOutHash = new WriteOnceIdempotent<MemBlock>();
        DHEWithCertificateHash = new WriteOnceIdempotent<MemBlock>();
        RDHE = new WriteOnceIdempotent<MemBlock>();
        RemoteCookie = new WriteOnceIdempotent<MemBlock>();
        _ldhe = null;
        _hash_verified = false;
        _called_enable = 0;
        _incoming = true;
        _running = true;
      }

      if(State == SAState.Active) {
        State = SAState.Updating;
      }

      return true;
    }
Esempio n. 6
0
    ///<summary>This is called when we want to reset the state of the SA after
    ///an equivalent time of two timeouts has occurred.</summary>
    public bool Reset() {
      lock(_sync) {
        DateTime now = DateTime.UtcNow;
        // State is not reset if:
        // - It has been done within the past 120 seconds
        // - This is closed
        // - A packet has been received since the last SA check
        if((_last_update != DateTime.MinValue &&
              _last_update.AddSeconds(120) > now &&
              State != States.Active) ||
            _closed == 1 ||
            (_receiving && State == States.Active))
        {
          return false;
        }
        
        _last_update = DateTime.UtcNow;
        _last_called_request_update = DateTime.UtcNow;

        _local_cert = new WriteOnceX509();
        _remote_cert = new WriteOnceX509();
        DHEWithCertificateAndCAsInHash = new WriteOnceIdempotent<MemBlock>();
        DHEWithCertificateAndCAsOutHash = new WriteOnceIdempotent<MemBlock>();
        DHEWithCertificateHash = new WriteOnceIdempotent<MemBlock>();
        RDHE = new WriteOnceIdempotent<MemBlock>();
        RemoteCookie = new WriteOnceIdempotent<MemBlock>();
        _ldhe = null;
        _hash_verified = false;
        _called_enable = 0;
        _receiving = true;
        _sending = true;
        _just_created = true;
      }

      UpdateState(States.Active, States.Updating);
      return true;
    }
Esempio n. 7
0
        ///<summary>Enables the SA if it has been properly setup.</summary>
        public void Enable()
        {
            // If both parties setup simultaneous SAs we could end up calling this
            // twice, once as a client and the other as server, this way we only
            // go through the whole process once.
            lock (_sync) {
                if (_called_enable == 1)
                {
                    return;
                }
                else if (_closed == 1)
                {
                    throw new Exception("Cannot enable a closed SA!");
                }
                else if (_ldhe == null)
                {
                    throw new Exception("Local DHE not set.");
                }
                else if (RDHE.Value == null)
                {
                    throw new Exception("Remote DHE not set.");
                }
                else if (!_hash_verified)
                {
                    throw new Exception("Hash is not verified!");
                }
                _called_enable = 1;

                // Deriving the DHE exchange and determing the order of keys
                // Specifically, we need up to 4 keys for the sender/receiver encryption/
                // authentication codes.  So to determine the order, we say whomever has
                // the smallest gets the first set of keys.
                byte[] rdhe = (byte[])RDHE.Value;
                RDHE = null;
                byte[] key = _dh.DecryptKeyExchange(rdhe);
                _dh.Clear();
                _dh = null;
                int i = 0;
                while (i < _ldhe.Length && _ldhe[i] == rdhe[i])
                {
                    i++;
                }
                bool same  = i == _ldhe.Length;
                bool first = !same && (_ldhe[i] < rdhe[i]);
                _ldhe = null;
                // Gathering our security parameter objects
                SecurityPolicy     sp     = SecurityPolicy.GetPolicy(_spi);
                SymmetricAlgorithm in_sa  = sp.CreateSymmetricAlgorithm();
                HashAlgorithm      in_ha  = sp.CreateHashAlgorithm();
                SymmetricAlgorithm out_sa = sp.CreateSymmetricAlgorithm();
                HashAlgorithm      out_ha = sp.CreateHashAlgorithm();

                // Generating the total key length
                int key_length             = key.Length + 2 + (in_sa.KeySize / 8 + in_sa.BlockSize / 8) * 2;
                KeyedHashAlgorithm in_kha  = in_ha as KeyedHashAlgorithm;
                KeyedHashAlgorithm out_kha = out_ha as KeyedHashAlgorithm;
                if (in_kha != null)
                {
                    key_length += (in_kha.HashSize / 8) * 2;
                }

                // Generating a key by repeatedly hashing the DHE value and the key so far
                SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
                int usable_key_offset          = key.Length;
                while (key.Length < key_length)
                {
                    byte[] hash    = sha1.ComputeHash(key);
                    byte[] tmp_key = new byte[hash.Length + key.Length];
                    key.CopyTo(tmp_key, 0);
                    hash.CopyTo(tmp_key, key.Length);
                    key = tmp_key;
                }

                // Like a sub-session ID (see DTLS)
                short epoch = (short)((key[usable_key_offset] << 8) + key[usable_key_offset + 1]);
                usable_key_offset += 2;

                byte[] key0 = new byte[in_sa.KeySize / 8];
                Array.Copy(key, usable_key_offset, key0, 0, key0.Length);
                usable_key_offset += key0.Length;

                byte[] key1 = new byte[in_sa.KeySize / 8];
                Array.Copy(key, usable_key_offset, key1, 0, key1.Length);
                usable_key_offset += key1.Length;

                // Same may occur if we are forming a session with ourselves!
                if (same)
                {
                    in_sa.Key  = key0;
                    out_sa.Key = key0;
                }
                else if (first)
                {
                    in_sa.Key  = key0;
                    out_sa.Key = key1;
                }
                else
                {
                    out_sa.Key = key0;
                    in_sa.Key  = key1;
                }

                if (in_kha != null)
                {
                    byte[] hkey0 = new byte[in_kha.HashSize / 8];
                    Array.Copy(key, usable_key_offset, hkey0, 0, hkey0.Length);
                    usable_key_offset += hkey0.Length;

                    byte[] hkey1 = new byte[in_kha.HashSize / 8];
                    Array.Copy(key, usable_key_offset, hkey1, 0, hkey1.Length);
                    usable_key_offset += hkey1.Length;

                    if (same)
                    {
                        in_kha.Key  = hkey0;
                        out_kha.Key = hkey0;
                    }
                    else if (first)
                    {
                        in_kha.Key  = hkey0;
                        out_kha.Key = hkey1;
                    }
                    else
                    {
                        out_kha.Key = hkey0;
                        in_kha.Key  = hkey1;
                    }
                }

                SecurityHandler sh = new SecurityHandler(in_sa, out_sa, in_ha, out_ha, epoch);
                sh.Update += UpdateSH;
                SecurityHandler to_close = _current_sh;
                if (to_close != null)
                {
                    to_close.Close();
                }
                _current_sh    = sh;
                _last_epoch    = _current_epoch;
                _current_epoch = epoch;
            }
            // All finished set the state (which will probably fire an event)
            UpdateState(States.Active);
            _active = _state == States.Active;
        }
Esempio n. 8
0
    public void Reset() {
      lock(_sync) {
        _last_update = DateTime.UtcNow;
        _last_called_request_update = DateTime.UtcNow;

        _local_cert = new WriteOnceX509();
        _remote_cert = new WriteOnceX509();
        DHEWithCertificateAndCAsInHash = new WriteOnceIdempotent<MemBlock>();
        DHEWithCertificateAndCAsOutHash = new WriteOnceIdempotent<MemBlock>();
        DHEWithCertificateHash = new WriteOnceIdempotent<MemBlock>();
        RDHE = new WriteOnceIdempotent<MemBlock>();
        RemoteCookie = new WriteOnceIdempotent<MemBlock>();
        _ldhe = null;
        _hash_verified = false;
        _called_enable = 0;
        _receiving = true;
        _sending = true;
      }

      UpdateState(States.Active, States.Updating);
    }