public async Task <bool> SignAsync(string packagePath, string outputPath, string timestampUrl, Uri v3ServiceIndex, IReadOnlyList <string> packageOwners, SignatureType signatureType, HashAlgorithmName signatureHashAlgorithm, HashAlgorithmName timestampHashAlgorithm, bool overwrite, X509Certificate2 publicCertificate, System.Security.Cryptography.RSA rsa, CancellationToken cancellationToken = default) { var packagesToSign = LocalFolderUtility.ResolvePackageFromPath(packagePath); var signatureProvider = new KeyVaultSignatureProvider(rsa, new Rfc3161TimestampProvider(new Uri(timestampUrl))); SignPackageRequest request = null; if (signatureType == SignatureType.Author) { request = new AuthorSignPackageRequest(publicCertificate, signatureHashAlgorithm, timestampHashAlgorithm); } else if (signatureType == SignatureType.Repository) { request = new RepositorySignPackageRequest(publicCertificate, signatureHashAlgorithm, timestampHashAlgorithm, v3ServiceIndex, packageOwners); } else { throw new ArgumentOutOfRangeException(nameof(signatureType)); } string originalPackageCopyPath = null; foreach (var package in packagesToSign) { cancellationToken.ThrowIfCancellationRequested(); logger.LogInformation($"{nameof(SignAsync)} [{package}]: Begin Signing {Path.GetFileName(package)}"); try { originalPackageCopyPath = CopyPackage(package); using var options = SigningOptions.CreateFromFilePaths(originalPackageCopyPath, outputPath, overwrite, signatureProvider, new NuGetLogger(logger, package)); await SigningUtility.SignAsync(options, request, cancellationToken); } catch (Exception e) { logger.LogError(e, e.Message); return(false); } finally { try { FileUtility.Delete(originalPackageCopyPath); } catch { } logger.LogInformation($"{nameof(SignAsync)} [{package}]: End Signing {Path.GetFileName(package)}"); } } return(true); }
public async Task <bool> SignAsync(string packagePath, string outputPath, string timestampUrl, HashAlgorithmName signatureHashAlgorithm, HashAlgorithmName timestampHashAlgorithm, bool overwrite, X509Certificate2 publicCertificate, System.Security.Cryptography.RSA rsa) { var fileName = Path.GetFileName(packagePath); logger.LogInformation($"{nameof(SignAsync)} [{fileName}]: Begin Signing {packagePath}"); var signatureProvider = new KeyVaultSignatureProvider(rsa, new Rfc3161TimestampProvider(new Uri(timestampUrl))); var request = new AuthorSignPackageRequest(publicCertificate, signatureHashAlgorithm, timestampHashAlgorithm); string originalPackageCopyPath = null; try { originalPackageCopyPath = CopyPackage(packagePath); using (var options = SigningOptions.CreateFromFilePaths(originalPackageCopyPath, outputPath, overwrite, signatureProvider, new NuGetLogger(logger, fileName))) { await SigningUtility.SignAsync(options, request, CancellationToken.None); } } catch (Exception e) { logger.LogError(e, e.Message); return(false); } finally { try { FileUtility.Delete(originalPackageCopyPath); } catch { } logger.LogInformation($"{nameof(SignAsync)} [{fileName}]: End Signing {packagePath}"); } return(true); }
public async Task <int> SignAsync(string file, string timestampUrl, HashAlgorithmName signatureHashAlgorithm, HashAlgorithmName timestampeHashAlgorithm, string keyVaultCertificateName, string keyVaultUrl, string keyVaultClientId, string keyVaultClientSecret, string keyVaultAccessToken) { string validatedToken = null; async Task <string> Authenticate(string authority, string resource, string scope) { if (!string.IsNullOrWhiteSpace(keyVaultAccessToken)) { validatedToken = keyVaultAccessToken; return(keyVaultAccessToken); } var context = new AuthenticationContext(authority); var credential = new ClientCredential(keyVaultClientId, keyVaultClientSecret); var result = await context.AcquireTokenAsync(resource, credential) .ConfigureAwait(false); if (result == null) { throw new InvalidOperationException("Authentication to Azure failed."); } validatedToken = result.AccessToken; return(result.AccessToken); } var client = new KeyVaultClient(Authenticate, new HttpClient()); // We call this here to verify it's a valid cert // It also implicitly validates the access token or credentials var kvcert = await client.GetCertificateAsync(keyVaultUrl, keyVaultCertificateName) .ConfigureAwait(false); var cert = new X509Certificate2(kvcert.Cer); var rsa = client.ToRSA(kvcert.KeyIdentifier, cert); // TODO: Add Hash Alg choice var request = new SignPackageRequest() { Certificate = cert, SignatureHashAlgorithm = signatureHashAlgorithm, TimestampHashAlgorithm = timestampeHashAlgorithm }; string tempFilePath = null; try { tempFilePath = CopyPackage(file); var signatureProvider = new KeyVaultSignatureProvider(rsa, new Rfc3161TimestampProvider(new Uri(timestampUrl))); // remove first to overwrite // This command overwrites by default, like signtool using (var packageWriteStream = File.Open(tempFilePath, FileMode.Open)) using (var package = new SignedPackageArchive(packageWriteStream)) { var signer = new Signer(package, signatureProvider); await signer.RemoveSignaturesAsync(new NullLogger(), CancellationToken.None); } // Now sign using (var packageWriteStream = File.Open(tempFilePath, FileMode.Open)) using (var package = new SignedPackageArchive(packageWriteStream)) { var signer = new Signer(package, signatureProvider); await signer.SignAsync(request, new NullLogger(), CancellationToken.None); } OverwritePackage(tempFilePath, file); } catch (Exception e) { Console.Error.WriteLine(e.Message); Console.Error.WriteLine(e.StackTrace); return(-1); } finally { try { FileUtility.Delete(tempFilePath); } catch { } } return(0); }