Skip to content

Commit

Permalink
Merge pull request #2 from PKISharp/master
Browse files Browse the repository at this point in the history
Update master
  • Loading branch information
WouterTinus authored Feb 17, 2019
2 parents 609f519 + ba46184 commit 0662c0e
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 19 deletions.
21 changes: 19 additions & 2 deletions src/ACMESharp/Authorizations/AuthorizationDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ public static IChallengeValidationDetails DecodeChallengeValidation(

switch (challengeType)
{
case "dns-01":
case Dns01ChallengeValidationDetails.Dns01ChallengeType:
return ResolveChallengeForDns01(authz, challenge, signer);
case "http-01":
case Http01ChallengeValidationDetails.Http01ChallengeType:
return ResolveChallengeForHttp01(authz, challenge, signer);
case TlsAlpn01ChallengeValidationDetails.TlsAlpn01ChallengeType:
return ResolveChallengeForTlsAlpn01(authz, challenge, signer);
}

throw new NotImplementedException(
Expand Down Expand Up @@ -78,5 +80,20 @@ public static Http01ChallengeValidationDetails ResolveChallengeForHttp01(
HttpResourceValue = keyAuthz,
};
}

/// <summary>
/// </summary>
/// <remarks>
/// https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05
/// </remarks>
public static TlsAlpn01ChallengeValidationDetails ResolveChallengeForTlsAlpn01(
Authorization authz, Challenge challenge, IJwsTool signer)
{
var keyAuthz = JwsHelper.ComputeKeyAuthorization(signer, challenge.Token);
return new TlsAlpn01ChallengeValidationDetails
{
TokenValue = keyAuthz,
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace ACMESharp.Authorizations
{
/// <summary>
/// https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05
/// </summary>
public class TlsAlpn01ChallengeValidationDetails : IChallengeValidationDetails
{
public const string TlsAlpn01ChallengeType = "tls-alpn-01";
public const string AlpnExtensionName = "acme-tls/1";
public const string AcmeIdentifierExtension = "acmeIdentifier";

public string ChallengeType => TlsAlpn01ChallengeType;

public string TokenValue { get; set; }
}
}
24 changes: 18 additions & 6 deletions src/ACMESharp/Crypto/JOSE/Impl/ESJwsTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class ESJwsTool : IJwsTool
{
private HashAlgorithmName _shaName;
private ECDsa _dsa;
private object _jwk;
private ESJwk _jwk;

/// <summary>
/// Specifies the size in bits of the SHA-2 hash function to use.
Expand Down Expand Up @@ -110,6 +110,22 @@ public void Import(string exported)
// }
// }

// As per RFC 7638 Section 3, these are the *required* elements of the
// JWK and are sorted in lexicographic order to produce a canonical form
class ESJwk
{
[JsonProperty(Order = 1)]
public string crv;

[JsonProperty(Order = 2)]
public string kty = "EC";

[JsonProperty(Order = 3)]
public string x;

[JsonProperty(Order = 4)]
public string y;
}

public object ExportJwk(bool canonical = false)
{
Expand All @@ -119,13 +135,9 @@ public object ExportJwk(bool canonical = false)
if (_jwk == null)
{
var keyParams = _dsa.ExportParameters(false);
_jwk = new
_jwk = new ESJwk
{
// As per RFC 7638 Section 3, these are the *required* elements of the
// JWK and are sorted in lexicographic order to produce a canonical form

crv = CurveName,
kty = "EC", // https://tools.ietf.org/html/rfc7518#section-6.2
x = CryptoHelper.Base64.UrlEncode(keyParams.Q.X),
y = CryptoHelper.Base64.UrlEncode(keyParams.Q.Y),
};
Expand Down
24 changes: 17 additions & 7 deletions src/ACMESharp/Crypto/JOSE/Impl/RSJwsTool.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.IO;
using System.Security.Cryptography;
using Newtonsoft.Json;
Expand All @@ -13,7 +13,7 @@ public class RSJwsTool : IJwsTool
{
private HashAlgorithm _sha;
private RSACryptoServiceProvider _rsa;
private object _jwk;
private RSJwk _jwk;

/// <summary>
/// Specifies the size in bits of the SHA-2 hash function to use.
Expand Down Expand Up @@ -87,6 +87,20 @@ public void Import(string exported)
// }
// }

// As per RFC 7638 Section 3, these are the *required* elements of the
// JWK and are sorted in lexicographic order to produce a canonical form
class RSJwk
{
[JsonProperty(Order = 1)]
public string e;

[JsonProperty(Order = 2)]
public string kty = "RSA";

[JsonProperty(Order = 3)]
public string n;
}

public object ExportJwk(bool canonical = false)
{
// Note, we only produce a canonical form of the JWK
Expand All @@ -95,13 +109,9 @@ public object ExportJwk(bool canonical = false)
if (_jwk == null)
{
var keyParams = _rsa.ExportParameters(false);
_jwk = new
_jwk = new RSJwk
{
// As per RFC 7638 Section 3, these are the *required* elements of the
// JWK and are sorted in lexicographic order to produce a canonical form

e = CryptoHelper.Base64.UrlEncode(keyParams.Exponent),
kty = "RSA", // https://tools.ietf.org/html/rfc7518#section-6.3
n = CryptoHelper.Base64.UrlEncode(keyParams.Modulus),
};
}
Expand Down
4 changes: 2 additions & 2 deletions src/ACMESharp/HTTP/Link.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Text.RegularExpressions;

namespace ACMESharp.HTTP
Expand All @@ -19,7 +19,7 @@ public class Link
/// <summary>
/// Regex pattern to match and extract the components of an HTTP related link header.
/// </summary>
public static readonly Regex LinkHeaderRegex = new Regex("<(.+)>;rel=\"(.+)\"");
public static readonly Regex LinkHeaderRegex = new Regex("<(.+)>;[ ]?rel=\"(.+)\"");

public const string LinkHeaderFormat = "<{0}>;rel={1}";

Expand Down
4 changes: 2 additions & 2 deletions src/ACMESharp/Protocol/AcmeProtocolClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public async Task<AccountDetails> CreateAccountAsync(IEnumerable<string> contact
{
Contact = contacts,
TermsOfServiceAgreed = termsOfServiceAgreed,
ExternalAccountBinding = (JwsSignedPayload)externalAccountBinding,
ExternalAccountBinding = externalAccountBinding,
};
var resp = await SendAcmeAsync(
new Uri(_http.BaseAddress, Directory.NewAccount),
Expand Down Expand Up @@ -943,4 +943,4 @@ public void Dispose()
}
#endregion
}
}
}
45 changes: 45 additions & 0 deletions test/ACMESharp.UnitTests/JwsTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using ACMESharp.Crypto;
using ACMESharp.Crypto.JOSE.Impl;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ACMESharp.UnitTests
Expand Down Expand Up @@ -305,5 +307,48 @@ public void TestRfc7515Example_A_2_1()
string sigB64uActual = CryptoHelper.Base64.UrlEncode(sigActual);
Assert.AreEqual(sigB64uExpected, sigB64uActual);
}

[TestMethod]
public void SerDesEC()
{
var rng = RandomNumberGenerator.Create();
for (var i = 0; i < 1000; i++) {
var original = new ESJwsTool(); // Default for ISigner
original.Init();
var rawX = new byte[8034];
rng.GetBytes(rawX);
var sigX = original.Sign(rawX);

var exported = original.Export();
var copy = new ESJwsTool();
copy.Init();
copy.Import(exported);
var verified = copy.Verify(rawX, sigX);

Assert.AreEqual(true, verified);
}
}

[TestMethod]
public void SerDesRSA()
{
var rng = RandomNumberGenerator.Create();
for (var i = 0; i < 1000; i++)
{
var original = new RSJwsTool(); // Default for ISigner
original.Init();
var rawX = new byte[8034];
rng.GetBytes(rawX);
var sigX = original.Sign(rawX);

var exported = original.Export();
var copy = new RSJwsTool();
copy.Init();
copy.Import(exported);
var verified = copy.Verify(rawX, sigX);

Assert.AreEqual(true, verified);
}
}
}
}

0 comments on commit 0662c0e

Please sign in to comment.