/// <summary>
 /// Removes an association from the associations table.
 /// </summary>
 /// <param name="assoc">Association to remove from persistence.</param>
 public void Remove(Association assoc)
 {
     DataRow[] rows = Associations.Select("handle = '" + assoc.Handle + "'");
     foreach (DataRow dr in rows)
     {
         Associations.Rows.Remove(dr);
     }
     Associations.AcceptChanges();
 }
 /// <summary>
 /// Removes an association from the database.
 /// </summary>
 /// <param name="assoc">Association to remove.</param>
 public void Remove(Association assoc)
 {
     string sql = "DELETE FROM " + _tableName + " WHERE Handle = '" + FixSqlIn(assoc.Handle) + "'";
     _conn.Open();
     IDbCommand comm = _conn.CreateCommand();
     comm.CommandText = sql;
     comm.ExecuteNonQuery();
     _conn.Close();
 }
        /// <summary>
        /// Adds a new association to the associations table.
        /// </summary>
        /// <param name="association">The association entry to store.</param>
        public void Add(Association association)
        {
            // Check for existing association
            DataRow[] result = Associations.Select("server = '" + association.Server + "'");
            if (result.Length > 0)
            {
                for (int i = 0; i < result.Length; i++)
                {
                    Associations.Rows.Remove(result[i]);
                }
            }

            // Add new row
            DataRow dr = Associations.NewRow();
            dr["protocol"] = association.ProtocolVersion;
            dr["server"] = association.Server;
            dr["handle"] = association.Handle;
            dr["assoc_type"] = association.AssociationType;
            dr["session_type"] = association.SessionType;
            dr["secret"] = association.Secret;
            dr["expiration"] = association.Expiration;
            Associations.Rows.Add(dr);
            Associations.AcceptChanges();
        }
 /// <summary>
 /// Translates a DataRow matching the correct schema
 /// into an Association object.
 /// </summary>
 /// <param name="dr">DataRow containing source data.</param>
 /// <returns>Populated Association object.</returns>
 private static Association ToAssociation(DataRow dr)
 {
     Association ar = new Association();
     ar.ProtocolVersion = (ProtocolVersion)dr["protocol"];
     ar.Server = (string)dr["server"];
     ar.Handle = (string)dr["handle"];
     ar.AssociationType = (string)dr["assoc_type"];
     ar.SessionType = (string)dr["session_type"];
     ar.Secret = (byte[])dr["secret"];
     ar.Expiration = (DateTime)dr["expiration"];
     return ar;
 }
        /// <summary>
        /// Add an assocation to the database.
        /// </summary>
        /// <param name="association">Association to add.</param>
        public void Add(Association association)
        {
            string protoversion = "";
            switch (association.ProtocolVersion)
            {
                case ProtocolVersion.V1Dot1:
                    protoversion = "V1_1";
                    break;
                case ProtocolVersion.V2Dot0:
                    protoversion = "V2_0";
                    break;
            }

            string sql = "INSERT INTO " + _tableName + " (Handle, Server, AssociationType, "
                + "SessionType, ProtocolVersion, Secret, Expiration) "
                + "VALUES ('" + FixSqlIn(association.Handle) + "', "
                + "'" + association.Server + "', "
                + "'" + association.AssociationType + "', "
                + "'" + association.SessionType + "', "
                + "'" + protoversion + "', "
                + "'" + Convert.ToBase64String(association.Secret) + "', " 
                + "'" + association.Expiration.ToString("s", CultureInfo.InvariantCulture) + "') ";
            _conn.Open();
            IDbCommand comm = _conn.CreateCommand();
            comm.CommandText = sql;
            comm.ExecuteNonQuery();
            _conn.Close();
        }
 /// <summary>
 /// Transforms the current record in a DataReader object into an Association object.
 /// </summary>
 /// <param name="dr">The DataReader object use.</param>
 /// <returns>A populated Association object.</returns>
 protected static Association ToAssociation(IDataRecord dr)
 {
     Association ar = new Association();
     switch ((string)dr["ProtocolVersion"])
     {
         case "V2_0":
             ar.ProtocolVersion = ProtocolVersion.V2Dot0;
             break;
         case "V1_1":
             ar.ProtocolVersion = ProtocolVersion.V1Dot1;
             break;
     }
     ar.Server = (string)dr["Server"];
     ar.Handle = FixSqlOut((string)dr["Handle"]);
     ar.AssociationType = (string)dr["AssociationType"];
     ar.SessionType = (string)dr["SessionType"];
     ar.Secret = Convert.FromBase64String((string)dr["Secret"]);
     ar.Expiration = ((DateTime)dr["Expiration"]);
     return ar;
 }
Example #7
0
        /// <summary>
        /// Perform an association request with an OpenID Provider.
        /// </summary>
        /// <param name="server">URL to the OpenID Provider.</param>
        /// <param name="associationManager">The IAssociationPersistence object to use for persistence.</param>
        /// <param name="version">The ProtocolVersion to use.</param>
        /// <param name="encryption">The key encryption type to use.</param>
        /// <returns>Populated Association object, or null.</returns>
        internal static Association CreateAssociation(Uri server, IAssociationPersistence associationManager,
                                                      ProtocolVersion version, KeyEncryption encryption)
        {
            if (server == null) { throw new ArgumentNullException("server"); }
            if (associationManager == null) { throw new ArgumentNullException("associationManager"); }

            NameValueCollection sd = new NameValueCollection();
            DiffieHellmanManaged dhm = new DiffieHellmanManaged();
            sd["openid.mode"] = "associate";

            switch (version)
            {
                case ProtocolVersion.V2Dot0:
                    sd["openid.ns"] = ProtocolUri.OpenId2Dot0.AbsoluteUri;
                    break;
                case ProtocolVersion.V1Dot1:
                    if (encryption == KeyEncryption.DHSHA256)
                    {
                        encryption = KeyEncryption.DHSHA1;
                    }
                    break;
            }

            byte[] pubkey = null;
            DHParameters dp;

            switch (encryption)
            {
                case KeyEncryption.None:
                    sd["openid.assoc_type"] = "HMAC-SHA1";
                    switch (version)
                    {
                        case ProtocolVersion.V2Dot0:
                            sd["openid.session_type"] = "no-encryption";
                            break;
                        case ProtocolVersion.V1Dot1:
                            sd["openid.session_type"] = "";
                            break;
                    }
                    break;
                case KeyEncryption.DHSHA1:
                    pubkey = dhm.CreateKeyExchange();
                    dp = dhm.ExportParameters(true);

                    sd["openid.assoc_type"] = "HMAC-SHA1";
                    sd["openid.session_type"] = "DH-SHA1";
                    sd["openid.dh_modulus"] = Utility.UnsignedToBase64(dp.P);
                    sd["openid.dh_gen"] = Utility.UnsignedToBase64(dp.G);
                    sd["openid.dh_consumer_public"] = Utility.UnsignedToBase64(pubkey);
                    break;
                case KeyEncryption.DHSHA256:
                    pubkey = dhm.CreateKeyExchange();
                    dp = dhm.ExportParameters(true);

                    sd["openid.assoc_type"] = "HMAC-SHA256";
                    sd["openid.session_type"] = "DH-SHA256";
                    sd["openid.dh_modulus"] = Utility.UnsignedToBase64(dp.P);
                    sd["openid.dh_gen"] = Utility.UnsignedToBase64(dp.G);
                    sd["openid.dh_consumer_public"] = Utility.UnsignedToBase64(pubkey);
                    break;
            }

            Tracer.Write("Opening connection to OpenID Provider.");
            string response = "";
            string actualLocation = null;
            response = Utility.MakeRequest(server, "POST", sd, out actualLocation);

            NameValueCollection association = null;
            Association retassoc = null;
            if (response != null)
            {
                Tracer.Write("Association response received.");
                association = Utility.SplitResponse(response);
            }
            else
            {
                Tracer.Write("No association response received.");
                switch (encryption)
                {
                    case KeyEncryption.DHSHA256:
                        Tracer.Write("Falling back to DHSHA1");
                        encryption = KeyEncryption.DHSHA1;
                        retassoc = CreateAssociation(server, associationManager, version, encryption);
                        if (retassoc != null) { return retassoc; }
                        break;
                    case KeyEncryption.DHSHA1:
                        Tracer.Write("Falling back to No-encryption");
                        encryption = KeyEncryption.None;
                        retassoc = CreateAssociation(server, associationManager, version, encryption);
                        if (retassoc != null) { return retassoc; }
                        break;
                }
                return null;
            }

            if (association["error"] != null)
            {
                Tracer.Write("Association response contains error. - " + association["error"]);
                return null;
            }

            if (encryption == KeyEncryption.DHSHA1 || encryption == KeyEncryption.DHSHA256)
            {
                Tracer.Write("Expecting DHSHA1 or DHSHA256.");
                StringBuilder vals = new StringBuilder();
                foreach (string key in association.Keys)
                {
                    vals.AppendLine(key + ": " + association[key]);
                }
                if (association["enc_mac_key"] == null) { Tracer.Write("No encoded MAC key returned! Received " + vals.ToString()); }
                if (association["enc_mac_key"] != null)
                {
                    Tracer.Write("Encrypted association key is present.");
                    byte[] serverpublickey = Convert.FromBase64String(association["dh_server_public"]);
                    byte[] mackey = Convert.FromBase64String(association["enc_mac_key"]);

                    byte[] dhShared = dhm.DecryptKeyExchange(serverpublickey);
                    byte[] shaShared = new byte[0];

                    if (encryption == KeyEncryption.DHSHA1)
                    {
                        Tracer.Write("Decoding DHSHA1 Association.");
                        SHA1 sha1 = new SHA1CryptoServiceProvider();
                        shaShared = sha1.ComputeHash(Utility.EnsurePositive(dhShared));
                    }
                    else if (encryption == KeyEncryption.DHSHA256)
                    {
                        Tracer.Write("Decoding DHSHA256 Association.");
                        SHA256 sha256 = new SHA256Managed();
                        shaShared = sha256.ComputeHash(Utility.EnsurePositive(dhShared));
                    }

                    byte[] secret = new byte[mackey.Length];
                    for (int i = 0; i < mackey.Length; i++)
                    {
                        secret[i] = (byte)(mackey[i] ^ shaShared[i]);
                    }
                    association["mac_key"] = Convert.ToBase64String(secret);
                }
                else
                {
                    Tracer.Write("Error: Received plaintext association when expecting encrypted.");
                    return null;
                }
            }

            Tracer.Write("Building association");
            retassoc = new Association();
            retassoc.AssociationType = association["assoc_type"];
            retassoc.Expiration = DateTime.UtcNow.AddSeconds(Convert.ToDouble(association["expires_in"], CultureInfo.InvariantCulture));
            retassoc.Handle = association["assoc_handle"];
            retassoc.ProtocolVersion = version;
            retassoc.Server = server.AbsoluteUri;
            retassoc.SessionType = association["session_type"];
            retassoc.Secret = Convert.FromBase64String(association["mac_key"]);
            return retassoc;
        }