Skip to content

Commit

Permalink
Merge pull request #2446 from pomortaz/keyvault2
Browse files Browse the repository at this point in the history
Improve the GetHashCode and Equals methods in JsonWebKey
  • Loading branch information
markcowl authored Oct 11, 2016
2 parents 93c8ebc + 61ec541 commit 1eb59dc
Show file tree
Hide file tree
Showing 10 changed files with 345 additions and 164 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@
"Microsoft.Azure.KeyVault.Core": "2.0.0-preview",
"Microsoft.Azure.KeyVault.Cryptography": "2.0.0-preview",
"dotnet-test-xunit": "2.2.0-preview2-build1029",
"Microsoft.Azure.KeyVault.WebKey": "2.0.0-preview"
"Microsoft.Azure.KeyVault.WebKey": "2.0.1-preview"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"Microsoft.Azure.KeyVault": "2.0.2-preview",
"Microsoft.Azure.KeyVault.Core": "2.0.0-preview",
"Microsoft.Azure.KeyVault.Cryptography": "2.0.1-preview",
"Microsoft.Azure.KeyVault.WebKey": "2.0.0-preview"
"Microsoft.Azure.KeyVault.WebKey": "2.0.1-preview"
},
"frameworks": {
"netstandard1.5": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ public void KeyVaultUpdateKeyAttributesTest()

VerifyKeyAttributesAreEqual(updatedKey.Attributes, attributes);
VerifyKeyOperationsAreEqual(updatedKey.Key.KeyOps, operations);
updatedKey.Key.KeyOps = JsonWebKeyOperation.AllOperations;
VerifyWebKeysAreEqual(updatedKey.Key, createdKey.Key);

// Create a new version of the key
Expand All @@ -354,6 +355,7 @@ public void KeyVaultUpdateKeyAttributesTest()

VerifyKeyAttributesAreEqual(updatedKey.Attributes, attributes);
VerifyKeyOperationsAreEqual(updatedKey.Key.KeyOps, operations);
updatedKey.Key.KeyOps = JsonWebKeyOperation.AllOperations;
VerifyWebKeysAreEqual(updatedKey.Key, createdKey.Key);
}
finally
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for
// license information.
//

using Newtonsoft.Json;
using System;
using System.IO;
using System.Security.Cryptography;
using Xunit;

namespace Microsoft.Azure.KeyVault.WebKey.Tests
{
public class WebKeyAesValidationTest
{
[Fact]
public void AesKeyValidation()
{
using (Aes aes = Aes.Create())
{
var key = SerializeDeserialize(aes);
Assert.True(key.HasPrivateKey());
Assert.True(key.IsValid());

Aes secretKey = key.ToAes();
EncryptDecrypt(secretKey);

// Compare equal JSON web keys
var sameKey = new JsonWebKey(aes);
Assert.Equal(key, key);
Assert.Equal(key, sameKey);
Assert.Equal(key.GetHashCode(), sameKey.GetHashCode());
}
}

[Fact]
public void InvalidKeyOps()
{
var key = new JsonWebKey(Aes.Create());
key.KeyOps = new string[] { JsonWebKeyOperation.Encrypt, "foo" };
Assert.False(key.IsValid());
}

[Fact]
public void OctHashCode()
{
JsonWebKey key = new JsonWebKey(Aes.Create());

// Compare hash codes for unequal JWK that would not map to the same hash
Assert.NotEqual(key.GetHashCode(), new JsonWebKey() { K = key.K }.GetHashCode());
Assert.NotEqual(key.GetHashCode(), new JsonWebKey() { Kty = key.Kty }.GetHashCode());

// Compare hash codes for unequal JWK that would map to the same hash
Assert.Equal(key.GetHashCode(), new JsonWebKey() { K = key.K, Kty = key.Kty }.GetHashCode());
}


private void EncryptDecrypt(Aes aes)
{
byte[] encrypted = Encrypt("content to be encrypted", aes);

// Decrypt the bytes to a string.
Decrypt(encrypted, aes);
}

private byte[] Encrypt(string plainText, Aes aes)
{
byte[] encrypted;

// Encrypt the string to an array of bytes using encryptor.
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

// Encryption stream.
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
using (var sw = new StreamWriter(cs))
{

// write to the stream
sw.Write(plainText);
}
encrypted = ms.ToArray();
}
}
return encrypted;
}

private string Decrypt(byte[] encrypted, Aes aes)
{
string plaintext = string.Empty;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

// Create the streams used for decryption.
using (var ms = new MemoryStream(encrypted))
{
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (var sr = new StreamReader(cs))
{
// read from the stream
plaintext = sr.ReadToEnd();
}
}
}
return plaintext;
}

private JsonWebKey SerializeDeserialize(Aes aes)
{
JsonWebKey webKey = new JsonWebKey(aes);
string serializedKey = webKey.ToString();
return JsonConvert.DeserializeObject<JsonWebKey>(serializedKey);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for
// license information.
//

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using Xunit;

namespace Microsoft.Azure.KeyVault.WebKey.Tests
{
public class WebKeyHsmRsaValidationTest
{
string keyWithoutT = "{\"kid\":\"key_id\",\"kty\":\"RSA-HSM\",\"key_ops\":[\"encrypt\",\"decrypt\"],\"n\":\"1_6ZtP288hEkKML-L6nFyZh1PD1rmAgwbbwjEvTSDK_008BYWhjp_6ULy9BhWtRIytNkPkm9gzaBTrCpp-vyDXPGa836Htp-w8u5JmxoUZchJh576m3m-8ZYWTmZSAp5SpruyKAmLSxPJHEWPXQntnmuTMjb9HBT9Ltrwc0ZDk-jsMLYunDJrNmrRUxQgb0zQ_Tl5fJjj8j-0KVx2RXtbfWFvf5fRdBYyP3m0aUpoopQPwtXszD2LcSKMJ_TnmnvMWr8MOA5aRlBaGdBk7zBgRafvDPam3Q2AvFA9mfcAVncpfZ3JFm73VARw6MofXtRqOHtZ7y4oNbY95xXwU2r6w\",\"e\":\"AQAB\"}";
string keyWithT = "{\"kid\":\"key_id\",\"kty\":\"RSA-HSM\",\"key_ops\":[\"encrypt\",\"decrypt\"],\"key_hsm\":\"T-TOKEN\"}";

[Fact]
public void RsaHsmValidation()
{
var keyNoT = JsonConvert.DeserializeObject<JsonWebKey>(keyWithoutT);
var keyT = JsonConvert.DeserializeObject<JsonWebKey>(keyWithT);

Assert.True(keyNoT.IsValid());
Assert.False(keyNoT.HasPrivateKey());

Assert.True(keyT.IsValid());
Assert.False(keyT.HasPrivateKey());
}

[Fact]
public void RsaHsmHashCode()
{
var keyNoT = JsonConvert.DeserializeObject<JsonWebKey>(keyWithoutT);
var keyT = JsonConvert.DeserializeObject<JsonWebKey>(keyWithT);

Assert.NotEqual(keyT.GetHashCode(), keyNoT.GetHashCode());

// Compare hash codes for unequal JWK that would not map to the same hash
Assert.NotEqual(keyT.GetHashCode(), new JsonWebKey() { Kid = keyT.Kid, T = keyT.T }.GetHashCode());
Assert.NotEqual(keyT.GetHashCode(), new JsonWebKey() { Kid = keyT.Kid, Kty = keyT.Kty }.GetHashCode());
Assert.NotEqual(keyNoT.GetHashCode(), new JsonWebKey().GetHashCode());

// Compare hash codes for unequal JWK that would map to the same hash
Assert.Equal(keyT.GetHashCode(),
new JsonWebKey() { Kid = keyT.Kid, T = keyT.T, Kty = keyT.Kty }.GetHashCode());
Assert.Equal(keyNoT.GetHashCode(), new JsonWebKey() { Kid = keyT.Kid }.GetHashCode());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
"dependencies": {
"dotnet-test-xunit": "2.2.0-preview2-build1029",
"Microsoft.Azure.KeyVault.WebKey": "2.0.0-preview",
"Microsoft.Azure.KeyVault.WebKey": "2.0.1-preview",
"xunit": "2.2.0-beta2-build3300"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace Microsoft.Azure.KeyVault.WebKey
{
public class Base64UrlJsonConverter : JsonConverter
internal class Base64UrlJsonConverter : JsonConverter
{
/// <summary>
/// Converts a byte array to a Base64Url encoded string
Expand Down
Loading

0 comments on commit 1eb59dc

Please sign in to comment.