Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions Tests/Aws.IoTCore.Devices.UnitTests.nfproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
<Compile Include="ShadowTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ShadowJsonMessageExamples.cs" />
<Compile Include="SignatureVersion4Tests.cs" />
<Compile Include="SortExtensionTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
Expand All @@ -46,6 +48,9 @@
<Reference Include="nanoFramework.Json, Version=2.2.199.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.Json.2.2.199\lib\nanoFramework.Json.dll</HintPath>
</Reference>
<Reference Include="nanoFramework.Runtime.Events">
<HintPath>..\packages\nanoFramework.Runtime.Events.1.11.32\lib\nanoFramework.Runtime.Events.dll</HintPath>
</Reference>
<Reference Include="nanoFramework.System.Collections, Version=1.5.67.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.System.Collections.1.5.67\lib\nanoFramework.System.Collections.dll</HintPath>
</Reference>
Expand All @@ -61,6 +66,18 @@
<Reference Include="System.IO.Streams, Version=1.1.96.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.System.IO.Streams.1.1.96\lib\System.IO.Streams.dll</HintPath>
</Reference>
<Reference Include="System.Net">
<HintPath>..\packages\nanoFramework.System.Net.1.11.43\lib\System.Net.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http">
<HintPath>..\packages\nanoFramework.System.Net.Http.1.5.196\lib\System.Net.Http.dll</HintPath>
</Reference>
<Reference Include="System.Threading">
<HintPath>..\packages\nanoFramework.System.Threading.1.1.52\lib\System.Threading.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\nanoFramework.Aws.IoTCore.Devices\nanoFramework.Aws.IoTCore.Devices.nfproj" />
</ItemGroup>
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets')" />
<!-- MANUAL UPDATE HERE -->
Expand Down
86 changes: 86 additions & 0 deletions Tests/SignatureVersion4Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

using nanoFramework.TestFramework;
using System;
using System.Collections;

namespace nanoFramework.Aws.SignatureVersion4.Tests
{
// https://github.com/inspiration/uniface-aws-sigv4
// https://github.com/FantasticFiasco/aws-signature-version-4
// https://stackoverflow.com/questions/28966075/creating-a-hmac-signature-for-aws-rest-query-in-c-sharp
[TestClass]
public class SignatureVersion4Tests
{

[TestMethod]
public void check_SignerForQueryParameters_ComputeSignature_Get_iotGateway_generated_correctly()
{
// See: https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
// https://github.com/aws/aws-sdk-java-v2/blob/master/core/auth/src/test/java/software/amazon/awssdk/auth/signer/Aws4SignerTest.java
// https://github.com/aws/aws-sdk-net/blob/master/sdk/test/Services/Signer/UnitTests/Generated/Endpoints/SignerEndpointProviderTests.cs

var v4signer = new SignerForQueryParameterAuth
{
EndpointUri = new System.Uri("https://test.us-east-1.amazonaws.com"),
HttpMethod = "GET",
Service = "iotdevicegateway",
Region = "us-east-1"
};

Console.WriteLine(v4signer.ComputeSignature(new Hashtable(), "", "", "fakeAccessKey", "fakeSecret"));

//http://demo.us-east-1.amazonaws.com
//?X-Amz-Algorithm=AWS4-HMAC-SHA256
//&X-Amz-Credential=<your-access-key-id>/20130721/us-east-1/iotdevicegateway/aws4_request
//&X-Amz-Date=20130721T201207Z
//&X-Amz-SignedHeaders=host
//&X-Amz-Signature=<signature-value>

// replace '<your-access-key-id>' with "fakeAccessKey"
// replace '<signature-value>'
// replace '/' with '%2F' in url
// ignore or inject datetime?
}

[TestMethod]
public void check_SignerForQueryParameters_ComputeSignature_Post_S3_generated_correctly()
{
// See: https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html


var v4signer = new SignerForQueryParameterAuth
{
EndpointUri = new System.Uri("https://test.us-east-1.amazonaws.com"),
HttpMethod = "POST",
Service = "s3",
Region = "us-east-1"
};

// FIXME: would fail!
var sigparams = new Hashtable
{
{ "X-Amz-Expires", "86400" }
};

Console.WriteLine(v4signer.ComputeSignature(sigparams, "", "", "fakeAccessKey", "fakeSecret"));

//http://demo.us-east-1.amazonaws.com
//?X-Amz-Algorithm=AWS4-HMAC-SHA256
//&X-Amz-Credential=<your-access-key-id>/20130721/us-east-1/s3/aws4_request
//&X-Amz-Date=20130721T201207Z
//&X-Amz-Expires=86400
//&X-Amz-SignedHeaders=host
//&X-Amz-Signature=<signature-value>

// replace '<your-access-key-id>' with "fakeAccessKey"
// replace '<signature-value>'
// replace '/' with '%2F' in url
// ignore or inject datetime?
}

}
}
97 changes: 97 additions & 0 deletions Tests/SortExtensionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

using nanoFramework.TestFramework;
using System;
using System.Collections;

namespace nanoFramework.Aws.SignatureVersion4.Tests
{
[TestClass]
public class SortExtensionTests
{
[TestMethod]
public void check_ArrayList_Sort_Ordinal_when_order_is_canonical_already()
{
var list = new ArrayList();
list.Add("aTest");
list.Add("Atest2");
list.Add("btest");
list.Add("ctest");

list.Sort(StringComparer.Ordinal);

foreach (var item in list)
{
Console.WriteLine(item.ToString());
}



// Expect "atest;atest2;btest;ctest"
}

[TestMethod]
public void check_check_ArrayList_Sort_Ordinal_when_order_is_not_sorted()
{
var list = new ArrayList();
list.Add("aTest");
list.Add("ctest");
list.Add("btest");
list.Add("Atest2");

list.Sort(StringComparer.Ordinal);

foreach (var item in list)
{
Console.WriteLine(item.ToString());
}

// Expect "atest;atest2;btest;ctest"
}


[TestMethod]
public void check_ArrayList_Sort_OrdinalIgnoreCase_when_order_is_canonical_already()
{
var list = new ArrayList();
list.Add("aTest");
list.Add("Atest2");
list.Add("btest");
list.Add("ctest");

list.Sort(StringComparer.OrdinalIgnoreCase);

foreach (var item in list)
{
Console.WriteLine(item.ToString());
}



// Expect "atest;atest2;btest;ctest"
}

[TestMethod]
public void check_check_ArrayList_Sort_OrdinalIgnoreCase_when_order_is_not_sorted()
{
var list = new ArrayList();
list.Add("aTest");
list.Add("ctest");
list.Add("btest");
list.Add("Atest2");

list.Sort(StringComparer.OrdinalIgnoreCase);

foreach (var item in list)
{
Console.WriteLine(item.ToString());
}

// Expect "atest;atest2;btest;ctest"
}

}
}
4 changes: 4 additions & 0 deletions Tests/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
<packages>
<package id="nanoFramework.CoreLibrary" version="1.17.11" targetFramework="netnano1.0" />
<package id="nanoFramework.Json" version="2.2.199" targetFramework="netnano1.0" />
<package id="nanoFramework.Runtime.Events" version="1.11.32" targetFramework="netnano1.0" />
<package id="nanoFramework.System.Collections" version="1.5.67" targetFramework="netnano1.0" />
<package id="nanoFramework.System.IO.Streams" version="1.1.96" targetFramework="netnano1.0" />
<package id="nanoFramework.System.Net" version="1.11.43" targetFramework="netnano1.0" />
<package id="nanoFramework.System.Net.Http" version="1.5.196" targetFramework="netnano1.0" />
<package id="nanoFramework.System.Text" version="1.3.42" targetFramework="netnano1.0" />
<package id="nanoFramework.System.Threading" version="1.1.52" targetFramework="netnano1.0" />
<package id="nanoFramework.TestFramework" version="3.0.77" targetFramework="netnano1.0" developmentDependency="true" />
</packages>
24 changes: 24 additions & 0 deletions Tests/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"resolved": "2.2.199",
"contentHash": "XBNKcI5hiUpn19NxhSYM4cxH0FXeefrohGD4tFrTlwhZw3hL1ie5UQJ0dPsaUBb/YkypkJZzQoxEvnwOj8DI5w=="
},
"nanoFramework.Runtime.Events": {
"type": "Direct",
"requested": "[1.11.32, 1.11.32]",
"resolved": "1.11.32",
"contentHash": "NyLUIwJDlpl5VKSd+ljmdDtO2WHHBvPvruo1ccaL+hd79z+6XMYze1AccOVXKGiZenLBCwDmFHwpgIQyHkM7GA=="
},
"nanoFramework.System.Collections": {
"type": "Direct",
"requested": "[1.5.67, 1.5.67]",
Expand All @@ -26,12 +32,30 @@
"resolved": "1.1.96",
"contentHash": "kJSy4EJwChO4Vq3vGWP9gNRPFDnTsDU5HxzeI7NDO+RjbDsx7B8EhKymoeTPLJCxQq8y/0P1KG2XCxGpggW+fw=="
},
"nanoFramework.System.Net": {
"type": "Direct",
"requested": "[1.11.43, 1.11.43]",
"resolved": "1.11.43",
"contentHash": "USwz59gxcNUzsiXfQohWSi8ANNwGDsp+qG4zBtHZU3rKMtvTsLI3rxdfMC77VehKqsCPn7aK3PU2oCRFo+1Rgg=="
},
"nanoFramework.System.Net.Http": {
"type": "Direct",
"requested": "[1.5.196, 1.5.196]",
"resolved": "1.5.196",
"contentHash": "2qfUnvJa55Wx5C86HopeoUZVfXY+L6stufrlcKNHlalqIk4cc3Orv0Eqc0oroy3iB6aQGDw+tji7WYJS8LQNoA=="
},
"nanoFramework.System.Text": {
"type": "Direct",
"requested": "[1.3.42, 1.3.42]",
"resolved": "1.3.42",
"contentHash": "68HPjhersNpssbmEMUHdMw3073MHfGTfrkbRk9eILKbNPFfPFck7m4y9BlAi6DaguUJaeKxgyIojXF3SQrF8/A=="
},
"nanoFramework.System.Threading": {
"type": "Direct",
"requested": "[1.1.52, 1.1.52]",
"resolved": "1.1.52",
"contentHash": "kv+US/+7QKV1iT/snxBh032vwZ+3krJ4vujlSsvmS2nNj/nK64R3bq/ST3bCFquxHDD0mog8irtCBCsFazr4kA=="
},
"nanoFramework.TestFramework": {
"type": "Direct",
"requested": "[3.0.77, 3.0.77]",
Expand Down
2 changes: 2 additions & 0 deletions nanoFramework.Aws.IoTCore.Devices.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ This is an SDK for Aws IoTCore.</description>
<dependency id="nanoFramework.CoreLibrary" version="1.17.11" />
<dependency id="nanoFramework.Json" version="2.2.199" />
<dependency id="nanoFramework.M2Mqtt" version="5.1.199" />
<dependency id="nanoFramework.System.Net.WebSockets" version="1.1.151" />
<dependency id="nanoFramework.System.Text.RegularExpressions" version="1.1.128" />
</dependencies>
</metadata>
<files>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

//
// Originally by Elze Kool see http://www.microframework.nl/2009/09/05/shahmac-digest-class/
// Adjustments by Laurent Ellerbach [email protected] 2021/05/31
//

namespace System.Security.Cryptography
{
using System;

/// <summary>
/// Computes a Hash-based Message Authentication Code (HMAC) by using the System.Security.Cryptography.SHA256
/// hash function.
/// </summary>
public class HMACSHA256
{
/// <summary>
/// Gets or sets the key to use in the HMAC calculation.
/// </summary>
public byte[] Key { get; set; }

/// <summary>
/// Initializes a new instance of the System.Security.Cryptography.HMACSHA256 class
/// with the specified key data.
/// </summary>
/// <param name="key">The secret key for System.Security.Cryptography.HMACSHA256 encryption. The key
/// can be any length. However, the recommended size is 64 bytes max.</param>
public HMACSHA256(byte[] key)
{
Key = key;
}

/// <summary>
/// Computes the hash value for the specified byte array.
/// </summary>
/// <param name="buffer">The input to compute the hash code for.</param>
/// <returns>The computed hash code.</returns>
/// <exception cref="ArgumentNullException">buffer is null.</exception>
public byte[] ComputeHash(byte[] buffer)
{
if (buffer == null)
{
throw new ArgumentNullException();
}

return ComputeHMACSHA256(Key, buffer);
}

/// <summary>
/// Compute HMAC SHA-256
/// </summary>
/// <param name = "secret">Secret</param>
/// <param name = "value">Password</param>
/// <returns>32 byte HMAC_SHA256</returns>
private static byte[] ComputeHMACSHA256(byte[] secret, byte[] value)
{
// Create two arrays, bi and bo
var bi = new byte[64 + value.Length];
var bo = new byte[64 + 32];

// Copy secret to both arrays
Array.Copy(secret, bi, secret.Length);
Array.Copy(secret, bo, secret.Length);

for (var i = 0; i < 64; i++)
{
// Xor bi with 0x36
bi[i] = (byte)(bi[i] ^ 0x36);

// Xor bo with 0x5c
bo[i] = (byte)(bo[i] ^ 0x5c);
}

// Append value to bi
Array.Copy(value, 0, bi, 64, value.Length);

var sha256 = SHA256.Create();
// Append SHA256(bi) to bo
var sha_bi = sha256.ComputeHash(bi);
Array.Copy(sha_bi, 0, bo, 64, 32);

// Return SHA256(bo)
return sha256.ComputeHash(bo);
}
}
}
Loading