Beispiel #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;
    }
 public void TDES()
 {
   SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider(); 
   SymmetricAlgorithm sa = new TripleDESCryptoServiceProvider();
   SecurityHandler sh = new SecurityHandler(sa, sa, sha1, sha1, 0);
   byte[] data = new byte[1024];
   RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
   rng.GetBytes(data);
   SecurityDataMessage sdm = new SecurityDataMessage();
   sdm.SPI = 5;
   sdm.Data = MemBlock.Reference(data);
   sh.SignAndEncrypt(sdm);
   SecurityDataMessage sdm_d = new SecurityDataMessage(sdm.Packet);
   sh.DecryptAndVerify(sdm_d);
   Assert.AreEqual(sdm.Data, sdm.Data, "SecurityHandler");
 }