PrimarySignature CreateKeyVaultPrimarySignature(SignPackageRequest request, SignatureContent signatureContent, ILogger logger) { // Get the chain var getter = typeof(SignPackageRequest).GetProperty("Chain", BindingFlags.Instance | BindingFlags.NonPublic) .GetGetMethod(true); var certs = (IReadOnlyList <X509Certificate2>)getter.Invoke(request, null); var cmsSigner = CreateCmsSigner(request, certs, logger); var contentInfo = new ContentInfo(signatureContent.GetBytes()); var cms = new SignedCms(contentInfo); try { cms.ComputeSignature(cmsSigner, false); // silent is false to ensure PIN prompts appear if CNG/CAPI requires it } catch (CryptographicException ex) when(ex.HResult == INVALID_PROVIDER_TYPE_HRESULT) { var exceptionBuilder = new StringBuilder(); exceptionBuilder.AppendLine("Invalid provider type"); exceptionBuilder.AppendLine(CertificateUtility.X509Certificate2ToString(request.Certificate, NuGet.Common.HashAlgorithmName.SHA256)); throw new SignatureException(NuGetLogCode.NU3001, exceptionBuilder.ToString()); } return(PrimarySignature.Load(cms)); }
public async Task <byte[]> GenerateSignedPackageBytesAsync( Stream inputPackageStream, SignPackageRequest request, Uri timestampUri, ITestOutputHelper output) { var testLogger = new TestLogger(output); var timestampProvider = new Rfc3161TimestampProvider(timestampUri); var signatureProvider = new X509SignatureProvider(timestampProvider); using (var outputPackageStream = new MemoryStream()) { await SigningUtility.SignAsync( new SigningOptions( inputPackageStream : new Lazy <Stream>(() => inputPackageStream), outputPackageStream : new Lazy <Stream>(() => outputPackageStream), overwrite : true, signatureProvider : signatureProvider, logger : testLogger), request, CancellationToken.None); return(outputPackageStream.ToArray()); } }
public async Task <PrimarySignature> CreatePrimarySignatureAsync(SignPackageRequest request, SignatureContent signatureContent, ILogger logger, CancellationToken token) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (signatureContent == null) { throw new ArgumentNullException(nameof(signatureContent)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } logger.LogInformation($"{nameof(CreatePrimarySignatureAsync)}: Creating Primary signature"); var authorSignature = CreateKeyVaultPrimarySignature(request, signatureContent, logger); logger.LogInformation($"{nameof(CreatePrimarySignatureAsync)}: Primary signature completed"); logger.LogInformation($"{nameof(CreatePrimarySignatureAsync)}: Timestamp primary signature"); var timestamped = await TimestampPrimarySignatureAsync(request, logger, authorSignature, token); logger.LogInformation($"{nameof(CreatePrimarySignatureAsync)}: Timestamp completed"); return(timestamped); }
private async Task <int> SignPackageAsync( string packagePath, string outputPath, ILogger logger, bool Overwrite, ISignatureProvider signatureProvider, SignPackageRequest request, CancellationToken token) { // For overwrite we need to first remove the signature and then sign the unsigned package if (Overwrite) { var originalPackageCopyPath = CopyPackage(packagePath); await RemoveSignatureAsync(logger, signatureProvider, packagePath, originalPackageCopyPath, token); await AddSignatureAndUpdatePackageAsync(logger, signatureProvider, request, originalPackageCopyPath, outputPath, token); FileUtility.Delete(originalPackageCopyPath); } else { await AddSignatureAndUpdatePackageAsync(logger, signatureProvider, request, packagePath, outputPath, token); } return(0); }
internal static SignTest Create( X509Certificate2 certificate, HashAlgorithmName hashAlgorithm, byte[] package = null, ISignatureProvider signatureProvider = null) { ISignedPackage signedPackage; MemoryStream readStream = null; MemoryStream writeStream = null; if (package == null) { signedPackage = Mock.Of <ISignedPackage>(); } else { readStream = new MemoryStream(package); writeStream = new MemoryStream(); signedPackage = new SignedPackageArchive(readStream, writeStream); } signatureProvider = signatureProvider ?? Mock.Of <ISignatureProvider>(); var signer = new Signer(signedPackage, signatureProvider); var request = new SignPackageRequest(certificate, signatureHashAlgorithm: hashAlgorithm); return(new SignTest( signer, signedPackage, signatureProvider, request, readStream, writeStream)); }
/// <summary> /// Sign and timestamp a package for test purposes. /// This method timestamps a package and should only be used with tests marked with [CIOnlyFact] /// </summary> private static async Task SignAndTimeStampPackageAsync(TestLogger testLogger, X509Certificate2 certificate, SignedPackageArchive signPackage) { var testSignatureProvider = new X509SignatureProvider(new Rfc3161TimestampProvider(new Uri(_testTimestampServer))); var signer = new Signer(signPackage, testSignatureProvider); var request = new SignPackageRequest(certificate, signatureHashAlgorithm: HashAlgorithmName.SHA256); await signer.SignAsync(request, testLogger, CancellationToken.None); }
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 <int> ExecuteCommandAsync( IEnumerable <string> packagesToSign, SignPackageRequest signPackageRequest, string timestamper, ILogger logger, string outputDirectory, bool overwrite, CancellationToken token) { var success = true; try { SigningUtility.Verify(signPackageRequest); } catch (Exception e) { success = false; ExceptionUtilities.LogException(e, logger); } if (success) { var signatureProvider = GetSignatureProvider(timestamper); foreach (var packagePath in packagesToSign) { try { string outputPath; if (string.IsNullOrEmpty(outputDirectory)) { outputPath = packagePath; } else { outputPath = Path.Combine(outputDirectory, Path.GetFileName(packagePath)); } await SignPackageAsync(packagePath, outputPath, logger, overwrite, signatureProvider, signPackageRequest, token); } catch (Exception e) { success = false; ExceptionUtilities.LogException(e, logger); } } } if (success) { logger.LogInformation(Strings.SignCommandSuccess); } return(success ? 0 : 1); }
PrimarySignature CreateKeyVaultPrimarySignature(SignPackageRequest request, SignatureContent signatureContent, SignatureType signatureType) { // Get the chain var getter = typeof(SignPackageRequest).GetProperty("Chain", BindingFlags.Instance | BindingFlags.NonPublic) .GetGetMethod(true); var certs = (IReadOnlyList <X509Certificate2>)getter.Invoke(request, null); var attribs = SigningUtility.CreateSignedAttributes(request, certs); // Convert .NET crypto attributes to Bouncy Castle var attribTable = new AttributeTable(new Asn1EncodableVector(attribs.Cast <CryptographicAttributeObject>() .Select(ToBcAttribute) .ToArray())); // SignerInfo generator setup var signerInfoGeneratorBuilder = new SignerInfoGeneratorBuilder() .WithSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(attribTable)); // Subject Key Identifier (SKI) is smaller and less prone to accidental matching than issuer and serial // number. However, to ensure cross-platform verification, SKI should only be used if the certificate // has the SKI extension attribute. // Try to look for the value var bcCer = DotNetUtilities.FromX509Certificate(request.Certificate); var ext = bcCer.GetExtensionValue(new DerObjectIdentifier(Oids.SubjectKeyIdentifier)); SignerInfoGenerator signerInfoGenerator; if (ext != null) { var ski = new SubjectKeyIdentifierStructure(ext); signerInfoGenerator = signerInfoGeneratorBuilder.Build(new RsaSignatureFactory(HashAlgorithmToBouncyCastle(request.SignatureHashAlgorithm), provider), ski.GetKeyIdentifier()); } else { signerInfoGenerator = signerInfoGeneratorBuilder.Build(new RsaSignatureFactory(HashAlgorithmToBouncyCastle(request.SignatureHashAlgorithm), provider), bcCer); } var generator = new CmsSignedDataGenerator(); generator.AddSignerInfoGenerator(signerInfoGenerator); // Get the chain as bc certs generator.AddCertificates(X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(certs.Select(DotNetUtilities.FromX509Certificate). ToList()))); var msg = new CmsProcessableByteArray(signatureContent.GetBytes()); var data = generator.Generate(msg, true); var encoded = data.ContentInfo.GetDerEncoded(); return(PrimarySignature.Load(encoded)); }
private SignTest(SignPackageRequest request, TestDirectory directory, SigningOptions options, TestLogger logger) { Request = request; Options = options; Logger = logger; _directory = directory; }
CmsSigner CreateCmsSigner(SignPackageRequest request, IReadOnlyList <X509Certificate2> chain, ILogger logger) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } // Subject Key Identifier (SKI) is smaller and less prone to accidental matching than issuer and serial // number. However, to ensure cross-platform verification, SKI should only be used if the certificate // has the SKI extension attribute. CmsSigner signer; if (request.Certificate.Extensions[Oids.SubjectKeyIdentifier] == null) { signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, request.Certificate, provider); } else { signer = new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, request.Certificate, provider); } foreach (var certificate in chain) { signer.Certificates.Add(certificate); } CryptographicAttributeObjectCollection attributes; if (request.SignatureType == SignatureType.Repository) { attributes = SigningUtility.CreateSignedAttributes((RepositorySignPackageRequest)request, chain); } else { attributes = SigningUtility.CreateSignedAttributes(request, chain); } foreach (var attribute in attributes) { signer.SignedAttributes.Add(attribute); } // We built the chain ourselves and added certificates. // Passing any other value here would trigger another chain build // and possibly add duplicate certs to the collection. signer.IncludeOption = X509IncludeOption.None; signer.DigestAlgorithm = request.SignatureHashAlgorithm.ConvertToOid(); return(signer); }
Task <Signature> TimestampSignature(SignPackageRequest request, ILogger logger, byte[] signature, CancellationToken token) { var timestampRequest = new TimestampRequest { SignatureValue = signature, Certificate = request.Certificate, SigningSpec = SigningSpecifications.V1, TimestampHashAlgorithm = request.TimestampHashAlgorithm }; return(timestampProvider.TimestampSignatureAsync(timestampRequest, logger, token)); }
private static void VerifyAttributes( CryptographicAttributeObjectCollection attributes, SignPackageRequest request) { var pkcs9SigningTimeAttributeFound = false; var commitmentTypeIndicationAttributeFound = false; var signingCertificateV2AttributeFound = false; foreach (var attribute in attributes) { Assert.Equal(1, attribute.Values.Count); switch (attribute.Oid.Value) { case "1.2.840.113549.1.9.5": // PKCS #9 signing time Assert.IsType <Pkcs9SigningTime>(attribute.Values[0]); pkcs9SigningTimeAttributeFound = true; break; case Oids.CommitmentTypeIndication: var qualifier = CommitmentTypeQualifier.Read(attribute.Values[0].RawData); var expectedCommitmentType = AttributeUtility.GetSignatureTypeOid(request.SignatureType); Assert.Equal(expectedCommitmentType, qualifier.CommitmentTypeIdentifier.Value); commitmentTypeIndicationAttributeFound = true; break; case Oids.SigningCertificateV2: var signingCertificateV2 = SigningCertificateV2.Read(attribute.Values[0].RawData); Assert.Equal(1, signingCertificateV2.Certificates.Count); var essCertIdV2 = signingCertificateV2.Certificates[0]; Assert.Equal(SignTestUtility.GetHash(request.Certificate, request.SignatureHashAlgorithm), essCertIdV2.CertificateHash); Assert.Equal(request.SignatureHashAlgorithm.ConvertToOidString(), essCertIdV2.HashAlgorithm.Algorithm.Value); Assert.Equal(request.Certificate.IssuerName.Name, essCertIdV2.IssuerSerial.GeneralNames[0].DirectoryName.Name); SignTestUtility.VerifySerialNumber(request.Certificate, essCertIdV2.IssuerSerial); Assert.Null(signingCertificateV2.Policies); signingCertificateV2AttributeFound = true; break; } } Assert.True(pkcs9SigningTimeAttributeFound); Assert.True(commitmentTypeIndicationAttributeFound); Assert.True(signingCertificateV2AttributeFound); }
Task <PrimarySignature> TimestampPrimarySignatureAsync(SignPackageRequest request, ILogger logger, PrimarySignature signature, CancellationToken token) { var signatureValue = signature.GetSignatureValue(); var messageHash = request.TimestampHashAlgorithm.ComputeHash(signatureValue); var timestampRequest = new TimestampRequest( signingSpecifications: SigningSpecifications.V1, hashedMessage: messageHash, hashAlgorithm: request.TimestampHashAlgorithm, target: SignaturePlacement.PrimarySignature ); return(timestampProvider.TimestampSignatureAsync(signature, timestampRequest, logger, token)); }
private SignTest(Signer signer, ISignedPackage package, ISignatureProvider signatureProvider, SignPackageRequest request, MemoryStream readStream, MemoryStream writeStream) { Signer = signer; Package = package; SignatureProvider = signatureProvider; Request = request; _readStream = readStream; _writeStream = writeStream; }
public static async Task CreateSignedPackageAsync( SignPackageRequest request, Stream packageReadStream, Stream packageWriteStream) { using (var signedPackage = new SignedPackageArchive(packageReadStream, packageWriteStream)) using (var options = new SigningOptions( new Lazy <Stream>(() => packageReadStream), new Lazy <Stream>(() => packageWriteStream), overwrite: false, signatureProvider: new X509SignatureProvider(timestampProvider: null), logger: NullLogger.Instance)) { await SigningUtility.SignAsync(options, request, CancellationToken.None); } }
/// <summary> /// Generates a Signature for a given package for tests. /// </summary> /// <param name="package">Package to be used for the signature.</param> /// <param name="request">Sign package request for primary signature</param> /// <param name="timestampProvider">Provider to add timestamp to package. Defaults to null.</param> /// <returns>Signature for the package.</returns> public static async Task <PrimarySignature> CreatePrimarySignatureForPackageAsync( PackageArchiveReader package, SignPackageRequest request, ITimestampProvider timestampProvider = null) { Assert.False(await package.IsSignedAsync(CancellationToken.None)); var testLogger = new TestLogger(); var signatureProvider = new X509SignatureProvider(timestampProvider); var zipArchiveHash = await package.GetArchiveHashAsync(request.SignatureHashAlgorithm, CancellationToken.None); var base64ZipArchiveHash = Convert.ToBase64String(zipArchiveHash); var signatureContent = new SignatureContent(SigningSpecifications.V1, request.SignatureHashAlgorithm, base64ZipArchiveHash); return(await signatureProvider.CreatePrimarySignatureAsync(request, signatureContent, testLogger, CancellationToken.None)); }
/// <summary> /// Generates a Signature for a package. /// </summary> /// <param name="testCert">Certificate to be used while generating the signature.</param> /// <param name="nupkg">Package for which the signature has to be generated.</param> /// <returns>Signature for the package.</returns> public static async Task <Signature> CreateSignatureForPackageAsync(X509Certificate2 testCert, Stream packageStream) { var testLogger = new TestLogger(); var hashAlgorithm = HashAlgorithmName.SHA256; using (var request = new SignPackageRequest(testCert, hashAlgorithm)) using (var package = new PackageArchiveReader(packageStream, leaveStreamOpen: true)) { var zipArchiveHash = await package.GetArchiveHashAsync(request.SignatureHashAlgorithm, CancellationToken.None); var base64ZipArchiveHash = Convert.ToBase64String(zipArchiveHash); var signatureContent = new SignatureContent(SigningSpecifications.V1, hashAlgorithm, base64ZipArchiveHash); var testSignatureProvider = new X509SignatureProvider(timestampProvider: null); return(await testSignatureProvider.CreateSignatureAsync(request, signatureContent, testLogger, CancellationToken.None)); } }
internal Test(X509Certificate2 certificate) { _directory = TestDirectory.Create(); _certificate = new X509Certificate2(certificate); var packageContext = new SimpleTestPackageContext(); ReadStream = packageContext.CreateAsStream(); WriteStream = packageContext.CreateAsStream(); Package = new SignedPackageArchive(ReadStream, WriteStream); Request = new SignPackageRequest(_certificate, HashAlgorithmName.SHA256); var signatureProvider = new X509SignatureProvider(timestampProvider: null); Signer = new Signer(Package, signatureProvider); }
private static async Task AddSignatureToPackageAsync(ISignedPackage package, SignPackageRequest request, ILogger logger) { var testSignatureProvider = new X509SignatureProvider(timestampProvider: null); var zipArchiveHash = await package.GetArchiveHashAsync(request.SignatureHashAlgorithm, CancellationToken.None); var base64ZipArchiveHash = Convert.ToBase64String(zipArchiveHash); var signatureContent = new SignatureContent(SigningSpecifications.V1, request.SignatureHashAlgorithm, base64ZipArchiveHash); var signature = await testSignatureProvider.CreatePrimarySignatureAsync(request, signatureContent, logger, CancellationToken.None); using (var stream = new MemoryStream(signature.GetBytes())) { #if IS_DESKTOP await package.AddSignatureAsync(stream, CancellationToken.None); #endif } }
private static async Task AddSignatureAndUpdatePackageAsync( ILogger logger, ISignatureProvider signatureProvider, SignPackageRequest request, string packagePath, string outputPath, CancellationToken token) { var originalPackageCopyPath = CopyPackage(packagePath); using (var packageReadStream = File.OpenRead(packagePath)) using (var packageWriteStream = File.Open(originalPackageCopyPath, FileMode.Open)) using (var package = new SignedPackageArchive(packageReadStream, packageWriteStream)) { var signer = new Signer(package, signatureProvider); await signer.SignAsync(request, logger, token); } OverwritePackage(originalPackageCopyPath, outputPath); FileUtility.Delete(originalPackageCopyPath); }
private static void VerifyAttributesRepository( CryptographicAttributeObjectCollection attributes, SignPackageRequest request, Uri v3ServiceIndexUrl, IReadOnlyList <string> packageOwners) { VerifyAttributes(attributes, request); var nugetV3ServiceIndexUrlAttributeFound = false; var nugetPackageOwnersAttributeFound = false; foreach (var attribute in attributes) { Assert.Equal(1, attribute.Values.Count); switch (attribute.Oid.Value) { case Oids.NuGetV3ServiceIndexUrl: var nugetV3ServiceIndexUrl = NuGetV3ServiceIndexUrl.Read(attribute.Values[0].RawData); Assert.True(nugetV3ServiceIndexUrl.V3ServiceIndexUrl.IsAbsoluteUri); Assert.Equal(v3ServiceIndexUrl.OriginalString, nugetV3ServiceIndexUrl.V3ServiceIndexUrl.OriginalString); nugetV3ServiceIndexUrlAttributeFound = true; break; case Oids.NuGetPackageOwners: var nugetPackageOwners = NuGetPackageOwners.Read(attribute.Values[0].RawData); Assert.Equal(packageOwners, nugetPackageOwners.PackageOwners); nugetPackageOwnersAttributeFound = true; break; } } Assert.True(nugetV3ServiceIndexUrlAttributeFound); Assert.Equal(packageOwners != null && packageOwners.Count > 0, nugetPackageOwnersAttributeFound); }
public async Task <Signature> CreateSignatureAsync(SignPackageRequest request, SignatureManifest signatureManifest, ILogger logger, CancellationToken token) { if (request == null) { throw new ArgumentNullException(nameof(request)); } if (signatureManifest == null) { throw new ArgumentNullException(nameof(signatureManifest)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } var authorSignature = CreateKeyVaultSignature(request.Certificate, signatureManifest); var timestamped = await TimestampSignature(request, logger, authorSignature, token); return(timestamped); }
public SignPackageRequest GetSignRequest() { ValidatePackagePath(); WarnIfNoTimestamper(Console); ValidateCertificateInputs(); EnsureOutputDirectory(); var signingSpec = SigningSpecifications.V1; var signatureHashAlgorithm = ValidateAndParseHashAlgorithm(HashAlgorithm, nameof(HashAlgorithm), signingSpec); var timestampHashAlgorithm = ValidateAndParseHashAlgorithm(TimestampHashAlgorithm, nameof(TimestampHashAlgorithm), signingSpec); var certCollection = GetCertificateCollection(); var certificate = GetCertificate(certCollection); var privateKey = GetPrivateKey(certificate); var request = new SignPackageRequest( certificate, signatureHashAlgorithm, timestampHashAlgorithm); request.PrivateKey = privateKey; request.AdditionalCertificates.AddRange(certCollection); return(request); }
/// <summary> /// Timestamps a signature for tests. /// </summary> /// <param name="timestampProvider">Timestamp provider.</param> /// <param name="signatureRequest">SignPackageRequest containing metadata for timestamp request.</param> /// <param name="signature">Signature that needs to be timestamped.</param> /// <param name="logger">ILogger.</param> /// <returns>Timestamped Signature.</returns> public static Task <Signature> TimestampSignature(ITimestampProvider timestampProvider, SignPackageRequest signatureRequest, Signature signature, ILogger logger) { var timestampRequest = new TimestampRequest { SignatureValue = signature.GetBytes(), SigningSpec = SigningSpecifications.V1, TimestampHashAlgorithm = signatureRequest.TimestampHashAlgorithm }; return(TimestampSignature(timestampProvider, timestampRequest, signature, logger)); }
/// <summary> /// Generates a Signature for a given package for tests. /// </summary> /// <param name="signatureProvider">Signature proivider to create the signature.</param> /// <param name="package">Package to be used for the signature.</param> /// <param name="request">SignPackageRequest containing the metadata for the signature request.</param> /// <param name="testLogger">ILogger.</param> /// <returns>Signature for the package.</returns> public static async Task <Signature> CreateSignatureForPackageAsync(ISignatureProvider signatureProvider, PackageArchiveReader package, SignPackageRequest request, TestLogger testLogger) { var zipArchiveHash = await package.GetArchiveHashAsync(request.SignatureHashAlgorithm, CancellationToken.None); var base64ZipArchiveHash = Convert.ToBase64String(zipArchiveHash); var signatureContent = new SignatureContent(SigningSpecifications.V1, request.SignatureHashAlgorithm, base64ZipArchiveHash); return(await signatureProvider.CreateSignatureAsync(request, signatureContent, testLogger, CancellationToken.None)); }
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); }
public async Task <int> ExecuteCommandAsync( IEnumerable <string> packagesToSign, SignPackageRequest signPackageRequest, string timestamper, ILogger logger, string outputDirectory, bool overwrite, CancellationToken token) { var success = true; try { SigningUtility.Verify(signPackageRequest, logger); } catch (Exception e) { success = false; ExceptionUtilities.LogException(e, logger); } if (success) { var signatureProvider = GetSignatureProvider(timestamper); foreach (var packagePath in packagesToSign) { // Set the output of the signing operation to a temp file because signing cannot be done in place. var tempPackageFile = new FileInfo(Path.GetTempFileName()); try { string outputPath; if (string.IsNullOrEmpty(outputDirectory)) { outputPath = packagePath; } else { outputPath = Path.Combine(outputDirectory, Path.GetFileName(packagePath)); } using (var options = SigningOptions.CreateFromFilePaths( packagePath, tempPackageFile.FullName, overwrite, signatureProvider, logger)) { await SigningUtility.SignAsync(options, signPackageRequest, token); } if (tempPackageFile.Length > 0) { FileUtility.Replace(tempPackageFile.FullName, outputPath); } else { throw new SignatureException(Strings.Error_UnableToSignPackage); } } catch (Exception e) { success = false; ExceptionUtilities.LogException(e, logger); } finally { FileUtility.Delete(tempPackageFile.FullName); } } } if (success) { logger.LogInformation(Strings.SignCommandSuccess); } return(success ? 0 : 1); }
PrimarySignature CreateKeyVaultRepositoryCountersignature(CmsSigner cmsSigner, SignPackageRequest request, PrimarySignature primarySignature) { var cms = new SignedCms(); cms.Decode(primarySignature.GetBytes()); try { cms.SignerInfos[0].ComputeCounterSignature(cmsSigner); } catch (CryptographicException ex) when(ex.HResult == INVALID_PROVIDER_TYPE_HRESULT) { var exceptionBuilder = new StringBuilder(); exceptionBuilder.AppendLine("Invalid provider type"); exceptionBuilder.AppendLine(CertificateUtility.X509Certificate2ToString(request.Certificate, NuGet.Common.HashAlgorithmName.SHA256)); throw new SignatureException(NuGetLogCode.NU3001, exceptionBuilder.ToString()); } return(PrimarySignature.Load(cms)); }
/// <summary> /// Timestamps a signature for tests. /// </summary> /// <param name="timestampProvider">Timestamp provider.</param> /// <param name="signatureRequest">SignPackageRequest containing metadata for timestamp request.</param> /// <param name="signature">Signature that needs to be timestamped.</param> /// <param name="logger">ILogger.</param> /// <returns>Timestamped Signature.</returns> public static Task <PrimarySignature> TimestampPrimarySignature(ITimestampProvider timestampProvider, SignPackageRequest signatureRequest, PrimarySignature signature, ILogger logger) { var signatureValue = signature.GetSignatureValue(); var messageHash = signatureRequest.TimestampHashAlgorithm.ComputeHash(signatureValue); var timestampRequest = new TimestampRequest( signingSpecifications: SigningSpecifications.V1, hashedMessage: messageHash, hashAlgorithm: signatureRequest.TimestampHashAlgorithm, target: SignaturePlacement.PrimarySignature ); return(TimestampPrimarySignature(timestampProvider, timestampRequest, signature, logger)); }