private static async Task <IOrderContext> AuthorizeHttp(AcmeContext ctx, IList <string> hosts) { for (var i = 0; i < 10; ++i) { var orderCtx = await ctx.NewOrder(hosts); var order = await orderCtx.Resource(); Assert.NotNull(order); Assert.Equal(hosts.Count, order.Authorizations?.Count); Assert.True(OrderStatus.Pending == order.Status || OrderStatus.Ready == order.Status || OrderStatus.Processing == order.Status); var authrizations = await orderCtx.Authorizations(); foreach (var authz in authrizations) { var httpChallenge = await authz.Http(); await httpChallenge.Validate(); } while (true) { await Task.Delay(100); var statuses = new List <AuthorizationStatus>(); foreach (var authz in authrizations) { var a = await authz.Resource(); statuses.Add(a.Status ?? AuthorizationStatus.Pending); } if (statuses.All(s => s == AuthorizationStatus.Valid)) { return(orderCtx); } if (statuses.Any(s => s == AuthorizationStatus.Invalid)) { break; } } } Assert.True(false, "Authorization failed."); return(null); }
public async Task Account() { var acmeDir = await IntegrationHelper.GetAcmeUriV2(); var accountKey = Helper.GetKeyV2(KeyAlgorithm.RS256); var httpClient = IntegrationHelper.GetAcmeHttpClient(acmeDir); var acme = new AcmeContext(acmeDir, accountKey, httpClient); var account = await acme.Account(); var order = await acme.NewOrder(new[] { "www.certes-ci.dymetis.com" }); var authz = (await order.Authorizations()).First(); var httpChallenge = await authz.Http(); var token = httpChallenge.Token; var keyAuthz = httpChallenge.KeyAuthz; var orderUri = order.Location; await httpChallenge.Validate(); var res = await authz.Resource(); while (res.Status != AuthorizationStatus.Valid && res.Status != AuthorizationStatus.Invalid) { res = await authz.Resource(); } acme = new AcmeContext(acmeDir, accountKey, httpClient); order = acme.Order(orderUri); var privateKey = KeyFactory.NewKey(KeyAlgorithm.ES256); var cert = await order.Generate(new CsrInfo { CountryName = "CA", State = "Ontario", Locality = "Toronto", Organization = "Certes", OrganizationUnit = "Dev", CommonName = "www.certes-ci.dymetis.com", }, privateKey, null); var pfxBuilder = cert.ToPfx(privateKey); pfxBuilder.AddTestCerts(); var pfx = pfxBuilder.Build("my-cert", "abcd1234"); }
public async Task CanGenerateCertificateTlsAlpn() { var dirUri = await GetAcmeUriV2(); var hosts = new[] { $"{DomainSuffix}.tls-alpn.certes-ci.dymetis.com" }; var ctx = new AcmeContext(dirUri, GetKeyV2(), http: GetAcmeHttpClient(dirUri)); var orderCtx = await ctx.NewOrder(hosts); var order = await orderCtx.Resource(); Assert.NotNull(order); Assert.Equal(hosts.Length, order.Authorizations?.Count); Assert.True( OrderStatus.Ready == order.Status || OrderStatus.Pending == order.Status || OrderStatus.Processing == order.Status, $"Invalid order status: {order.Status}"); var authrizations = await orderCtx.Authorizations(); foreach (var authzCtx in authrizations) { var authz = await authzCtx.Resource(); var tlsAlpnChallenge = await authzCtx.TlsAlpn(); var alpnCertKey = KeyFactory.NewKey(KeyAlgorithm.ES256); var alpnCert = ctx.AccountKey.TlsAlpnCertificate(tlsAlpnChallenge.Token, authz.Identifier.Value, alpnCertKey); await SetupValidationResponder(authz, alpnCert, alpnCertKey); await tlsAlpnChallenge.Validate(); } while (true) { await Task.Delay(100); var statuses = new List <AuthorizationStatus>(); foreach (var authz in authrizations) { var a = await authz.Resource(); statuses.Add(a.Status ?? AuthorizationStatus.Pending); } if (statuses.All(s => s == AuthorizationStatus.Valid || s == AuthorizationStatus.Invalid)) { break; } } var certKey = KeyFactory.NewKey(KeyAlgorithm.RS256); var finalizedOrder = await orderCtx.Finalize(new CsrInfo { CountryName = "CA", State = "Ontario", Locality = "Toronto", Organization = "Certes", OrganizationUnit = "Dev", CommonName = hosts[0], }, certKey); var certChain = await orderCtx.Download(null); var pfxBuilder = certChain.ToPfx(certKey); pfxBuilder.AddTestCerts(); var pfx = pfxBuilder.Build("my-pfx", "abcd1234"); // revoke certificate var certParser = new X509CertificateParser(); var certificate = certParser.ReadCertificate(certChain.Certificate.ToDer()); var der = certificate.GetEncoded(); await ctx.RevokeCertificate(der, RevocationReason.Unspecified, null); // deactivate authz so the subsequence can trigger challenge validation foreach (var authz in authrizations) { var authzRes = await authz.Deactivate(); Assert.Equal(AuthorizationStatus.Deactivated, authzRes.Status); } }
protected async Task CanGenerateCertificateWithEC(KeyAlgorithm algo) { var dirUri = await GetAcmeUriV2(); var hosts = new[] { $"www-ec-{DomainSuffix}.{algo}.certes-ci.dymetis.com".ToLower() }; var ctx = new AcmeContext(dirUri, GetKeyV2(algo), http: GetAcmeHttpClient(dirUri)); var orderCtx = await ctx.NewOrder(hosts); var order = await orderCtx.Resource(); Assert.NotNull(order); Assert.Equal(hosts.Length, order.Authorizations?.Count); Assert.True(OrderStatus.Pending == order.Status || OrderStatus.Processing == order.Status); var authrizations = await orderCtx.Authorizations(); foreach (var authz in authrizations) { var httpChallenge = await authz.Http(); await httpChallenge.Validate(); } while (true) { await Task.Delay(100); var statuses = new List <AuthorizationStatus>(); foreach (var authz in authrizations) { var a = await authz.Resource(); statuses.Add(a.Status ?? AuthorizationStatus.Pending); } if (statuses.All(s => s == AuthorizationStatus.Valid || s == AuthorizationStatus.Invalid)) { break; } } var certKey = KeyFactory.NewKey(algo); var finalizedOrder = await orderCtx.Finalize(new CsrInfo { CountryName = "CA", State = "Ontario", Locality = "Toronto", Organization = "Certes", OrganizationUnit = "Dev", CommonName = hosts[0], }, certKey); var cert = await orderCtx.Download(); var x509 = new X509Certificate2(cert.Certificate.ToDer()); Assert.Contains(hosts[0], x509.Subject); // deactivate authz so the subsequence can trigger challenge validation foreach (var authz in authrizations) { var authzRes = await authz.Deactivate(); Assert.Equal(AuthorizationStatus.Deactivated, authzRes.Status); } }
protected async Task <IOrderContext> AuthzDns(AcmeContext ctx, string[] hosts) { var orderCtx = await ctx.NewOrder(hosts); var order = await orderCtx.Resource(); Assert.NotNull(order); Assert.Equal(hosts.Length, order.Authorizations?.Count); Assert.True(OrderStatus.Pending == order.Status || OrderStatus.Processing == order.Status); var authrizations = await orderCtx.Authorizations(); var tokens = new Dictionary <string, string>(); foreach (var authz in authrizations) { var res = await authz.Resource(); var dnsChallenge = await authz.Dns(); tokens.Add(res.Identifier.Value, dnsChallenge.Token); } await DeployDns01(KeyAlgorithm.ES256, tokens); await Task.Delay(1000); foreach (var authz in authrizations) { var res = await authz.Resource(); var dnsChallenge = await authz.Dns(); await dnsChallenge.Validate(); } while (true) { await Task.Delay(100); var statuses = new List <AuthorizationStatus>(); foreach (var authz in authrizations) { var a = await authz.Resource(); if (AuthorizationStatus.Invalid == a.Status) { return(null); } else { statuses.Add(a.Status ?? AuthorizationStatus.Pending); } } if (statuses.All(s => s == AuthorizationStatus.Valid)) { break; } } return(orderCtx); }