コード例 #1
0
ファイル: AzureAppCommand.cs プロジェクト: yurikus/certes
        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
                });
            }
        }
コード例 #2
0
        protected async Task <RestClient> CreateAzureRestClient(ArgumentSyntax syntax)
        {
            var azSettings = await UserSettings.GetAzureSettings();

            var tenantId = syntax.GetOption <string>(AzureTenantIdOption)
                           ?? azSettings.TenantId;
            var clientId = syntax.GetOption <string>(AzureClientIdOption)
                           ?? azSettings.ClientId;
            var secret = syntax.GetOption <string>(AzureSecretOption)
                         ?? azSettings.ClientSecret;
            var subscriptionId = syntax.GetOption <string>(AzureSubscriptionIdOption)
                                 ?? azSettings.SubscriptionId;

            ValidateOption(tenantId, AzureTenantIdOption);
            ValidateOption(clientId, AzureClientIdOption);
            ValidateOption(secret, AzureSecretOption);
            ValidateOption(subscriptionId, AzureSubscriptionIdOption);

            var loginInfo = new ServicePrincipalLoginInformation
            {
                ClientId     = clientId,
                ClientSecret = secret,
            };

            return(CreateRestClient(tenantId, subscriptionId, loginInfo));
        }
コード例 #3
0
        public async Task <object> Execute(ArgumentSyntax syntax)
        {
            var talentId       = syntax.GetOption <string>(AzureTalentIdOption);
            var clientId       = syntax.GetOption <string>(AzureClientIdOption);
            var secret         = syntax.GetOption <string>(AzureSecretOption);
            var subscriptionId = syntax.GetOption <string>(AzureSubscriptionIdOption);

            var loginInfo = new ServicePrincipalLoginInformation
            {
                ClientId     = clientId,
                ClientSecret = secret,
            };

            var credentials = new AzureCredentials(
                loginInfo, talentId, AzureEnvironment.AzureGlobalCloud)
                              .WithDefaultSubscription(subscriptionId);

            var resourceGroups = await LoadResourceGroups(credentials);

            var azSettings = new AzureSettings
            {
                ClientId       = clientId,
                TalentId       = talentId,
                ClientSecret   = secret,
                SubscriptionId = subscriptionId,
            };

            await userSettings.SetAzureSettings(azSettings);

            return(new
            {
                resourceGroups
            });
        }
コード例 #4
0
ファイル: AzureCommand.cs プロジェクト: yurikus/certes
        protected async Task <AzureCredentials> ReadAzureCredentials(ArgumentSyntax syntax)
        {
            var azSettings = await UserSettings.GetAzureSettings();

            var tenantId = syntax.GetOption <string>(AzureTenantIdOption)
                           ?? azSettings.TenantId;
            var clientId = syntax.GetOption <string>(AzureClientIdOption)
                           ?? azSettings.ClientId;
            var secret = syntax.GetOption <string>(AzureSecretOption)
                         ?? azSettings.ClientSecret;
            var subscriptionId = syntax.GetOption <string>(AzureSubscriptionIdOption)
                                 ?? azSettings.SubscriptionId;

            ValidateOption(tenantId, AzureTenantIdOption);
            ValidateOption(clientId, AzureClientIdOption);
            ValidateOption(secret, AzureSecretOption);
            ValidateOption(subscriptionId, AzureSubscriptionIdOption);

            var loginInfo = new ServicePrincipalLoginInformation
            {
                ClientId     = clientId,
                ClientSecret = secret,
            };

            var credentials = new AzureCredentials(
                loginInfo, tenantId, AzureEnvironment.AzureGlobalCloud)
                              .WithDefaultSubscription(subscriptionId);

            return(credentials);
        }
コード例 #5
0
        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,
                });
            }
        }
コード例 #6
0
        public static async Task<IKey> ReadKey(
            this ArgumentSyntax syntax,
            string optionName,
            string environmentVariableName,
            IFileUtil file,
            IEnvironmentVariables environment,
            bool isRequired = false)
        {
            var keyPath = syntax.GetOption<string>(optionName);
            if (!string.IsNullOrWhiteSpace(keyPath))
            {
                return KeyFactory.FromPem(await file.ReadAllText(keyPath));
            }
            else
            {
                var keyData = environment.GetVar(environmentVariableName);
                if (!string.IsNullOrWhiteSpace(keyData))
                {
                    return KeyFactory.FromDer(Convert.FromBase64String(keyData));
                }
                else if (isRequired)
                {
                    throw new Exception(string.Format(Strings.ErrorOptionMissing, optionName));
                }
            }

            return null;
        }
コード例 #7
0
ファイル: AccountNewCommand.cs プロジェクト: yurikus/certes
        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()
            });
        }
コード例 #8
0
        public async Task <object> Execute(ArgumentSyntax syntax)
        {
            var(location, cert) = await DownloadCertificate(syntax);

            var outPath = syntax.GetOption <string>(OutOption);

            if (string.IsNullOrWhiteSpace(outPath))
            {
                return(new
                {
                    location,
                    resource = new
                    {
                        certificate = cert.Certificate.ToDer(),
                        issuers = cert.Issuers.Select(i => i.ToDer()).ToArray(),
                    },
                });
            }
            else
            {
                logger.Debug("Saving certificate to '{0}'.", outPath);
                await File.WriteAllText(outPath, cert.ToPem());

                return(new
                {
                    location,
                });
            }
        }
コード例 #9
0
        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,
                });
            }
        }
コード例 #10
0
        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
                });
            }
        }
コード例 #11
0
        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);
            var preferredChain = syntax.GetOption <string>(PreferredChainOption);

            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(preferredChain));
        }
コード例 #12
0
 public static string GetKeyOption(this ArgumentSyntax syntax)
     => syntax.GetOption<string>(KeyOptionName);
コード例 #13
0
 public static Uri GetServerOption(this ArgumentSyntax syntax)
     => syntax.GetOption<Uri>(ServerOptionName);