115 lines
3 KiB
C#
115 lines
3 KiB
C#
/*
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
*/
|
|
|
|
using System;
|
|
using System.Security.Cryptography;
|
|
|
|
namespace Apache.Qpid.Sasl
|
|
{
|
|
/// <summary>
|
|
/// Rough HMAC MD5 implementation as presented in
|
|
/// RFC 2104. Used because the HMACMD5 class in the
|
|
/// .NET framework is not available in v1.1.
|
|
/// </summary>
|
|
public sealed class MD5HMAC : IDisposable
|
|
{
|
|
private const int BLOCK_LEN = 64;
|
|
private MD5 _hash;
|
|
private byte[] _key;
|
|
private byte[] _ipad;
|
|
private byte[] _opad;
|
|
|
|
public MD5HMAC(byte[] key)
|
|
{
|
|
if ( key == null || key.Length == 0 )
|
|
throw new ArgumentNullException("key");
|
|
|
|
_hash = new MD5CryptoServiceProvider();
|
|
|
|
byte[] theKey = key;
|
|
if ( theKey.Length > BLOCK_LEN )
|
|
{
|
|
theKey = _hash.ComputeHash(theKey);
|
|
}
|
|
// pad key with 0's up to BLOCK_LEN
|
|
_key = new byte[BLOCK_LEN];
|
|
Array.Copy(theKey, _key, theKey.Length);
|
|
|
|
CreatePads();
|
|
}
|
|
|
|
public byte[] ComputeHash(byte[] input)
|
|
{
|
|
// H(K XOR opad, H(K XOR ipad, text))
|
|
return H(_opad, H(_ipad, input));
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if ( _hash != null )
|
|
{
|
|
((IDisposable)_hash).Dispose();
|
|
_hash = null;
|
|
}
|
|
}
|
|
|
|
#region Private Methods
|
|
//
|
|
// Private Methods
|
|
//
|
|
|
|
private void CreatePads()
|
|
{
|
|
_ipad = new byte[BLOCK_LEN];
|
|
_opad = new byte[BLOCK_LEN];
|
|
for ( int i = 0; i < BLOCK_LEN; i++ )
|
|
{
|
|
_ipad[i] = 0x36;
|
|
_opad[i] = 0x5c;
|
|
}
|
|
|
|
XOR(_ipad, _key);
|
|
XOR(_opad, _key);
|
|
}
|
|
|
|
private static void XOR(byte[] dest, byte[] other)
|
|
{
|
|
// assume both are same size
|
|
for ( int i = 0; i < dest.Length; i++ )
|
|
{
|
|
dest[i] ^= other[i];
|
|
}
|
|
}
|
|
|
|
private byte[] H(byte[] v1, byte[] v2)
|
|
{
|
|
byte[] total = new byte[v1.Length + v2.Length];
|
|
Array.Copy(v1, total, v1.Length);
|
|
Array.Copy(v2, 0, total, v1.Length, v2.Length);
|
|
|
|
return _hash.ComputeHash(total);
|
|
}
|
|
|
|
#endregion // Private Methods
|
|
|
|
} // class MD5HMAC
|
|
|
|
} // namespace Apache.Qpid.Sasl
|