Skip to content

Commit

Permalink
add model for ACME directory
Browse files Browse the repository at this point in the history
  • Loading branch information
fszlin committed Jul 20, 2017
1 parent 1a1a748 commit 5113e39
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 27 deletions.
108 changes: 108 additions & 0 deletions src/Certes/Acme/AcmeDirectory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;

namespace Certes.Acme
{
/// <summary>
/// Represents the ACME directory.
/// </summary>
public class AcmeDirectory
{
/// <summary>
/// Gets or sets the new nonce endpoint.
/// </summary>
/// <value>
/// The new nonce endpoint.
/// </value>
[JsonProperty("new-nonce")]
public Uri NewNonce { get; set; }

/// <summary>
/// Gets or sets the new certificate endpoint.
/// </summary>
/// <value>
/// The new certificate endpoint.
/// </value>
[JsonProperty("new-cert")]
public Uri NewCert { get; set; }

/// <summary>
/// Gets or sets the new authorization endpoint.
/// </summary>
/// <value>
/// The new authorization endpoint.
/// </value>
[JsonProperty("new-authz")]
public Uri NewAuthz { get; set; }

/// <summary>
/// Gets or sets the revoke cert.
/// </summary>
/// <value>
/// The revoke cert.
/// </value>
[JsonProperty("revoke-cert")]
public Uri RevokeCert { get; set; }

/// <summary>
/// Gets or sets the key change endpoint.
/// </summary>
/// <value>
/// The key change endpoint.
/// </value>
[JsonProperty("key-change")]
public Uri KeyChange { get; set; }

/// <summary>
/// Gets or sets the new registration endpoint.
/// </summary>
/// <value>
/// The new registration endpoint.
/// </value>
[JsonProperty("new-reg")]
public Uri NewReg { get; set; }

/// <summary>
/// Gets or sets the metadata.
/// </summary>
/// <value>
/// The metadata.
/// </value>
[JsonProperty("meta")]
public AcmeDirectoryMeta Meta { get; set; }

/// <summary>
/// Represents the metadata for ACME directory.
/// </summary>
public class AcmeDirectoryMeta
{
/// <summary>
/// Gets or sets the terms of service.
/// </summary>
/// <value>
/// The terms of service.
/// </value>
[JsonProperty("terms-of-service")]
public Uri TermsOfService { get; set; }

/// <summary>
/// Gets or sets the website.
/// </summary>
/// <value>
/// The website.
/// </value>
[JsonProperty("website")]
public Uri Website { get; set; }

/// <summary>
/// Gets or sets the caa identities.
/// </summary>
/// <value>
/// The caa identities.
/// </value>
[JsonProperty("caa-identities")]
public IList<string> CaaIdentities { get; set; }
}
}
}
16 changes: 13 additions & 3 deletions src/Certes/Acme/AcmeHttpHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
using System.Text;
using System.Threading.Tasks;

using AcmeDirectory = System.Collections.Generic.Dictionary<string, System.Object>;

namespace Certes.Acme
{
/// <summary>
Expand Down Expand Up @@ -61,7 +59,19 @@ public AcmeHttpHandler(Uri serverUri, HttpMessageHandler httpMessageHandler = nu
public async Task<Uri> GetResourceUri(string resourceType)
{
await FetchDirectory(false);
return new Uri(this.directory[resourceType] as String);
var resourceUri =
ResourceTypes.NewRegistration == resourceType ? this.directory.NewReg :
ResourceTypes.NewAuthorization == resourceType ? this.directory.NewAuthz :
ResourceTypes.NewCertificate == resourceType ? this.directory.NewCert :
ResourceTypes.RevokeCertificate == resourceType ? this.directory.RevokeCert :
null;

if (resourceUri == null)
{
throw new Exception($"Unsupported resource type '{resourceType}'.");
}

return resourceUri;
}

/// <summary>
Expand Down
19 changes: 16 additions & 3 deletions src/Certes/Acme/AuthorizationIdentifier.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
namespace Certes.Acme
using System;

namespace Certes.Acme
{
/// <summary>
/// Represents the identifier for ACME Authorization.
/// </summary>
public class AuthorizationIdentifier
public class AuthorizationIdentifier : IEquatable<AuthorizationIdentifier>
{
/// <summary>
/// Gets or sets the type.
Expand Down Expand Up @@ -42,7 +44,18 @@ public override int GetHashCode()
/// </returns>
public override bool Equals(object obj)
{
var other = obj as AuthorizationIdentifier;
return this.Equals(obj as AuthorizationIdentifier);
}

/// <summary>
/// Determines whether the specified <see cref="AuthorizationIdentifier" />, is equal to this instance.
/// </summary>
/// <param name="other">The <see cref="AuthorizationIdentifier" /> to compare with this instance.</param>
/// <returns>
/// <c>true</c> if the specified <see cref="AuthorizationIdentifier" /> is equal to this instance; otherwise, <c>false</c>.
/// </returns>
public bool Equals(AuthorizationIdentifier other)
{
return other?.Type == this.Type && other?.Value == this.Value;
}
}
Expand Down
8 changes: 5 additions & 3 deletions test/Certes.Tests.Web/Certes.Tests.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@

<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
<RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
</PropertyGroup>

<ItemGroup>
<Compile Include="..\..\AssemblyInfo.Shared.cs" Link="Properties\AssemblyInfo.Shared.cs" />
<Compile Remove="wwwroot\**" />
<Content Remove="wwwroot\**" />
<EmbeddedResource Remove="wwwroot\**" />
<None Remove="wwwroot\**" />
</ItemGroup>

<ItemGroup>
<Folder Include="wwwroot\" />
<Compile Include="..\..\AssemblyInfo.Shared.cs" Link="Properties\AssemblyInfo.Shared.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.1.1" />
Expand Down
31 changes: 13 additions & 18 deletions test/Certes.Tests/AcmeClientTests.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
using Certes.Acme;
using Certes.Json;
using Certes.Jws;
using Certes.Pkcs;
using Moq;
using Moq.Protected;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Certes.Json;
using Xunit;

namespace Certes.Tests
Expand All @@ -24,20 +22,17 @@ public class AcmeClientTests
private const string NonceFormat = "nonce-{0}";
private readonly Uri server = new Uri("http://example.com/dir");
private readonly Uri tos = new Uri("http://example.com/tos");
private readonly Dictionary<string, Uri> legacyDictData = new Dictionary<string, Uri>
{
{ "new-authz", new Uri("http://example.com/new-authz") },
{ "new-cert", new Uri("http://example.com/new-cert") },
{ "new-reg", new Uri("http://example.com/new-reg") },
{ "revoke-cert", new Uri("http://example.com/revoke-cert") },
};
private readonly Dictionary<string, Object> dictData = new Dictionary<string, Object>

private readonly AcmeDirectory acmeDict = new AcmeDirectory
{
{ "meta", new Dictionary<string, Object> { { "terms-of-service", "http://example.com/tos.pdf" } } },
{ "new-authz", "http://example.com/new-authz" },
{ "new-cert", "http://example.com/new-cert" },
{ "new-reg", "http://example.com/new-reg" },
{ "revoke-cert", "http://example.com/revoke-cert" },
Meta = new AcmeDirectory.AcmeDirectoryMeta
{
TermsOfService = new Uri("http://example.com/tos.pdf")
},
NewAuthz = new Uri("http://example.com/new-authz"),
NewCert = new Uri("http://example.com/new-cert"),
NewReg = new Uri("http://example.com/new-reg"),
RevokeCert = new Uri("http://example.com/revoke-cert")
};

private int nonce = 0;
Expand All @@ -49,7 +44,7 @@ public async Task CanCreateRegistration()
var regLocation = new Uri("http://example.com/reg/1");
var mock = MockHttp(async req =>
{
if (req.Method == HttpMethod.Post && req.RequestUri == new Uri(dictData["new-reg"] as String))
if (req.Method == HttpMethod.Post && req.RequestUri == acmeDict.NewReg)
{
var payload = await ParsePayload<Registration>(req);
Assert.Equal(ResourceTypes.NewRegistration, payload.Resource);
Expand Down Expand Up @@ -183,7 +178,7 @@ private Mock<HttpMessageHandler> MockHttp(Func<HttpRequestMessage, Task<HttpResp
{
var resp = new HttpResponseMessage();
resp.StatusCode = HttpStatusCode.OK;
resp.Content = new StringContent(JsonConvert.SerializeObject(dictData), Encoding.UTF8, "application/json");
resp.Content = new StringContent(JsonConvert.SerializeObject(acmeDict), Encoding.UTF8, "application/json");
resp.Headers.Add("Replay-Nonce", string.Format(NonceFormat, ++this.nonce));
return resp;
Expand Down

0 comments on commit 5113e39

Please sign in to comment.