Пример #1
1
        public static byte[] SHA1XorSecret(DiffieHellman dh, byte[] keyEx, byte[] encMacKey)
        {
            byte[] dhShared = dh.DecryptKeyExchange(keyEx);
            byte[] sha1DhShared = sha1.ComputeHash(EnsurePositive(dhShared));

            if (sha1DhShared.Length != encMacKey.Length)
                throw new ArgumentOutOfRangeException(String.Format("encMacKey's length is not 20 bytes: [{0}]", ToBase64String(encMacKey)));

            byte[] secret = new byte[encMacKey.Length];
            for (uint i = 0; i < encMacKey.Length; i++)
            {
                secret[i] = (byte) (encMacKey[i] ^ sha1DhShared[i]);
            }

            return secret;
        }
Пример #2
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;
    }
Пример #3
0
 public new static DiffieHellman Create()
 {
     return(DiffieHellman.Create("Mono.Security.Cryptography.DiffieHellman"));
 }
Пример #4
0
        /****************   Static Methods *****************/
        public static byte[] CreateAssociationRequest(DiffieHellman dh, NameValueCollection args)
        {
            byte[] dhPublic = dh.CreateKeyExchange();
            string cpub = CryptUtil.UnsignedToBase64(dhPublic);
            DHParameters dhps = dh.ExportParameters(true);

            args.Add("openid.mode", "associate");
            args.Add("openid.assoc_type", "HMAC-SHA1");
            args.Add("openid.session_type", "DH-SHA1");
            args.Add("openid.dh_modulus", CryptUtil.UnsignedToBase64(dhps.P));
            args.Add("openid.dh_gen", CryptUtil.UnsignedToBase64(dhps.G));
            args.Add("openid.dh_consumer_public", cpub);

            return ASCIIEncoding.ASCII.GetBytes(UriUtil.CreateQueryString(args));
        }
Пример #5
0
        private Association FetchAssociation(DiffieHellman dh, Uri serverUri, byte[] body)
        {
            try {
            FetchResponse resp = this.fetcher.Post(serverUri, body);
            NameValueCollection results = KVUtil.KVToDict(resp.data);

            return ParseAssociation(results, dh, serverUri);
            }
            catch (FetchException e)
            {
            if (e.response == null)
            {
            // XXX: log network failure
            }
            else if (e.response.code == HttpStatusCode.BadRequest)
            {
            // XXX: log this
            /*
              server_error = results.get('error', '<no message from server>')
              fmt = 'Getting association: error returned from server %s: %s'
              oidutil.log(fmt % (server_url, server_error))
            */
            }
            else
            {
            // XXX: log this
            /*fmt = 'Getting association: bad status code from server %s: %s'
              oidutil.log(fmt % (server_url, http_code))
            */
            }
            return null;
            }
        }
Пример #6
0
 private static byte[] CreateAssociateRequest(DiffieHellman dh)
 {
     NameValueCollection args = new NameValueCollection();
     return CreateAssociationRequest(dh, args);
 }
Пример #7
0
        protected Association ParseAssociation(NameValueCollection results, DiffieHellman dh, Uri serverUri)
        {
            try
            {
            if (GetParameter(results, "assoc_type") != "HMAC-SHA1")
            {
            // XXX: log this
            return null;
            }

            byte[] secret;
            string sessionType = results["session_type"];
            if (sessionType == null)
            {
            string macKey = results["mac_key"];
            if (macKey == null)
            {
            // XXX: Log this
            return null;
            }
            secret = Convert.FromBase64String(macKey);
            }
            else
            {
            if (sessionType != "DH-SHA1")
            {
            // XXX: log this
            return null;
            }

            byte[] spub = Convert.FromBase64String(GetParameter(results, "dh_server_public"));
            byte[] encMacKey = Convert.FromBase64String(GetParameter(results, "enc_mac_key"));
            secret = CryptUtil.SHA1XorSecret(dh, spub, encMacKey);
            }

            string assocHandle = GetParameter(results, "assoc_handle");
            TimeSpan expiresIn = new TimeSpan(0, 0, Convert.ToInt32(GetParameter(results, "expires_in")));
            Association assoc = new HMACSHA1Association(assocHandle, secret, expiresIn);
            this.store.StoreAssociation(serverUri, assoc);

            return assoc;
            }
            catch (MissingParameterException e)
            {
            // XXX: log this
            return null;
            }
        }