Skip to content

Commit

Permalink
Merge pull request #28 from jimsch/oscoap-multi
Browse files Browse the repository at this point in the history
Start the work on doing multicast OSCOAP.
  • Loading branch information
jimsch authored Aug 1, 2017
2 parents 6b292f3 + 7db473e commit 996e978
Show file tree
Hide file tree
Showing 13 changed files with 660 additions and 401 deletions.
13 changes: 11 additions & 2 deletions CoAP.Example/CoAP.Server/CoAP.Server.NET45.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
Expand Down Expand Up @@ -43,6 +43,12 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="CBOR, Version=2.5.2.0, Culture=neutral, PublicKeyToken=9cd62db60ea5554c, processorArchitecture=MSIL">
<HintPath>..\..\packages\PeterO.Cbor.2.5.2\lib\portable-net45+dnxcore50+netcore45+win+wpa81+wp80\CBOR.dll</HintPath>
</Reference>
<Reference Include="Numbers, Version=0.4.0.0, Culture=neutral, PublicKeyToken=9cd62db60ea5554c, processorArchitecture=MSIL">
<HintPath>..\..\packages\PeterO.Numbers.0.4.0\lib\portable-net45+dnxcore50+netcore45+win+wpa81+wp80\Numbers.dll</HintPath>
</Reference>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
Expand All @@ -64,6 +70,9 @@
<Name>CoAP.NET45</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
Expand All @@ -72,4 +81,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
5 changes: 5 additions & 0 deletions CoAP.Example/CoAP.Server/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="PeterO.Cbor" version="2.5.2" targetFramework="net45" />
<package id="PeterO.Numbers" version="0.4.0" targetFramework="net45" />
</packages>
2 changes: 1 addition & 1 deletion CoAP.NET/CoAP.NET45.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<Optimize>true</Optimize>
<IntermediateOutputPath>obj\Release\NET45</IntermediateOutputPath>
<OutputPath>bin\Release\NET45\</OutputPath>
<DefineConstants>TRACE;COAPALL;INCLUDE_OSCOAP;OSCOAP_COMPRESS</DefineConstants>
<DefineConstants>TRACE;COAPALL;INCLUDE_OSCOAP;FRESHNESS</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\NET45\CoAP.XML</DocumentationFile>
Expand Down
9 changes: 8 additions & 1 deletion CoAP.NET/Log/FileLogManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@

namespace Com.AugustCellars.CoAP.Log
{
class FileLogManager : ILogManager
/// <summary>
/// Log to file to make life easier to get information
/// </summary>
public class FileLogManager : ILogManager
{
/// <summary>
/// Create a file log manager item
/// </summary>
/// <param name="writeTo">File to write things to</param>
public FileLogManager(System.IO.TextWriter writeTo)
{
LogStream = writeTo;
Expand Down
10 changes: 8 additions & 2 deletions CoAP.NET/Net/Exchange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,17 @@ public T GetOrAdd<T>(Object key, Func<Object, Object> valueFactory)
return (T)GetOrAdd(key, o => valueFactory(o));
}

/// <summary>
/// Set an object in the attribute map based on it's key.
/// If a previous object existed, return it.
/// </summary>
/// <param name="key">Key to use to save the object</param>
/// <param name="value">value to save</param>
/// <returns>old object if one exists.</returns>
public Object Set(Object key, Object value)
{
Object old = null;
_attributes.AddOrUpdate(key, value, (k, v) =>
{
_attributes.AddOrUpdate(key, value, (k, v) => {
old = v;
return value;
});
Expand Down
137 changes: 74 additions & 63 deletions CoAP.NET/OSCOAP/HKDF.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,40 @@
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto;
#pragma warning disable 1591

namespace Com.AugustCellars.CoAP.OSCOAP
{
#if INCLUDE_OSCOAP
/**
* HMAC-based Extract-and-Expand Key Derivation Function (HKDF) implemented
* according to IETF RFC 5869, May 2010 as specified by H. Krawczyk, IBM
* Research &amp; P. Eronen, Nokia. It uses a HMac internally to compute de OKM
* (output keying material) and is likely to have better security properties
* than KDF's based on just a hash function.
*/
/// <summary>
/// HMAC-based Extract-and-Expand Key Derivation Function(HKDF) implemented
/// according to IETF RFC 5869, May 2010 as specified by H.Krawczyk, IBM
/// Research &amp; P.Eronen, Nokia.It uses a HMac internally to compute de OKM
/// (output keying material) and is likely to have better security properties
/// than KDF's based on just a hash function.
/// </summary>
public class HkdfBytesGenerator
: IDerivationFunction
{
private HMac hMacHash;
private int hashLen;
private readonly HMac _hMacHash;
private readonly int _hashLen;

private byte[] info;
private byte[] currentT;
private byte[] _info;
private byte[] _currentT;

private int generatedBytes;
private int _generatedBytes;

/**
* Creates a HKDFBytesGenerator based on the given hash function.
*
* @param hash the digest to be used as the source of generatedBytes bytes
*/
/// <summary>
/// Creates a HKDFBytesGenerator based on the given hash function.
/// </summary>
/// <param name="hash">the digest to be used as the source of generatedBytes bytes</param>
public HkdfBytesGenerator(IDigest hash)
{
this.hMacHash = new HMac(hash);
this.hashLen = hash.GetDigestSize();
this._hMacHash = new HMac(hash);
this._hashLen = hash.GetDigestSize();
}

/// <inheritdoc/>
public virtual void Init(IDerivationParameters parameters)
{
if (!(parameters is HkdfParameters))
Expand All @@ -48,16 +49,16 @@ public virtual void Init(IDerivationParameters parameters)
HkdfParameters hkdfParameters = (HkdfParameters)parameters;
if (hkdfParameters.SkipExtract) {
// use IKM directly as PRK
hMacHash.Init(new KeyParameter(hkdfParameters.GetIkm()));
_hMacHash.Init(new KeyParameter(hkdfParameters.GetIkm()));
}
else {
hMacHash.Init(Extract(hkdfParameters.GetSalt(), hkdfParameters.GetIkm()));
_hMacHash.Init(Extract(hkdfParameters.GetSalt(), hkdfParameters.GetIkm()));
}

info = hkdfParameters.GetInfo();
_info = hkdfParameters.GetInfo();

generatedBytes = 0;
currentT = new byte[hashLen];
_generatedBytes = 0;
_currentT = new byte[_hashLen];
}

/**
Expand All @@ -69,19 +70,19 @@ public virtual void Init(IDerivationParameters parameters)
*/
private KeyParameter Extract(byte[] salt, byte[] ikm)
{
hMacHash.Init(new KeyParameter(ikm));
_hMacHash.Init(new KeyParameter(ikm));
if (salt == null) {
// TODO check if hashLen is indeed same as HMAC size
hMacHash.Init(new KeyParameter(new byte[hashLen]));
_hMacHash.Init(new KeyParameter(new byte[_hashLen]));
}
else {
hMacHash.Init(new KeyParameter(salt));
_hMacHash.Init(new KeyParameter(salt));
}

hMacHash.BlockUpdate(ikm, 0, ikm.Length);
_hMacHash.BlockUpdate(ikm, 0, ikm.Length);

byte[] prk = new byte[hashLen];
hMacHash.DoFinal(prk, 0);
byte[] prk = new byte[_hashLen];
_hMacHash.DoFinal(prk, 0);
return new KeyParameter(prk);
}

Expand All @@ -94,50 +95,60 @@ private KeyParameter Extract(byte[] salt, byte[] ikm)
*/
private void ExpandNext()
{
int n = generatedBytes / hashLen + 1;
int n = _generatedBytes / _hashLen + 1;
if (n >= 256) {
throw new DataLengthException(
"HKDF cannot generate more than 255 blocks of HashLen size");
}
// special case for T(0): T(0) is empty, so no update
if (generatedBytes != 0) {
hMacHash.BlockUpdate(currentT, 0, hashLen);
if (_generatedBytes != 0) {
_hMacHash.BlockUpdate(_currentT, 0, _hashLen);
}
hMacHash.BlockUpdate(info, 0, info.Length);
hMacHash.Update((byte)n);
hMacHash.DoFinal(currentT, 0);
_hMacHash.BlockUpdate(_info, 0, _info.Length);
_hMacHash.Update((byte)n);
_hMacHash.DoFinal(_currentT, 0);
}

/// <summary>
/// Get the digest function
/// </summary>
public virtual IDigest Digest {
get { return hMacHash.GetUnderlyingDigest(); }
get { return _hMacHash.GetUnderlyingDigest(); }
}

/// <summary>
/// Generate bytes
/// </summary>
/// <param name="output">destination</param>
/// <param name="outOff">diestination offset</param>
/// <param name="len">count of bytes</param>
/// <returns>count of bytes</returns>
public virtual int GenerateBytes(byte[] output, int outOff, int len)
{
if (generatedBytes + len > 255 * hashLen) {
if (_generatedBytes + len > 255 * _hashLen) {
throw new DataLengthException(
"HKDF may only be used for 255 * HashLen bytes of output");
}

if (generatedBytes % hashLen == 0) {
if (_generatedBytes % _hashLen == 0) {
ExpandNext();
}

// copy what is left in the currentT (1..hash
int toGenerate = len;
int posInT = generatedBytes % hashLen;
int leftInT = hashLen - generatedBytes % hashLen;
int posInT = _generatedBytes % _hashLen;
int leftInT = _hashLen - _generatedBytes % _hashLen;
int toCopy = System.Math.Min(leftInT, toGenerate);
Array.Copy(currentT, posInT, output, outOff, toCopy);
generatedBytes += toCopy;
Array.Copy(_currentT, posInT, output, outOff, toCopy);
_generatedBytes += toCopy;
toGenerate -= toCopy;
outOff += toCopy;

while (toGenerate > 0) {
ExpandNext();
toCopy = System.Math.Min(hashLen, toGenerate);
Array.Copy(currentT, 0, output, outOff, toCopy);
generatedBytes += toCopy;
toCopy = System.Math.Min(_hashLen, toGenerate);
Array.Copy(_currentT, 0, output, outOff, toCopy);
_generatedBytes += toCopy;
toGenerate -= toCopy;
outOff += toCopy;
}
Expand All @@ -146,37 +157,37 @@ public virtual int GenerateBytes(byte[] output, int outOff, int len)
}
}

/**
* Parameter class for the HkdfBytesGenerator class.
*/
/// <summary>
/// Parameter class for the HkdfBytesGenerator class.
/// </summary>
public class HkdfParameters
: IDerivationParameters
{
private readonly byte[] ikm;
private readonly bool skipExpand;
private readonly byte[] salt;
private readonly byte[] info;
private readonly byte[] _ikm;
private readonly bool _skipExpand;
private readonly byte[] _salt;
private readonly byte[] _info;

private HkdfParameters(byte[] ikm, bool skip, byte[] salt, byte[] info)
{
if (ikm == null)
throw new ArgumentNullException("ikm");

this.ikm = Arrays.Clone(ikm);
this.skipExpand = skip;
this._ikm = Arrays.Clone(ikm);
this._skipExpand = skip;

if (salt == null || salt.Length == 0) {
this.salt = null;
this._salt = null;
}
else {
this.salt = Arrays.Clone(salt);
this._salt = Arrays.Clone(salt);
}

if (info == null) {
this.info = new byte[0];
this._info = new byte[0];
}
else {
this.info = Arrays.Clone(info);
this._info = Arrays.Clone(info);
}
}

Expand Down Expand Up @@ -219,7 +230,7 @@ public static HkdfParameters DefaultParameters(byte[] ikm)
*/
public virtual byte[] GetIkm()
{
return Arrays.Clone(ikm);
return Arrays.Clone(_ikm);
}

/**
Expand All @@ -228,7 +239,7 @@ public virtual byte[] GetIkm()
* @return true for skipping, false for no skipping of step 1
*/
public virtual bool SkipExtract {
get { return skipExpand; }
get { return _skipExpand; }
}

/**
Expand All @@ -239,7 +250,7 @@ public virtual bool SkipExtract {
*/
public virtual byte[] GetSalt()
{
return Arrays.Clone(salt);
return Arrays.Clone(_salt);
}

/**
Expand All @@ -249,7 +260,7 @@ public virtual byte[] GetSalt()
*/
public virtual byte[] GetInfo()
{
return Arrays.Clone(info);
return Arrays.Clone(_info);
}
}
#endif
Expand Down
Loading

0 comments on commit 996e978

Please sign in to comment.