/** * This action open a XML file and inspect its signatures. */ public ActionResult Index(string userfile) { // Our action only works if a userfile is given to work with. byte[] userfileContent; if (!StorageMock.TryGetFile(userfile, out userfileContent)) { return(HttpNotFound()); } // Instanciate the XmlSignatureLocator class, responsible for opening and validating the signatures // in the XML file. The signed XML content is passed as a parameter of the XmlSignatureLocator. var xmlSignatureLocator = new XmlSignatureLocator(userfileContent); // Get the list of signatures found in the XML file. var signatures = xmlSignatureLocator.GetSignatures(); // Specify the parameters for the signature validation: // Define the trust arbitrator used to validate the certificate. var trustArbitrator = Util.GetTrustArbitrator(); // Acces any valid XmlDSig signature as long as the signer certificate is trusted. var policyMapper = XmlPoliciesForValidation.GetXmlDSigBasic(trustArbitrator); // Generate a model to be shown on the page from each XmlSignature instance retrieved from // GetSignatures() method above. This class can be inspected on Models/PKi/OpenXmlSignatureModel.cs // file. In this class, we validate each signature based on the policy mapper defined above. var sigModels = signatures.Select(s => new XmlSignatureModel(s, policyMapper)).ToList(); // Render the signatures' information (see file OpenXmlSignaturePki/Index.cshtml for more // information on the information returned). return(View(new OpenXmlSignatureModel() { Signatures = sigModels })); }
public async Task SaveExternalIconOverwritesFailures() { Data = "{}"; await Target.InitializeAsync(CancellationToken.None); const string originalIconUrlString = "https://source/"; var originalIconUrl = new Uri(originalIconUrlString); const string successStorageUrlString = "https://storage2/"; var successStorageUrl = new Uri(successStorageUrlString); Target.SaveExternalCopyFailure(originalIconUrl); await Target.SaveExternalIcon(originalIconUrl, successStorageUrl, StorageMock.Object, IconCacheStorageMock.Object, CancellationToken.None); StorageMock .Verify( ics => ics.CopyAsync(successStorageUrl, IconCacheStorageMock.Object, It.IsAny <Uri>(), It.IsAny <IReadOnlyDictionary <string, string> >(), CancellationToken.None), Times.Once); var item = Target.Get(originalIconUrl); Assert.True(item.IsCopySucceeded); Assert.Equal(originalIconUrlString, item.SourceUrl.AbsoluteUri); Assert.Equal(DefaultResolvedUrlString, item.StorageUrl.AbsoluteUri); }
public async Task SavesCache() { Data = "{}"; await Target.InitializeAsync(CancellationToken.None); await Target.SaveExternalIcon(new Uri("https://sourcez"), new Uri("https://storage1/d"), StorageMock.Object, IconCacheStorageMock.Object, CancellationToken.None); Target.SaveExternalCopyFailure(new Uri("https://sourcey")); string savedContent = null; StorageMock .Setup(s => s.SaveAsync(new Uri("https://cache.test/blob"), It.IsAny <StringStorageContent>(), CancellationToken.None)) .Callback <Uri, StorageContent, CancellationToken>((_1, sc, _2) => savedContent = ((StringStorageContent)sc).Content) .Returns(Task.CompletedTask); await Target.SaveAsync(CancellationToken.None); StorageMock .Verify(s => s.SaveAsync(new Uri("https://cache.test/blob"), It.IsAny <StringStorageContent>(), CancellationToken.None), Times.Once); Assert.Contains("https://sourcez", savedContent); Assert.DoesNotContain("https://storage1/d", savedContent); // this url is only used for copying blob Assert.Contains(DefaultResolvedUrlString, savedContent); Assert.Contains("https://sourcey", savedContent); }
public async Task <ActionResult> Start(int id) { // Get an instance of the CadesSignatureStarter class, responsible for receiving the signature // elements and start the signature process. var signatureStarter = new CadesSignatureStarter(Util.GetRestPkiClient()) { // Set the signature policy. SignaturePolicyId = StandardCadesSignaturePolicies.PkiBrazil.AdrBasica, // Set the security context to be used to determine trust in the certificate chain. We have // encapsulated the security context choice on Util.cs. SecurityContextId = Util.GetSecurityContextId(), // Optionally, set whether the content should be encapsulated in the resulting CMS. EncapsulateContent = true }; // Set the document to be signed based on its ID (passed to us from the page). signatureStarter.SetFileToSign(StorageMock.GetBatchDocPath(id)); // Call the StartWithWebPki() method, which initiates the signature. This yields the token, a // 43-character case-sensitive URL-safe string, which identifies this signature process. We'll // use this value to call the signWithRestPki() method on the Web PKI component (see // batch-signature-form.js) and also to complete the signature on the POST action below (this // should not be mistaken with the API access token). var token = await signatureStarter.StartWithWebPkiAsync(); // Return a JSON with the token obtained from REST PKI. (the page will use jQuery to decode this // value) return(Json(token)); }
public async Task <ActionResult> Index(SignatureModel model) { // Get an instance of the XmlSignatureFinisher class, responsible for completing the signature // process. var signatureFinisher = new XmlSignatureFinisher(Util.GetRestPkiClient()) { // Set the token for this signature (rendered in a hidden input field, see the view). Token = model.Token }; // Call the Finish() method, which finalizes the signature process and returns the signed PDF. var signedXml = await signatureFinisher.FinishAsync(); // Get information about the signer's certificate used. This method must only be called after // calling the Finish() method. var signerCert = signatureFinisher.GetCertificateInfo(); // At this point, you'd typically store the signed XML on your database. For demonstration // purposes, we'll store the PDF on our mock Storage class. var fileId = StorageMock.Store(signedXml, ".xml"); // Render the signature information page. return(View("SignatureInfo", new SignatureInfoModel() { File = fileId, SignerCertificate = signerCert })); }
public ActionResult Index(MergeServerFilesModel model) { string dataFileId, fileId1, fileId2; switch (model.ChosenCombination) { case 0: dataFileId = StorageMock.CopySampleToAppData(SampleDocs.CmsDataFile); fileId1 = StorageMock.CopySampleToAppData(SampleDocs.CmsDetached1); fileId2 = StorageMock.CopySampleToAppData(SampleDocs.CmsDetached2); return(RedirectToAction("Index", model.ReturnController, new { file1 = fileId1, file2 = fileId2, datafile = dataFileId })); case 1: dataFileId = StorageMock.CopySampleToAppData(SampleDocs.CmsDataFile); fileId1 = StorageMock.CopySampleToAppData(SampleDocs.CmsAttached1); fileId2 = StorageMock.CopySampleToAppData(SampleDocs.CmsDetached2); return(RedirectToAction("Index", model.ReturnController, new { file1 = fileId1, file2 = fileId2, datafile = dataFileId })); case 2: default: fileId1 = StorageMock.CopySampleToAppData(SampleDocs.CmsAttached1); fileId2 = StorageMock.CopySampleToAppData(SampleDocs.CmsAttached2); return(RedirectToAction("Index", model.ReturnController, new { file1 = fileId1, file2 = fileId2 })); } }
public ActionResult Start(BatchSignatureStartRequest request) { // Instantiate a CadesSigner class var cadesSigner = new CadesSigner(); // Get the file's content. if (!StorageMock.TryGetFile(StorageMock.GetBatchDocPath(request.Id), out byte[] fileContent))
public ActionResult Complete(BatchSignatureCompleteRequest request) { byte[] signatureContent; // Recover the "transfer data" content stored in a temporary file. byte[] transferDataContent; if (!StorageMock.TryGetFile(request.TransferDataFileId, out transferDataContent)) { return(HttpNotFound()); } // Instantiate a PadesSigner class var padesSigner = new PadesSigner(); // Set the signature policy. padesSigner.SetPolicy(GetSignaturePolicy()); // Set the signature computed on the client-side, along with the "transfer data" recovered from a temporary file padesSigner.SetPreComputedSignature(request.Signature, transferDataContent); // Call ComputeSignature(), which does all the work, including validation of the signer's certificate and of the // resulting signature padesSigner.ComputeSignature(); // Get the signed PDF as an array of bytes signatureContent = padesSigner.GetPadesSignature(); return(Json(new BatchSignatureCompleteResponse() { SignedFileId = StorageMock.Store(signatureContent, ".pdf") })); }
public async Task <ActionResult> Index(string userfile) { // Our action only works if a userfile is given to work with. if (!StorageMock.TryGetFile(userfile, out string userfilePath)) { return(HttpNotFound()); } // Get an instance of the PadesSignatureExplorer class, used to open/validate PDF signatures. var sigExplorer = new PadesSignatureExplorer(Util.GetRestPkiClient()) { // Specify that we want to validate the signatures in the file, not only inspect them. Validate = true, // Specify the parameters for the signature validation: // Accept any PAdES signature as long as the signer has an ICP-Brasil certificate. DefaultSignaturePolicyId = StandardPadesSignaturePolicies.Basic, // Specify the security context to be used to determine trust in the certificate chain. We // have encapsulated the security context choice on Util.cs. SecurityContextId = Util.GetSecurityContextId() }; // Set the PAdES signature file. sigExplorer.SetSignatureFile(userfilePath); // Call the Open() method, which returns the signature file's information. var signature = await sigExplorer.OpenAsync(); // Render the information (see file OpenPadesSignature/Index.html for more information on // the information returned). return(View(new OpenPadesSignatureModel() { Signature = signature })); }
public async Task <ActionResult> Complete(string id) { // Get an instance of the CadesSignatureFinisher2 class, responsible for completing the signature // process. var signatureFinisher = new CadesSignatureFinisher2(Util.GetRestPkiClient()) { // Set the token for this signature. (rendered in a hidden input field, see the view) Token = id }; // Call the Finish() method, which finalizes the signature process and returns a // SignatureResult object. var result = await signatureFinisher.FinishAsync(); // The "Certificate" property of the SignatureResult object contains information about the // certificate used by the user to sign the file. var signerCert = result.Certificate; // At this point, you'd typically store the signed PDF on your database. For demonstration // purposes, we'll store the PDF on our mock Storage class. // The SignatureResult object has various methods for writing the signature file to a stream // (WriteTo()), local file (WriteToFile()), open a stream to read the content (OpenRead()) and // get its contents (GetContent()). For large files, avoid the method GetContent() to avoid // memory allocation issues. string fileId; using (var resultStream = result.OpenRead()) { fileId = StorageMock.Store(resultStream, ".p7s"); } // Return a JSON with the signed file's id, stored using our mock class (the page will use // jQuery to decode this value). return(Json(fileId)); }
public ActionResult Sample(SampleDocs id) { string filename; var content = StorageMock.GetSampleDocContent(id, out filename); return(File(content, MimeMapping.GetMimeMapping(filename), filename)); }
// You may also change texts, positions and more by editing directly the method // generatePrinterFriendlyVersion() below. // #################################################################################################### // GET: PrinterFriendlyPadesRestPki?userfile={id} public ActionResult Index(string userfile) { // Locate document and read content from storage. Our action only works if the a valid fileId is // given. byte[] fileContent; try { fileContent = StorageMock.Read(userfile); } catch (FileNotFoundException) { return(HttpNotFound()); } // Check if doc already has a verification code registered on storage. var verificationCode = StorageMock.GetVerificationCode(userfile); if (verificationCode == null) { // If not, generate a code an register it. verificationCode = Util.GenerateVerificationCode(); StorageMock.SetVerificationCode(userfile, verificationCode); } // Generate the printer-friendly version. var pfvContent = generatePrinterFriendlyVersion(fileContent, verificationCode); // Return printer-friendly version as a downloadable file. return(File(pfvContent, "application/pdf", "printer-friendly.pdf")); }
public ActionResult Complete(SignatureCompleteModel model) { byte[] signatureContent; try { // Recover the "transfer data" content stored in a temporary file. if (!StorageMock.TryGetFile(model.TransferDataFileId, out byte[] transferDataContent))
public void TestQueueStartAddDirectoryWithFiles() { var directoryName = Guid.NewGuid().ToString(); var directory = Directory.CreateDirectory(directoryName); var fileName1 = directory.FullName + "\\" + Guid.NewGuid().ToString(); var fileName2 = directory.FullName + "\\" + Guid.NewGuid().ToString(); using (var fs = File.Create(fileName1)) { } using (var fs = File.Create(fileName2)) { } var provider = new TokenProvider(new LexerMock()); var storage = new StorageMock(); using (var objectUnderTest = new FileQueue(storage, provider)) { objectUnderTest.Add(directory.FullName); Thread.Sleep((int)(FileQueue.ProcessPeriodMS * 1.25)); Assert.AreEqual(2, storage.Actions.Count); var file1 = storage.Actions.Dequeue(); var file2 = storage.Actions.Dequeue(); Assert.IsTrue((file1.Item1 == fileName1 && file2.Item1 == fileName2) || (file1.Item1 == fileName2 && file2.Item1 == fileName1)); Assert.AreEqual(file1.Item2, StorageMock._Add); Assert.AreEqual(file2.Item2, StorageMock._Add); } File.Delete(fileName1); File.Delete(fileName2); Directory.Delete(directory.FullName); }
public async Task SavesFailureExpiration() { Data = "{}"; await Target.InitializeAsync(CancellationToken.None); var time = DateTimeOffset.UtcNow; const string failedUrl = "https://icon.test/fail"; Target.SaveExternalCopyFailure(new Uri(failedUrl)); string savedContent = null; StorageMock .Setup(s => s.SaveAsync(new Uri("https://cache.test/blob"), It.IsAny <StringStorageContent>(), CancellationToken.None)) .Callback <Uri, StorageContent, CancellationToken>((_1, sc, _2) => savedContent = ((StringStorageContent)sc).Content) .Returns(Task.CompletedTask); await Target.SaveAsync(CancellationToken.None); var savedDictionary = JsonConvert.DeserializeObject <Dictionary <Uri, ExternalIconCopyResult> >(savedContent); var item = Assert.Single(savedDictionary, e => e.Key.AbsoluteUri == failedUrl); Assert.NotNull(item.Value.Expiration); Assert.True(item.Value.Expiration - time < TimeSpan.FromSeconds(2)); }
public void TestAddDirectoryCreateFileChangeFileRenameFileRemoveFileFast() { var directoryName = Guid.NewGuid().ToString(); var directory = Directory.CreateDirectory(directoryName); var provider = new TokenProvider(new LexerMock()); var storage = new StorageMock(); using (var objectUnderTest = new FileQueue(storage, provider)) { objectUnderTest.Add(directory.FullName); var fileName = directory.FullName + "\\" + Guid.NewGuid().ToString(); using (var fs = File.Create(fileName)) { fs.Write(new byte[] { 1 }, 0, 1); } using (StreamWriter sw = new StreamWriter(fileName)) { sw.Write('a'); sw.Flush(); sw.Close(); } var newFileName = directory.FullName + "\\" + Guid.NewGuid().ToString(); File.Move(fileName, newFileName); File.Delete(newFileName); Thread.Sleep((int)(0.1 * FileQueue.ProcessPeriodMS)); Assert.AreEqual(1, storage.Actions.Count); Thread.Sleep((int)(1.25 * FileQueue.ProcessPeriodMS)); Assert.AreEqual(1, storage.Actions.Count); var tuple = storage.Actions.Dequeue(); Assert.AreEqual(newFileName, tuple.Item1); Assert.AreEqual(StorageMock._Delete, tuple.Item2); } Directory.Delete(directory.FullName); }
public async Task <ActionResult> Index(string userfile) { // Get an instance of the PadesSignatureExplorer class, used to open/validate PDF signatures. var sigExplorer = new PadesSignatureExplorer(Util.GetRestPkiClient()) { // Specify that we want an audit package to be generated, and that the signed file should be // included in the package. GenerateAuditPackage = true, IncludeSignedFileInAuditPackage = true, // In order to generate an audit package, we must also pass Validate = true. Validate = true, // Specify the parameters for the signature validation: // Accept any PAdES signature as long as the signer has an ICP-Brasil certificate. DefaultSignaturePolicyId = StandardPadesSignaturePolicies.Basic, // We have encapsulated the security context choice on Util.cs. SecurityContextId = Util.GetSecurityContextId() }; // Set the PDF file. if (string.IsNullOrEmpty(userfile)) { // If no file is passed, we use a previously signed and B-Stamped file. sigExplorer.SetSignatureFile(Server.MapPath("~/Content/bstamped.pdf")); } else { sigExplorer.SetSignatureFile(Server.MapPath("~/App_Data/" + userfile.Replace("_", "."))); // Note: we're receiving the userfile argument with "_" as "." because of limitations of // ASP.NET MVC. } // Call the OpenAsync() method, which returns the signature file's information. var signature = await sigExplorer.OpenAsync(); // If the document has been B-Stamped, store the "digest index file" to show a link on the page. if (signature.BStamp != null) { string indexFileId; using (var indexFileStream = signature.BStamp.IndexFile.OpenRead()) { indexFileId = StorageMock.Store(indexFileStream, ".txt"); } ViewBag.BStampIndexFile = indexFileId; } // Store the generated audit package. Notice that although we asked for its generation, the // signature might not have been B-Stamped yet, so an audit package might not be returned. if (signature.AuditPackage != null) { string auditPkgId; using (var auditPkgStream = signature.AuditPackage.OpenRead()) { auditPkgId = StorageMock.Store(auditPkgStream, ".zip"); } ViewBag.AuditPackageFile = auditPkgId; } // Render the information. (see file Views/OpenPadesSignatureBStamp/Index.html for more // information on the information returned) return(View(signature)); }
public ActionResult Index(SignatureStartModel model) { byte[] toSignBytes, transferData; SignatureAlgorithm signatureAlg; try { // Verify if the userfile exists and get its absolute path. string userfilePath; if (!StorageMock.TryGetFile(model.UserFile, out userfilePath)) { return(HttpNotFound()); } // Decode the user's certificate. var cert = PKCertificate.Decode(model.CertContent); // Get an instance of the PadesSigner class. var padesSigner = new PadesSigner(); // Set the file to be signed. padesSigner.SetPdfToSign(userfilePath); // Set the signer certificate. padesSigner.SetSigningCertificate(cert); // Set the signature policy. padesSigner.SetPolicy(GetSignaturePolicy()); // Set a visual representation for the signature. padesSigner.SetVisualRepresentation(PadesVisualElements.GetVisualRepresentationForPkiSdk(cert)); // Generate the "to-sign-bytes". This method also yields the signature algorithm that must // be used on the client-side, based on the signature policy, as well as the "transfer data", // a byte-array that will be needed on the next step. toSignBytes = padesSigner.GetToSignBytes(out signatureAlg, out transferData); } catch (ValidationException ex) { // Some of the operations above may throw a ValidationException, for instance if the certificate // encoding cannot be read or if the certificate is expired. ModelState.AddModelError("", ex.ValidationResults.ToString()); return(View()); } // On the next step (Complete action), we'll need once again some information: // - The thumbprint of the selected certificate. // - The "transfer data" used to validate the signature in complete action. Its content is stored in // a temporary file (with extension .bin) to be shared with the Complete action. // - The "to-sign-hash" (digest of the "to-sign-bytes") to be signed. (see signature-complete-form.js) // - The OID of the digest algorithm to be used during the signature operation. // We'll store these values on TempData, which is a dictionary shared between actions. TempData["SignatureCompleteModel"] = new SignatureCompleteModel() { CertThumb = model.CertThumb, TransferDataFileId = StorageMock.Store(transferData, ".bin"), ToSignHash = signatureAlg.DigestAlgorithm.ComputeHash(toSignBytes), DigestAlgorithmOid = signatureAlg.DigestAlgorithm.Oid }; return(RedirectToAction("Complete", new { userfile = model.UserFile })); }
private async Task OnDocumentSignatureCompletedAsync(DocumentModel model) { var restPkiService = Util.GetRestPkiService(); var apiDocument = await restPkiService.GetDocumentAsync(model); var content = await restPkiService.GetContentAsync(apiDocument.SignedFile.Location); StorageMock.Store(content, "", apiDocument.SignedFile.Name); }
public async Task DeleteAllAsync_Sunshine() { StorageMock .Setup(crd => crd.DeleteAllAsync(CancellationToken.None)).Returns(Task.CompletedTask); await _serviceToTest.DeleteAllAsync(); StorageMock.Verify(); }
public void TestQueueSimpleStartStop() { var provider = new TokenProvider(new LexerMock()); var storage = new StorageMock(); using (var objectUnderTest = new FileQueue(storage, provider)) { } }
public async Task DeleteAsync_Sunshine() { StorageMock .Setup(crd => crd.DeleteAsync(It.Is <string>(id => id == TestModelServerId), CancellationToken.None)).Returns(Task.CompletedTask); await _serviceToTest.DeleteAsync(TestModelServerId); StorageMock.Verify(); }
public ActionResult SignCodeh(string id, SignatureStartModel model) { // Recover XML envelope with signed COD element from "storage" based on its ID byte[] content; if (!StorageMock.TryGetFile(id, out content)) { return(HttpNotFound()); } byte[] toSignHash, transferData; SignatureAlgorithm signatureAlg; try { // Get an instance of the XmlElementSigner class. var signer = new XmlElementSigner(); // Set the XML to sign signer.SetXml(content); // Set the ID of the CODEH element signer.SetToSignElementId("CODEH"); // Decode the user's certificate and set as the signer certificate signer.SetSigningCertificate(PKCertificate.Decode(model.CertContent)); // Set the signature policy signer.SetPolicy(getSignaturePolicy()); // Generate the "to-sign-hash". This method also yields the signature algorithm that must // be used on the client-side, based on the signature policy. toSignHash = signer.GenerateToSignHash(out signatureAlg, out transferData); } catch (ValidationException ex) { // Some of the operations above may throw a ValidationException, for instance if the certificate // encoding cannot be read or if the certificate is expired. ModelState.AddModelError("", ex.ValidationResults.ToString()); return(View()); } // On the next step (SignCodehComplete action), we'll need once again some information: // - The thumpprint of the selected certificate // - The "to-sign-hash" // - The OID of the digest algorithm to be used during the signature operation // - The "transfer data" used to validate the signature in complete action.Its content is stored in // a temporary file (with extension .bin) to be shared with the Complete action. TempData["SignatureCompleteModel"] = new SignatureCompleteModel() { CertThumb = model.CertThumb, ToSignHash = toSignHash, DigestAlgorithmOid = signatureAlg.DigestAlgorithm.Oid, TransferDataFileId = StorageMock.Store(transferData, ".bin"), }; return(RedirectToAction("SignCodehComplete", new { id })); }
// GET: CadesServerKeySdk public ActionResult Index(string userfile) { byte[] signatureContent; PKCertificateWithKey certWithKey; try { // Instantiate a CadesSigner class var cadesSigner = new CadesSigner(); // Verify if the userfile exists and get the content of the userfile. if (!StorageMock.TryGetFile(userfile, out byte[] userfileContent))
public async Task CreateWithSpecifiedIdAsync_Sunshine() { StorageMock .Setup(crd => crd.CreateWithSpecifiedIdAsync(It.Is <string>(id => id == TestModelServerId), It.Is <TestModelCreate>(create => create.Status == TestModelServerStatus), CancellationToken.None)).Returns(Task.CompletedTask); var serverInItem = GetServerTestModel(); await _serviceToTest.CreateWithSpecifiedIdAsync(TestModelServerId, serverInItem); StorageMock.Verify(); }
public ActionResult Index(ServerFilesModel model) { // Copy file to the App_Data folder, where the upload files is stored. var fileId = StorageMock.CopySampleToAppData(model.ChosenFileId); if (model.IsCmsCoSign) { return(RedirectToAction("Index", model.ReturnController, new { cmsfile = fileId })); } return(RedirectToAction("Index", model.ReturnController, new { userfile = fileId })); }
public async Task InitializeAsyncReadsJson() { Data = "{ \"https://key\": { \"SourceUrl\": \"https://source.test/data\", \"StorageUrl\": \"https://dest.test/data2\", \"IsCopySucceeded\": true } }"; await Target.InitializeAsync(CancellationToken.None); StorageMock.VerifyAll(); var cache = Target.Get(new Uri("https://key")); Assert.NotNull(cache); Assert.Equal("https://source.test/data", cache.SourceUrl.AbsoluteUri); Assert.Equal("https://dest.test/data2", cache.StorageUrl.AbsoluteUri); }
public async Task CreateAsync_Sunshine() { StorageMock .Setup(crd => crd.CreateAsync(It.Is <TestModelCreate>(create => create.Status == TestModelServerStatus), CancellationToken.None)) .ReturnsAsync(TestModelServerId); var serverInItem = GetServerTestModel(); var id = await _serviceToTest.CreateAsync(serverInItem); Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(id); Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(TestModel.DecoratedId(ServerName, TestModelServerId), id); StorageMock.Verify(); }
public ActionResult SignCodehComplete(string id, SignatureCompleteModel model) { // Recover XML envelope with signed COD element from "storage" based on its ID byte[] content; if (!StorageMock.TryGetFile(id, out content)) { return(HttpNotFound()); } byte[] signatureContent; try { // Recover the "transfer data" content stored in a temporary file. byte[] transferDataContent; if (!StorageMock.TryGetFile(model.TransferDataFileId, out transferDataContent)) { return(HttpNotFound()); } // Get an instance of the XmlElementSigner class. var signer = new XmlElementSigner(); // Set the document to be signed and the policy, exactly like in the SignCodeh method signer.SetXml(content); signer.SetPolicy(getSignaturePolicy()); // Set the signature computed on the client-side, along with the "transfer data" signer.SetPrecomputedSignature(model.Signature, transferDataContent); // Call ComputeSignature(), which validates the signature of the "to-sign-hash" and finishes the signature process signer.ComputeSignature(); // Get the signed XML as an array of bytes signatureContent = signer.GetSignedXml(); } catch (ValidationException ex) { // Some of the operations above may throw a ValidationException, for instance if the certificate is revoked. ModelState.AddModelError("", ex.ValidationResults.ToString()); return(View()); } // On the next step (SignatureInfo action), we'll render the following information: // - The filename to be available to download in next action. // We'll store these values on TempData, which is a dictionary shared between actions. TempData["SignatureInfoModel"] = new SignatureInfoModel() { // Store the signature file on the folder "App_Data/" and redirect to the SignCodehResult action with the filename. File = StorageMock.Store(signatureContent, ".xml") }; return(RedirectToAction("SignCodehSignatureInfo")); }
public void ShouldUpdateStorageForEveryEvents() { var inputData = new List <Guid> { Guid.NewGuid(), Guid.NewGuid() }; var eventsSource = new EventsSourceMock(inputData); var storage = new StorageMock(); var sut = new EventsProcessorWithAutoConcurrency(storage); sut.Process(eventsSource); Assert.AreEqual(storage.Result.Count, inputData.Count); }