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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
bin
obj
artifacts
*.xslt.sql
*.user
*.suo
Expand Down
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project>
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<UseArtifactsOutput>true</UseArtifactsOutput>
</PropertyGroup>
</Project>

113 changes: 66 additions & 47 deletions WebPush.Test/ECKeyHelperTest.cs
Original file line number Diff line number Diff line change
@@ -1,69 +1,88 @@
using System.Linq;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Org.BouncyCastle.Crypto.Parameters;
using WebPush.Util;

namespace WebPush.Test
namespace WebPush.Test;

[TestClass]
public class ECKeyHelperTest
{
[TestClass]
public class ECKeyHelperTest
private const string TestPublicKey =
@"BCvKwB2lbVUYMFAaBUygooKheqcEU-GDrVRnu8k33yJCZkNBNqjZj0VdxQ2QIZa4kV5kpX9aAqyBKZHURm6eG1A";

private const string TestPrivateKey = @"on6X5KmLEFIVvPP3cNX9kE0OF6PV9TJQXVbnKU2xEHI";

[TestMethod]
public void TestGenerateKeys()
{
private const string TestPublicKey =
@"BCvKwB2lbVUYMFAaBUygooKheqcEU-GDrVRnu8k33yJCZkNBNqjZj0VdxQ2QIZa4kV5kpX9aAqyBKZHURm6eG1A";
var keypair = ECKeyHelper.GenerateKeys();
var publicKey = keypair.GetPublicKey();
var privateKey = keypair.GetPrivateKey();

private const string TestPrivateKey = @"on6X5KmLEFIVvPP3cNX9kE0OF6PV9TJQXVbnKU2xEHI";
var publicKeyLength = publicKey.Length;
var privateKeyLength = privateKey.Length;

[TestMethod]
public void TestGenerateKeys()
{
var keys = ECKeyHelper.GenerateKeys();
Assert.AreEqual(65, publicKeyLength);
Assert.AreEqual(32, privateKeyLength);
}

[TestMethod]
public void TestGenerateKeysNoCache()
{
var keys1 = ECKeyHelper.GenerateKeys();
var keys2 = ECKeyHelper.GenerateKeys();

var publicKey = ((ECPublicKeyParameters) keys.Public).Q.GetEncoded(false);
var privateKey = ((ECPrivateKeyParameters) keys.Private).D.ToByteArrayUnsigned();
var publicKey1 = keys1.GetPublicKey();
var privateKey1 = keys1.GetPrivateKey();

var publicKeyLength = publicKey.Length;
var privateKeyLength = privateKey.Length;
var publicKey2 = keys2.GetPublicKey();
var privateKey2 = keys2.GetPrivateKey();

Assert.AreEqual(65, publicKeyLength);
Assert.AreEqual(32, privateKeyLength);
}
Assert.IsFalse(publicKey1.SequenceEqual(publicKey2));
Assert.IsFalse(privateKey1.SequenceEqual(privateKey2));
}

[TestMethod]
public void TestGenerateKeysNoCache()
{
var keys1 = ECKeyHelper.GenerateKeys();
var keys2 = ECKeyHelper.GenerateKeys();
[TestMethod]
public void TestGetPrivateKey()
{
var privateKey = Base64UrlEncoder.DecodeBytes(TestPrivateKey);
var publicKey = Base64UrlEncoder.DecodeBytes(TestPublicKey);
var keypair = ECKeyHelper.GetKeyPair(privateKey, publicKey);

var publicKey1 = ((ECPublicKeyParameters) keys1.Public).Q.GetEncoded(false);
var privateKey1 = ((ECPrivateKeyParameters) keys1.Private).D.ToByteArrayUnsigned();
var importedPrivateKey = keypair.GetEncodedPrivateKey();
Assert.AreEqual(TestPrivateKey, importedPrivateKey);

var publicKey2 = ((ECPublicKeyParameters) keys2.Public).Q.GetEncoded(false);
var privateKey2 = ((ECPrivateKeyParameters) keys2.Private).D.ToByteArrayUnsigned();
var rawPrivateKey = keypair.GetPrivateKey();
Assert.IsTrue(privateKey.SequenceEqual(rawPrivateKey));
}

Assert.IsFalse(publicKey1.SequenceEqual(publicKey2));
Assert.IsFalse(privateKey1.SequenceEqual(privateKey2));
}
[TestMethod]
public void TestGetPublicKey()
{
var privateKey = Base64UrlEncoder.DecodeBytes(TestPrivateKey);
var publicKey = Base64UrlEncoder.DecodeBytes(TestPublicKey);
var keypair = ECKeyHelper.GetKeyPair(privateKey, publicKey);

[TestMethod]
public void TestGetPrivateKey()
{
var privateKey = UrlBase64.Decode(TestPrivateKey);
var privateKeyParams = ECKeyHelper.GetPrivateKey(privateKey);
var importedPublicKey = keypair.GetEncodedPublicKey();
Assert.AreEqual(TestPublicKey, importedPublicKey);

var importedPrivateKey = UrlBase64.Encode(privateKeyParams.D.ToByteArrayUnsigned());
var rawPublicKey = keypair.GetPublicKey();
Assert.IsTrue(publicKey.SequenceEqual(rawPublicKey));
}

Assert.AreEqual(TestPrivateKey, importedPrivateKey);
}
[TestMethod]
public void TestGetKeyPairNet()
{
var privateKey = Base64UrlEncoder.DecodeBytes(TestPrivateKey);
var publicKey = Base64UrlEncoder.DecodeBytes(TestPublicKey);

[TestMethod]
public void TestGetPublicKey()
{
var publicKey = UrlBase64.Decode(TestPublicKey);
var publicKeyParams = ECKeyHelper.GetPublicKey(publicKey);
var keypair = ECKeyHelper.GetKeyPair(privateKey, publicKey);

var importedPublicKey = UrlBase64.Encode(publicKeyParams.Q.GetEncoded(false));
var importedPublicKey = keypair.GetEncodedPublicKey();
Assert.AreEqual(TestPublicKey, importedPublicKey);

Assert.AreEqual(TestPublicKey, importedPublicKey);
}
var importedPrivateKey = keypair.GetEncodedPrivateKey();
Assert.AreEqual(TestPrivateKey, importedPrivateKey);
}
}
}
95 changes: 53 additions & 42 deletions WebPush.Test/JWSSignerTest.cs
Original file line number Diff line number Diff line change
@@ -1,52 +1,63 @@
using System.Collections.Generic;
using System;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WebPush.Util;

namespace WebPush.Test
{
[TestClass]
public class JWSSignerTest
{
private const string TestPrivateKey = @"on6X5KmLEFIVvPP3cNX9kE0OF6PV9TJQXVbnKU2xEHI";

[TestMethod]
public void TestGenerateSignature()
{
var decodedPrivateKey = UrlBase64.Decode(TestPrivateKey);
var privateKey = ECKeyHelper.GetPrivateKey(decodedPrivateKey);

var header = new Dictionary<string, object>();
header.Add("typ", "JWT");
header.Add("alg", "ES256");

var jwtPayload = new Dictionary<string, object>();
jwtPayload.Add("aud", "aud");
jwtPayload.Add("exp", 1);
jwtPayload.Add("sub", "subject");

var signer = new JwsSigner(privateKey);
var token = signer.GenerateSignature(header, jwtPayload);
namespace WebPush.Test;

var tokenParts = token.Split('.');

Assert.AreEqual(3, tokenParts.Length);

var encodedHeader = tokenParts[0];
var encodedPayload = tokenParts[1];
var signature = tokenParts[2];
[TestClass]
public class JWSSignerTest
{
private const string TestPublicKey =
@"BCvKwB2lbVUYMFAaBUygooKheqcEU-GDrVRnu8k33yJCZkNBNqjZj0VdxQ2QIZa4kV5kpX9aAqyBKZHURm6eG1A";

var decodedHeader = Encoding.UTF8.GetString(UrlBase64.Decode(encodedHeader));
var decodedPayload = Encoding.UTF8.GetString(UrlBase64.Decode(encodedPayload));
private const string TestPrivateKey = @"on6X5KmLEFIVvPP3cNX9kE0OF6PV9TJQXVbnKU2xEHI";

Assert.AreEqual(@"{""typ"":""JWT"",""alg"":""ES256""}", decodedHeader);
Assert.AreEqual(@"{""aud"":""aud"",""exp"":1,""sub"":""subject""}", decodedPayload);

var decodedSignature = UrlBase64.Decode(signature);
var decodedSignatureLength = decodedSignature.Length;
[TestMethod]
public void TestGenerateSignature()
{
var key = ECKeyHelper.GetKeyPair(Base64UrlEncoder.DecodeBytes(TestPrivateKey), Base64UrlEncoder.DecodeBytes(TestPublicKey));
var handler = new JsonWebTokenHandler
{
SetDefaultTimesOnTokenCreation = false
};
var now = DateTime.UtcNow;
var epoch = new DateTime(1970, 1, 1, 0, 0, 1, DateTimeKind.Utc);
var subject = new ClaimsIdentity([new Claim(JwtRegisteredClaimNames.Sub, "subject")]);

var isSignatureLengthValid = decodedSignatureLength == 66 || decodedSignatureLength == 64;
Assert.AreEqual(true, isSignatureLengthValid);
}
string token = handler.CreateToken(new SecurityTokenDescriptor
{
Audience = "aud",
// Expires = now.AddMinutes(1),
Expires = epoch,
// IssuedAt = now,
Subject = subject,
SigningCredentials = new SigningCredentials(new ECDsaSecurityKey(key), SecurityAlgorithms.EcdsaSha256),
});
var tokenParts = token.Split('.');

Assert.HasCount(3, tokenParts);

var encodedHeader = tokenParts[0];
var encodedPayload = tokenParts[1];
var signature = tokenParts[2];

var decodedHeader = Encoding.UTF8.GetString(Base64UrlEncoder.DecodeBytes(encodedHeader));
var decodedPayload = Encoding.UTF8.GetString(Base64UrlEncoder.DecodeBytes(encodedPayload));

Assert.AreEqual(@"{""alg"":""ES256"",""typ"":""JWT""}", decodedHeader);
Assert.Contains(@"""typ"":""JWT""", decodedHeader);
Assert.Contains(@"""alg"":""ES256""", decodedHeader);
Assert.AreEqual(@"{""aud"":""aud"",""exp"":1,""sub"":""subject""}", decodedPayload);

var decodedSignature = Base64UrlEncoder.DecodeBytes(signature);
var decodedSignatureLength = decodedSignature.Length;

var isSignatureLengthValid = decodedSignatureLength == 66 || decodedSignatureLength == 64;
Assert.IsTrue(isSignatureLengthValid);
}
}
}
39 changes: 20 additions & 19 deletions WebPush.Test/UrlBase64Test.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
using System.Linq;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WebPush.Util;

namespace WebPush.Test
[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)]

namespace WebPush.Test;

[TestClass]
public class UrlBase64Test
{
[TestClass]
public class UrlBase64Test
[TestMethod]
public void TestBase64UrlDecode()
{
[TestMethod]
public void TestBase64UrlDecode()
{
var expected = new byte[3] {181, 235, 45};
var actual = UrlBase64.Decode(@"test");
Assert.IsTrue(actual.SequenceEqual(expected));
}
var expected = new byte[3] { 181, 235, 45 };
var actual = Base64UrlEncoder.DecodeBytes(@"test");
Assert.IsTrue(actual.SequenceEqual(expected));
}

[TestMethod]
public void TestBase64UrlEncode()
{
var expected = @"test";
var actual = UrlBase64.Encode(new byte[3] {181, 235, 45});
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void TestBase64UrlEncode()
{
var expected = @"test";
var actual = Base64UrlEncoder.Encode([181, 235, 45]);
Assert.AreEqual(expected, actual);
}
}
}
Loading