public async Task <object> Execute(ArgumentSyntax syntax) { var(serverUri, key) = await ReadAccountKey(syntax, true, false); var orderUri = syntax.GetParameter <Uri>(OrderIdParam, true); var domain = syntax.GetParameter <string>(DomainParam, true); var azureCredentials = await ReadAzureCredentials(syntax); var resourceGroup = syntax.GetOption <string>(AzureResourceGroupOption, true); var appName = syntax.GetParameter <string>(AppNameParam, true); var appSlot = syntax.GetOption <string>(SlotOption, false); var privKey = await syntax.ReadKey(PrivateKeyOption, "CERTES_CERT_KEY", File, environment, true); var acme = ContextFactory.Invoke(serverUri, key); var orderCtx = acme.Order(orderUri); var order = await orderCtx.Resource(); if (order.Certificate == null) { throw new CertesCliException(string.Format(Strings.ErrorOrderIncompleted, orderCtx.Location)); } var cert = await orderCtx.Download(); var x509Cert = new X509Certificate2(cert.Certificate.ToDer()); var thumbprint = x509Cert.Thumbprint; using (var client = clientFactory.Invoke(azureCredentials)) { client.SubscriptionId = azureCredentials.DefaultSubscriptionId; var certUploaded = await FindCertificate(client, resourceGroup, thumbprint); if (certUploaded == null) { certUploaded = await UploadCertificate( client, resourceGroup, appName, appSlot, cert.ToPfx(privKey), thumbprint); } var hostNameBinding = new HostNameBindingInner { SslState = SslState.SniEnabled, Thumbprint = certUploaded.Thumbprint, }; var hostName = string.IsNullOrWhiteSpace(appSlot) ? await client.WebApps.CreateOrUpdateHostNameBindingAsync( resourceGroup, appName, domain, hostNameBinding) : await client.WebApps.CreateOrUpdateHostNameBindingSlotAsync( resourceGroup, appName, domain, hostNameBinding, appSlot); return(new { data = hostName }); } }
public async Task <object> Execute(ArgumentSyntax syntax) { var(serverUri, key) = await ReadAccountKey(syntax, true, false); var orderUri = syntax.GetParameter <Uri>(OrderIdParam, true); var domain = syntax.GetParameter <string>(DomainParam, true); var typeStr = syntax.GetParameter <string>(ChallengeTypeParam, true); var type = string.Equals(typeStr, "dns", OrdinalIgnoreCase) ? Dns01 : string.Equals(typeStr, "http", OrdinalIgnoreCase) ? Http01 : throw new ArgumentSyntaxException(string.Format(Strings.ErrorInvalidChallengeType, typeStr)); logger.Debug("Validating authz on '{0}'.", serverUri); var acme = ContextFactory.Invoke(serverUri, key); var orderCtx = acme.Order(orderUri); var authzCtx = await orderCtx.Authorization(domain) ?? throw new CertesCliException(string.Format(Strings.ErrorIdentifierNotAvailable, domain)); var challengeCtx = await authzCtx.Challenge(type) ?? throw new CertesCliException(string.Format(Strings.ErrorChallengeNotAvailable, typeStr)); logger.Debug("Validating challenge '{0}'.", challengeCtx.Location); var challenge = await challengeCtx.Validate(); return(new { location = challengeCtx.Location, resource = challenge, }); }
public async Task <object> Execute(ArgumentSyntax syntax) { var keyPath = syntax.GetParameter <string>(PrivateKeyOption, true); var pwd = syntax.GetParameter <string>(PasswordParam, true); var(location, cert) = await DownloadCertificate(syntax); var pfxName = string.Format(CultureInfo.InvariantCulture, "[certes] {0:yyyyMMddhhmmss}", DateTime.UtcNow); var privKey = await syntax.ReadKey(PrivateKeyOption, "CERTES_CERT_KEY", File, environment, true); var pfx = cert.ToPfx(privKey).Build(pfxName, pwd); var outPath = syntax.GetOption <string>(OutOption); if (string.IsNullOrWhiteSpace(outPath)) { return(new { location, pfx, }); } else { logger.Debug("Saving certificate to '{0}'.", outPath); await File.WriteAllBytes(outPath, pfx); return(new { location, }); } }
public async Task <object> Execute(ArgumentSyntax syntax) { var(serverUri, key) = await ReadAccountKey(syntax, true, false); var orderUri = syntax.GetParameter <Uri>(OrderIdParam, true); var domain = syntax.GetParameter <string>(DomainParam, true); var azureCredentials = await ReadAzureCredentials(syntax); var resourceGroup = syntax.GetOption <string>(AzureResourceGroupOption, true); var acme = ContextFactory.Invoke(serverUri, key); var orderCtx = acme.Order(orderUri); var authzCtx = await orderCtx.Authorization(domain) ?? throw new Exception(string.Format(Strings.ErrorIdentifierNotAvailable, domain)); var challengeCtx = await authzCtx.Dns() ?? throw new Exception(string.Format(Strings.ErrorChallengeNotAvailable, "dns")); var authz = await authzCtx.Resource(); var dnsValue = acme.AccountKey.DnsTxt(challengeCtx.Token); using (var client = clientFactory.Invoke(azureCredentials)) { client.SubscriptionId = azureCredentials.DefaultSubscriptionId; var idValue = authz.Identifier.Value; var zone = await FindDnsZone(client, idValue); var name = zone.Name.Length == idValue.Length ? "_acme-challenge" : "_acme-challenge." + idValue.Substring(0, idValue.Length - zone.Name.Length - 1); logger.Debug("Adding TXT record '{0}' for '{1}' in '{2}' zone.", dnsValue, name, zone.Name); var recordSet = await client.RecordSets.CreateOrUpdateAsync( resourceGroup, zone.Name, name, RecordType.TXT, new RecordSetInner( name : name, tTL : 300, txtRecords : new[] { new TxtRecord(new[] { dnsValue }) })); return(new { data = recordSet }); } }
public async Task <object> Execute(ArgumentSyntax syntax) { var acct = await ReadAccountKey(syntax); logger.Debug("Creating new account on '{0}'.", acct.Server); var key = acct.Key ?? KeyFactory.NewKey(KeyAlgorithm.ES256); var email = syntax.GetParameter <string>(EmailParam, true); var acme = ContextFactory.Invoke(acct.Server, key); var acctCtx = await acme.NewAccount(email, true); var outPath = syntax.GetOption <string>(OutOption); if (!string.IsNullOrWhiteSpace(outPath)) { logger.Debug("Saving new account key to '{0}'.", outPath); var pem = key.ToPem(); await File.WriteAllText(outPath, pem); } else { logger.Debug("Saving new account key to user settings."); await UserSettings.SetAccountKey(acct.Server, key); } return(new { location = acctCtx.Location, resource = await acctCtx.Resource() }); }
public async Task <object> Execute(ArgumentSyntax syntax) { var(serverUri, key) = await ReadAccountKey(syntax, true, false); var orderUri = syntax.GetParameter <Uri>(OrderIdParam, true); var distinguishedName = syntax.GetOption <string>(DnOption); var outPath = syntax.GetOption <string>(OutOption); var keyAlgorithmStr = syntax.GetOption <string>(KeyAlgorithmOption); var keyAlgorithm = keyAlgorithmStr == null ? KeyAlgorithm.ES256 : Enum.TryParse <KeyAlgorithm>(keyAlgorithmStr, out var alg) ? alg : throw new ArgumentSyntaxException(string.Format(Strings.ErrorInvalidkeyAlgorithm, keyAlgorithmStr)); var providedKey = await syntax.ReadKey(PrivateKeyOption, "CERTES_CERT_KEY", File, environment); var privKey = providedKey ?? KeyFactory.NewKey(keyAlgorithm); logger.Debug("Finalizing order from '{0}'.", serverUri); var acme = ContextFactory.Invoke(serverUri, key); var orderCtx = acme.Order(orderUri); var csr = await orderCtx.CreateCsr(privKey); if (!string.IsNullOrWhiteSpace(distinguishedName)) { csr.AddName(distinguishedName); } var order = await orderCtx.Finalize(csr.Generate()); // output private key only if it is generated and not being saved if (string.IsNullOrWhiteSpace(outPath) && providedKey == null) { return(new { location = orderCtx.Location, privateKey = privKey.ToDer(), resource = order, }); } else { if (providedKey == null) { await File.WriteAllText(outPath, privKey.ToPem()); } return(new { location = orderCtx.Location, resource = order, }); } }
public async Task <object> Execute(ArgumentSyntax syntax) { var(serverUri, key) = await ReadAccountKey(syntax, true, false); var orderUri = syntax.GetParameter <Uri>(OrderIdParam, true); var domain = syntax.GetParameter <string>(DomainParam, true); var typeStr = syntax.GetParameter <string>(ChallengeTypeParam, true); var type = string.Equals(typeStr, "dns", OrdinalIgnoreCase) ? Dns01 : string.Equals(typeStr, "http", OrdinalIgnoreCase) ? Http01 : throw new ArgumentSyntaxException(string.Format(Strings.ErrorInvalidChallengeType, typeStr)); logger.Debug("Loading authz from '{0}'.", serverUri); var acme = ContextFactory.Invoke(serverUri, key); var orderCtx = acme.Order(orderUri); var authzCtx = await orderCtx.Authorization(domain) ?? throw new CertesCliException(string.Format(Strings.ErrorIdentifierNotAvailable, domain)); var challengeCtx = await authzCtx.Challenge(type) ?? throw new CertesCliException(string.Format(Strings.ErrorChallengeNotAvailable, typeStr)); var challenge = await challengeCtx.Resource(); if (string.Equals(type, Dns01, OrdinalIgnoreCase)) { return(new { location = challengeCtx.Location, dnsTxt = key.DnsTxt(challenge.Token), resource = challenge, }); } return(new { location = challengeCtx.Location, challengeFile = $".well-known/acme-challenge/{challenge.Token}", challengeTxt = $"{challenge.Token}.{key.Thumbprint()}", resource = challenge, keyAuthz = challengeCtx.KeyAuthz }); }
public async Task <object> Execute(ArgumentSyntax syntax) { var(serverUri, key) = await ReadAccountKey(syntax, true, false); var orderUri = syntax.GetParameter <Uri>(OrderIdParam, true); logger.Debug("Loading order from '{0}'.", serverUri); var acme = ContextFactory.Invoke(serverUri, key); var orderCtx = acme.Order(orderUri); return(new { location = orderCtx.Location, resource = await orderCtx.Resource() }); }
public async Task <object> Execute(ArgumentSyntax syntax) { var(serverUri, key) = await ReadAccountKey(syntax, true, true); var email = syntax.GetParameter <string>(EmailParam, true); logger.Debug("Updating account on '{0}'.", serverUri); var acme = ContextFactory.Invoke(serverUri, key); var acctCtx = await acme.Account(); var acct = await acctCtx.Update(new[] { $"mailto://{email}" }, true); return(new { location = acctCtx.Location, resource = acct, }); }
protected async Task <(Uri Location, CertificateChain Cert)> DownloadCertificate(ArgumentSyntax syntax) { var(serverUri, key) = await ReadAccountKey(syntax, true, true); var orderUri = syntax.GetParameter <Uri>(OrderIdParam, true); logger.Debug("Downloading certificate from '{0}'.", serverUri); var acme = ContextFactory.Invoke(serverUri, key); var orderCtx = acme.Order(orderUri); var order = await orderCtx.Resource(); if (order.Status != OrderStatus.Valid) { throw new CertesCliException( string.Format(Strings.ErrorExportInvalidOrder, order.Status)); } return(order.Certificate, await orderCtx.Download()); }
public async Task <object> Execute(ArgumentSyntax syntax) { var(serverUri, _) = await ReadAccountKey(syntax, false); var keyPath = syntax.GetParameter <string>(KeyParam, true); var pem = await File.ReadAllText(keyPath); var key = KeyFactory.FromPem(pem); logger.Debug("Setting account for '{0}'.", serverUri); var acme = ContextFactory.Invoke(serverUri, key); var acctCtx = await acme.Account(); await UserSettings.SetAccountKey(serverUri, key); return(new { location = acctCtx.Location, resource = await acctCtx.Resource() }); }