private async Task <int> PerformAzureSignOnVsixAsync(string vsixPath, bool force, Uri timestampUri, HashAlgorithmName fileDigestAlgorithm, HashAlgorithmName timestampDigestAlgorithm, string azureUri, string azureClientId, string azureClientCertificateName, string azureClientSecret, string azureAccessToken ) { using (var package = OpcPackage.Open(vsixPath, OpcPackageFileMode.ReadWrite)) { if (package.GetSignatures().Any() && !force) { _signCommandApplication.Out.WriteLine("The VSIX is already signed."); return(EXIT_CODES.FAILED); } var signBuilder = package.CreateSignatureBuilder(); signBuilder.EnqueueNamedPreset <VSIXSignatureBuilderPreset>(); var signingConfiguration = new AzureKeyVaultSignConfigurationSet { FileDigestAlgorithm = fileDigestAlgorithm, PkcsDigestAlgorithm = fileDigestAlgorithm, AzureClientId = azureClientId, AzureClientSecret = azureClientSecret, AzureKeyVaultCertificateName = azureClientCertificateName, AzureKeyVaultUrl = azureUri, AzureAccessToken = azureAccessToken }; var signature = await signBuilder.SignAsync(signingConfiguration); if (timestampUri != null) { var timestampBuilder = signature.CreateTimestampBuilder(); var result = await timestampBuilder.SignAsync(timestampUri, timestampDigestAlgorithm); if (result == TimestampResult.Failed) { return(EXIT_CODES.FAILED); } } _signCommandApplication.Out.WriteLine("The signing operation is complete."); return(EXIT_CODES.SUCCESS); } }
internal async Task <int> SignAzure(CommandOption azureKeyVaultUrl, CommandOption azureKeyVaultClientId, CommandOption azureKeyVaultClientSecret, CommandOption azureKeyVaultCertificateName, CommandOption azureKeyVaultAccessToken, CommandOption force, CommandOption fileDigest, CommandOption timestampUrl, CommandOption timestampAlgorithm, CommandArgument vsixPath) { if (!azureKeyVaultUrl.HasValue()) { _signCommandApplication.Out.WriteLine("The Azure Key Vault URL must be specified for Azure signing."); return(EXIT_CODES.INVALID_OPTIONS); } // we only need the client id/secret if we don't have an access token if (!azureKeyVaultAccessToken.HasValue()) { if (!azureKeyVaultClientId.HasValue()) { _signCommandApplication.Out.WriteLine("The Azure Key Vault Client ID or Access Token must be specified for Azure signing."); return(EXIT_CODES.INVALID_OPTIONS); } if (!azureKeyVaultClientSecret.HasValue()) { _signCommandApplication.Out.WriteLine("The Azure Key Vault Client Secret or Access Token must be specified for Azure signing."); return(EXIT_CODES.INVALID_OPTIONS); } } if (!azureKeyVaultCertificateName.HasValue()) { _signCommandApplication.Out.WriteLine("The Azure Key Vault Client Certificate Name must be specified for Azure signing."); return(EXIT_CODES.INVALID_OPTIONS); } Uri timestampServer = null; if (timestampUrl.HasValue()) { if (!Uri.TryCreate(timestampUrl.Value(), UriKind.Absolute, out timestampServer)) { _signCommandApplication.Out.WriteLine("Specified timestamp URL is invalid."); return(EXIT_CODES.FAILED); } if (timestampServer.Scheme != Uri.UriSchemeHttp && timestampServer.Scheme != Uri.UriSchemeHttps) { _signCommandApplication.Out.WriteLine("Specified timestamp URL is invalid."); return(EXIT_CODES.FAILED); } } var vsixPathValue = vsixPath.Value; if (!File.Exists(vsixPathValue)) { _signCommandApplication.Out.WriteLine("Specified file does not exist."); return(EXIT_CODES.FAILED); } HashAlgorithmName fileDigestAlgorithm, timestampDigestAlgorithm; var fileDigestResult = AlgorithmFromInput(fileDigest.HasValue() ? fileDigest.Value() : null); if (fileDigestResult == null) { _signCommandApplication.Out.WriteLine("Specified file digest algorithm is not supported."); return(EXIT_CODES.INVALID_OPTIONS); } else { fileDigestAlgorithm = fileDigestResult.Value; } var timestampDigestResult = AlgorithmFromInput(timestampAlgorithm.HasValue() ? timestampAlgorithm.Value() : null); if (timestampDigestResult == null) { _signCommandApplication.Out.WriteLine("Specified timestamp digest algorithm is not supported."); return(EXIT_CODES.INVALID_OPTIONS); } else { timestampDigestAlgorithm = timestampDigestResult.Value; } var configuration = new AzureKeyVaultSignConfigurationSet { AzureKeyVaultUrl = azureKeyVaultUrl.Value(), AzureKeyVaultCertificateName = azureKeyVaultCertificateName.Value(), AzureClientId = azureKeyVaultClientId.Value(), AzureAccessToken = azureKeyVaultAccessToken.Value(), AzureClientSecret = azureKeyVaultClientSecret.Value(), }; var configurationDiscoverer = new KeyVaultConfigurationDiscoverer(); var materializedResult = await configurationDiscoverer.Materialize(configuration); AzureKeyVaultMaterializedConfiguration materialized; switch (materializedResult) { case ErrorOr <AzureKeyVaultMaterializedConfiguration> .Ok ok: materialized = ok.Value; break; default: _signCommandApplication.Out.WriteLine("Failed to get configuration from Azure Key Vault."); return(EXIT_CODES.FAILED); } var context = new KeyVaultContext(materialized.Client, materialized.KeyId, materialized.PublicCertificate); using (var keyVault = new RSAKeyVault(context)) { return(await PerformSignOnVsixAsync( vsixPathValue, force.HasValue(), timestampServer, fileDigestAlgorithm, timestampDigestAlgorithm, materialized.PublicCertificate, keyVault )); } }
public async Task <ErrorOr <AzureKeyVaultMaterializedConfiguration> > Materialize(AzureKeyVaultSignConfigurationSet configuration) { async Task <string> Authenticate(string authority, string resource, string scope) { if (!string.IsNullOrWhiteSpace(configuration.AzureAccessToken)) { return(configuration.AzureAccessToken); } var context = new AuthenticationContext(authority); ClientCredential credential = new ClientCredential(configuration.AzureClientId, configuration.AzureClientSecret); try { var result = await context.AcquireTokenAsync(resource, credential); return(result.AccessToken); } catch (AdalServiceException e) when(e.StatusCode >= 400 && e.StatusCode < 500) { return(null); } } var vault = new KeyVaultClient(Authenticate); var azureCertificate = await vault.GetCertificateAsync(configuration.AzureKeyVaultUrl, configuration.AzureKeyVaultCertificateName); var certificate = new X509Certificate2(azureCertificate.Cer); var keyId = azureCertificate.KeyIdentifier; return(new AzureKeyVaultMaterializedConfiguration(vault, certificate, keyId)); }