public void GivenTwoPartialSigningInfosWithEmptySections() { SigningInformation actualMerged = pushMetadata.MergeSigningInfo(new List <SigningInformation> { PartialSigningInfo3, PartialSigningInfo4 }); actualMerged.Should().BeEquivalentTo(MergedPartialMetadataSigningInfos); }
/// <summary> /// Method that creates a temporary pdf for calating the hash that must be sent to AMA for signing /// </summary> /// <param name="signingInformation">Information about the signature and its appearance</param> /// <returns>Information with the hashes required for signing and completing the retrieved signature injection</returns> public HashesForSigning CreateTemporaryPdfForSigning(SigningInformation signingInformation) { var pdfSigner = new PdfSigner(new PdfReader(signingInformation.PathToPdf), new FileStream(signingInformation.PathToIntermediaryPdf, FileMode.Create), new StampingProperties()); pdfSigner.SetFieldName(_signatureFieldname); var appearance = pdfSigner.GetSignatureAppearance(); appearance.SetPageRect(new Rectangle(10, 750, 150, 50)) .SetPageNumber(signingInformation.PageNumber) .SetLayer2FontSize(6f) .SetReason(signingInformation.Reason) .SetLocation(signingInformation.Location) .SetLayer2Text(BuildVisibleInformation(signingInformation.Reason, signingInformation.Location)) .SetCertificate(_userCertificateChain[0]); if (signingInformation.Logo != null) { appearance.SetRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION) .SetSignatureGraphic(signingInformation.Logo); } var crlBytesList = GetCrlByteList(); var ocspBytesList = GetOcspBytesList(); var container = new PrefareForAmaSigningContainer(_userCertificateChain, crlBytesList, ocspBytesList); pdfSigner.SignExternalContainer(container, EstimateContainerSize(crlBytesList)); // add size for timestamp in signature return(new HashesForSigning(container.HashToBeSignedByAma, container.NakedHash)); }
public async Task <bool> PushMetadataAsync(CancellationToken cancellationToken) { try { cancellationToken.ThrowIfCancellationRequested(); Log.LogMessage(MessageImportance.High, "Starting build metadata push to the Build Asset Registry..."); if (!Directory.Exists(ManifestsPath)) { Log.LogError($"Required folder '{ManifestsPath}' does not exist."); } else { //get the list of manifests List <Manifest> parsedManifests = GetParsedManifests(ManifestsPath, cancellationToken); if (parsedManifests.Count == 0) { Log.LogError( $"No manifests found matching the search pattern {SearchPattern} in {ManifestsPath}"); return(!Log.HasLoggedErrors); } Manifest manifest; //check if the manifest have any duplicate packages and blobs if (parsedManifests.Count > 1) { manifest = MergeManifests(parsedManifests); } else { manifest = parsedManifests[0]; } List <SigningInformation> signingInformation = new List <SigningInformation>(); foreach (var m in parsedManifests) { if (m.SigningInformation != null) { signingInformation.Add(m.SigningInformation); } } //get packages blobs and signing info (List <PackageArtifactModel> packages, List <BlobArtifactModel> blobs) = GetPackagesAndBlobsInfo(manifest); //create merged buildModel to create the merged manifest BuildModel modelForManifest = CreateMergedManifestBuildModel(packages, blobs, manifest); //add manifest as an asset to the buildModel var mergedManifestAsset = GetManifestAsAsset(blobs, MergedManifestFileName); modelForManifest.Artifacts.Blobs.Add(mergedManifestAsset); SigningInformation finalSigningInfo = MergeSigningInfo(signingInformation); // push the merged manifest, this is required for only publishingVersion 3 and above if (manifest.PublishingVersion >= 3) { PushMergedManifest(modelForManifest, finalSigningInfo); } // populate buildData and assetData using merged manifest data BuildData buildData = GetMaestroBuildDataFromMergedManifest(modelForManifest, manifest, cancellationToken); IMaestroApi client = ApiFactory.GetAuthenticated(MaestroApiEndpoint, BuildAssetRegistryToken); var deps = await GetBuildDependenciesAsync(client, cancellationToken); Log.LogMessage(MessageImportance.High, "Calculated Dependencies:"); foreach (var dep in deps) { Log.LogMessage(MessageImportance.High, $" {dep.BuildId}, IsProduct: {dep.IsProduct}"); } buildData.Dependencies = deps; LookupForMatchingGitHubRepository(manifest); buildData.GitHubBranch = GitHubBranch; buildData.GitHubRepository = GitHubRepository; Client.Models.Build recordedBuild = await client.Builds.CreateAsync(buildData, cancellationToken); BuildId = recordedBuild.Id; Log.LogMessage(MessageImportance.High, $"Metadata has been pushed. Build id in the Build Asset Registry is '{recordedBuild.Id}'"); Console.WriteLine($"##vso[build.addbuildtag]BAR ID - {recordedBuild.Id}"); // Only 'create' the AzDO (VSO) variables if running in an AzDO build if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("BUILD_BUILDID"))) { IEnumerable <DefaultChannel> defaultChannels = await GetBuildDefaultChannelsAsync(client, recordedBuild); HashSet <int> targetChannelIds = new HashSet <int>(defaultChannels.Select(dc => dc.Channel.Id)); var defaultChannelsStr = "[" + string.Join("][", targetChannelIds) + "]"; Log.LogMessage(MessageImportance.High, $"Determined build will be added to the following channels: {defaultChannelsStr}"); Console.WriteLine($"##vso[task.setvariable variable=BARBuildId]{recordedBuild.Id}"); Console.WriteLine($"##vso[task.setvariable variable=DefaultChannels]{defaultChannelsStr}"); Console.WriteLine($"##vso[task.setvariable variable=IsStableBuild]{IsStableBuild}"); } } } catch (Exception exc) { Log.LogErrorFromException(exc, true, true, null); } return(!Log.HasLoggedErrors); }
public async Task <bool> PushMetadataAsync(CancellationToken cancellationToken) { try { cancellationToken.ThrowIfCancellationRequested(); Log.LogMessage(MessageImportance.High, "Starting build metadata push to the Build Asset Registry..."); if (!Directory.Exists(ManifestsPath)) { Log.LogError($"Required folder '{ManifestsPath}' does not exist."); } else { (List <BuildData> buildsManifestMetadata, List <SigningInformation> signingInformation, ManifestBuildData manifestBuildData) = GetBuildManifestsMetadata(ManifestsPath, cancellationToken); if (buildsManifestMetadata.Count == 0) { Log.LogError($"No build manifests found matching the search pattern {SearchPattern} in {ManifestsPath}"); return(!Log.HasLoggedErrors); } BuildData finalBuild = MergeBuildManifests(buildsManifestMetadata); IMaestroApi client = ApiFactory.GetAuthenticated(MaestroApiEndpoint, BuildAssetRegistryToken); var deps = await GetBuildDependenciesAsync(client, cancellationToken); Log.LogMessage(MessageImportance.High, "Calculated Dependencies:"); foreach (var dep in deps) { Log.LogMessage(MessageImportance.High, $" {dep.BuildId}, IsProduct: {dep.IsProduct}"); } finalBuild.Dependencies = deps; // Based on the in-memory merged manifest, create a physical XML file and // upload it to the BlobArtifacts folder only when publishingVersion >= 3 if (manifestBuildData.PublishingVersion >= 3) { SigningInformation finalSigningInfo = MergeSigningInfo(signingInformation); // Inject an entry of MergedManifest.xml to the in-memory merged manifest string location = null; AssetData assetData = finalBuild.Assets.FirstOrDefault(); if (assetData != null) { AssetLocationData assetLocationData = assetData.Locations.FirstOrDefault(); if (assetLocationData != null) { location = assetLocationData.Location; } } finalBuild.Assets = finalBuild.Assets.Add(GetManifestAsAsset(finalBuild.Assets, location, MergedManifestFileName)); BuildModel modelForManifest = CreateMergedManifestBuildModel(finalBuild.Assets, manifestBuildData); PushMergedManifest(modelForManifest, finalSigningInfo); } Client.Models.Build recordedBuild = await client.Builds.CreateAsync(finalBuild, cancellationToken); BuildId = recordedBuild.Id; Log.LogMessage(MessageImportance.High, $"Metadata has been pushed. Build id in the Build Asset Registry is '{recordedBuild.Id}'"); Console.WriteLine($"##vso[build.addbuildtag]BAR ID - {recordedBuild.Id}"); // Only 'create' the AzDO (VSO) variables if running in an AzDO build if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("BUILD_BUILDID"))) { IEnumerable <DefaultChannel> defaultChannels = await GetBuildDefaultChannelsAsync(client, recordedBuild); HashSet <int> targetChannelIds = new HashSet <int>(defaultChannels.Select(dc => dc.Channel.Id)); var defaultChannelsStr = "[" + string.Join("][", targetChannelIds) + "]"; Log.LogMessage(MessageImportance.High, $"Determined build will be added to the following channels: { defaultChannelsStr}"); Console.WriteLine($"##vso[task.setvariable variable=BARBuildId]{recordedBuild.Id}"); Console.WriteLine($"##vso[task.setvariable variable=DefaultChannels]{defaultChannelsStr}"); Console.WriteLine($"##vso[task.setvariable variable=IsStableBuild]{IsStableBuild}"); } } } catch (Exception exc) { Log.LogErrorFromException(exc, true, true, null); } return(!Log.HasLoggedErrors); }
public static XElement SigningInfoToXml(SigningInformation signingInformation) { if (signingInformation == null) { return(null); } List <XElement> signingMetadata = new List <XElement>(); foreach (FileExtensionSignInfo fileExtensionSignInfo in signingInformation.FileExtensionSignInfos) { signingMetadata.Add(new XElement( nameof(FileExtensionSignInfo), new XAttribute[] { new XAttribute(nameof(fileExtensionSignInfo.Include), fileExtensionSignInfo.Include), new XAttribute(nameof(fileExtensionSignInfo.CertificateName), fileExtensionSignInfo.CertificateName) })); } foreach (FileSignInfo fileSignInfo in signingInformation.FileSignInfos) { List <XAttribute> xAttributes = new List <XAttribute>() { new XAttribute(nameof(fileSignInfo.Include), fileSignInfo.Include), new XAttribute(nameof(fileSignInfo.CertificateName), fileSignInfo.CertificateName) }; if (!string.IsNullOrEmpty(fileSignInfo.PublicKeyToken)) { xAttributes.Add(new XAttribute(nameof(fileSignInfo.PublicKeyToken), fileSignInfo.PublicKeyToken)); } if (!string.IsNullOrEmpty(fileSignInfo.TargetFramework)) { xAttributes.Add(new XAttribute(nameof(fileSignInfo.TargetFramework), fileSignInfo.TargetFramework)); } signingMetadata.Add(new XElement(nameof(FileSignInfo), xAttributes.ToArray())); } foreach (CertificatesSignInfo certificatesSignInfo in signingInformation.CertificatesSignInfo) { signingMetadata.Add(new XElement( nameof(CertificatesSignInfo), new XAttribute[] { new XAttribute(nameof(certificatesSignInfo.Include), certificatesSignInfo.Include), new XAttribute(nameof(certificatesSignInfo.DualSigningAllowed), certificatesSignInfo.DualSigningAllowed) })); } foreach (ItemsToSign itemsToSign in signingInformation.ItemsToSign) { signingMetadata.Add(new XElement( nameof(ItemsToSign), new XAttribute[] { new XAttribute(nameof(itemsToSign.Include), itemsToSign.Include) })); } foreach (StrongNameSignInfo strongNameSignInfo in signingInformation.StrongNameSignInfos) { signingMetadata.Add(new XElement( nameof(StrongNameSignInfo), new XAttribute[] { new XAttribute(nameof(strongNameSignInfo.Include), strongNameSignInfo.Include), new XAttribute(nameof(strongNameSignInfo.PublicKeyToken), strongNameSignInfo.PublicKeyToken), new XAttribute(nameof(strongNameSignInfo.CertificateName), strongNameSignInfo.CertificateName) })); } return(new XElement(nameof(SigningInformation), signingMetadata)); }
public void GivenEmptySigningInfoList() { SigningInformation actualMerged = pushMetadata.MergeSigningInfo(new List <SigningInformation>()); actualMerged.Should().Be(null); }
public void GivenDuplicateSigningInfo() { SigningInformation actualMerged = pushMetadata.MergeSigningInfo(ExpectedSigningInfo.Concat(ExpectedSigningInfo).ToList()); actualMerged.Should().BeEquivalentTo(ExpectedSigningInfo.First()); }
private SigningInformation GetTestInfo() { SigningInformation signingInfo = new SigningInformation() { CertificatesSignInfo = new List <CertificatesSignInfo>() { new CertificatesSignInfo() { DualSigningAllowed = true, Include = Certificate1Name, }, new CertificatesSignInfo() { DualSigningAllowed = false, Include = Certificate2Name, }, }, FileExtensionSignInfos = new List <FileExtensionSignInfo>() { new FileExtensionSignInfo() { CertificateName = Certificate1Name, Include = ".dll", }, new FileExtensionSignInfo() { CertificateName = Certificate2Name, Include = ".xbap", } }, FileSignInfos = new List <FileSignInfo>() { new FileSignInfo() { CertificateName = Certificate1Name, Include = "SomeAssembly.dll", PublicKeyToken = PublicKeyToken1, TargetFramework = TargetFramework1 }, new FileSignInfo() { CertificateName = Certificate2Name, Include = "SomeAssembly.dll", PublicKeyToken = PublicKeyToken1, TargetFramework = TargetFramework2 }, new FileSignInfo() { CertificateName = Certificate2Name, Include = "SomeOtherAssembly.dll", }, }, ItemsToSign = new List <ItemsToSign>() { new ItemsToSign() { Include = "SomeAssembly.dll" }, new ItemsToSign() { Include = "SomeOtherAssembly.dll" }, }, StrongNameSignInfos = new List <StrongNameSignInfo>() { new StrongNameSignInfo() { CertificateName = Certificate1Name, Include = "StrongName1", PublicKeyToken = PublicKeyToken1 }, new StrongNameSignInfo() { CertificateName = Certificate2Name, Include = "StrongName2", PublicKeyToken = PublicKeyToken2 } } }; return(signingInfo); }