public IHttpActionResult Start(SignatureStartRequest request) { byte[] toSignBytes; SignatureAlgorithm signatureAlg; try { // Decode the user's certificate var cert = PKCertificate.Decode(request.Certificate); // Instantiate a CadesSigner class var cadesSigner = new CadesSigner(); // Set the data to sign, which in the case of this example is a fixed sample document if (!string.IsNullOrEmpty(request.FileId)) { cadesSigner.SetDataToSign(Storage.GetFile(request.FileId)); } else { cadesSigner.SetDataToSign(Storage.GetSampleDocContent()); } // Set the signer certificate cadesSigner.SetSigningCertificate(cert); // Set the signature policy cadesSigner.SetPolicy(getSignaturePolicy()); // 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. toSignBytes = cadesSigner.GenerateToSignBytes(out signatureAlg); } 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. return(new ResponseMessageResult(Request.CreateResponse(HttpStatusCode.BadRequest, new ValidationErrorModel(ex.ValidationResults)))); } // Create response with some informations that we'll use on Complete action and on client-side. var response = new SignatureStartResponse() { // Send to the javascript the "to sign hash" of the document and the digest algorithm that must // be used on the signature algorithm computation ToSignBytes = toSignBytes, DigestAlgorithmOid = signatureAlg.DigestAlgorithm.Oid }; return(Ok(response)); }
public ActionResult Index(SignatureStartModel model) { byte[] toSignBytes; SignatureAlgorithm signatureAlg; try { // Instantiate a CadesSigner class var cadesSigner = new CadesSigner(); // Set the data to sign, which in the case of this example is a fixed sample document cadesSigner.SetDataToSign(Storage.GetSampleDocContent()); // Decode the user's certificate and set as the signer certificate cadesSigner.SetSigningCertificate(PKCertificate.Decode(model.CertContent)); // Set the signature policy cadesSigner.SetPolicy(getSignaturePolicy()); // 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. toSignBytes = cadesSigner.GenerateToSignBytes(out signatureAlg); } 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 content of the selected certificate used to validate the signature in complete action. // - The thumbprint of the selected certificate. // - The "to-sign-bytes" used to validate the signature in 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() { CertContent = model.CertContent, CertThumb = model.CertThumb, ToSignBytes = toSignBytes, ToSignHash = signatureAlg.DigestAlgorithm.ComputeHash(toSignBytes), DigestAlgorithmOid = signatureAlg.DigestAlgorithm.Oid }; return(RedirectToAction("Complete")); }
protected void SubmitCertificateButton_Click(object sender, EventArgs e) { byte[] toSignBytes; SignatureAlgorithm signatureAlg; try { // Decode the user's certificate. var cert = PKCertificate.Decode(Convert.FromBase64String(CertificateField.Value)); // Instantiate a CadesSigner class. var cadesSigner = new CadesSigner(); // Set the data to sign, which in the case of this example is a fixed sample document. cadesSigner.SetDataToSign(Storage.GetSampleDocContent()); // Set the signer certificate. cadesSigner.SetSigningCertificate(cert); // Set the signature policy. cadesSigner.SetPolicy(getSignaturePolicy()); // 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. toSignBytes = cadesSigner.GenerateToSignBytes(out signatureAlg); } 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. ex.ValidationResults.Errors.ForEach(ve => ModelState.AddModelError("", ve.ToString())); return; } // On the next step (SubmitSignatureButton_Click action), we'll need once again some information: // - The "to-sign-bytes" // - The "to-sign-hash" (digest of the "to-sign-bytes") // - The OID of the digest algorithm to be used during the signature operation // We'll set the hidden fields on this page, that'll be loaded again. ToSignBytesField.Value = Convert.ToBase64String(toSignBytes); ToSignHashField.Value = Convert.ToBase64String(signatureAlg.DigestAlgorithm.ComputeHash(toSignBytes)); DigestAlgorithmField.Value = signatureAlg.DigestAlgorithm.Oid; }
public ActionResult Index(SignatureStartModel model) { byte[] toSignBytes; SignatureAlgorithm signatureAlg; try { // Instantiate a CadesSigner class var cadesSigner = new CadesSigner(); if (!string.IsNullOrEmpty(model.CmsFile)) { // Verify if the cmsfile exists and get the content of the cmsfile. byte[] cmsfileContent; if (!StorageMock.TryGetFile(model.CmsFile, out cmsfileContent)) { return(HttpNotFound()); } // If the URL argument "cmsfile" is filled, the user has asked to co-sign a previously signed // CMS. We'll set the path to the CMS to be co-signed, which was perviously saved in the // App_Data folder by the POST action on this controller. cadesSigner.SetSignatureToCoSign(cmsfileContent); } else { // Verify if the userfile exists and get the content of the userfile. byte[] userfileContent; if (!StorageMock.TryGetFile(model.UserFile, out userfileContent)) { return(HttpNotFound()); } // If the URL argument "userfile" is filled, it means the user was redirected here by // UploadController (signature with file uploaded by user). We'll set the path of the file to // be signed, which was saved in the App_Data folder by UploadController. cadesSigner.SetDataToSign(userfileContent); } // Decode the user's certificate and set as the signer certificate. var cert = PKCertificate.Decode(model.CertContent); cadesSigner.SetSigningCertificate(cert); // Set the signature policy cadesSigner.SetPolicy(getSignaturePolicy()); // 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. toSignBytes = cadesSigner.GenerateToSignBytes(out signatureAlg); } 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 content of the selected certificate used to validate the signature in complete action. // - The thumbprint of the selected certificate. // - The "to-sign-bytes" used to validate the signature in 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() { UserFile = model.UserFile, CmsFile = model.CmsFile, CertContent = model.CertContent, CertThumb = model.CertThumb, ToSignBytes = toSignBytes, ToSignHash = signatureAlg.DigestAlgorithm.ComputeHash(toSignBytes), DigestAlgorithmOid = signatureAlg.DigestAlgorithm.Oid }; return(RedirectToAction("Complete", new { userfile = model.UserFile, cmsfile = model.CmsFile })); }
public IHttpActionResult Start(SignatureStartRequest model) { byte[] toSign; SignatureAlgorithm signatureAlg; try { // Instantiate a CadesSigner class var cadesSigner = new CadesSigner(); // Set the data to sign, which in the case of this example is a fixed sample document cadesSigner.SetDataToSign(Util.GetSampleDocContent()); // Decode the user's certificate and set as the signer certificate cadesSigner.SetSigningCertificate(PKCertificate.Decode(model.Certificate)); // Set the signature policy cadesSigner.SetPolicy(getPolicy()); // 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. toSign = cadesSigner.GenerateToSignBytes(out signatureAlg); } 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. return Ok(new SignatureStartResponse() { Success = false, Message = "A validation error has occurred", ValidationResults = ex.ValidationResults.ToString() }); } // On the next step (Complete action), we'll need once again the signer's certificate and the // "to-sign-bytes" (besides from the document to be signed and the policy). We'll store these // values on the database and return to the page an identifier that will be later used to locate // these values again. SignatureProcess signatureProcess; using (var dbContext = new DbContext()) { signatureProcess = SignatureProcess.Create(); signatureProcess.CadesSignerCertificate = model.Certificate; signatureProcess.CadesToSign = toSign; dbContext.SignatureProcesses.Add(signatureProcess); dbContext.SaveChanges(); } // Send back to the page: // - The identifier that we'll later use to locate the user's certificate and "to-sign-bytes" // - The "to-sign-bytes" // - The OID of the digest algorithm to be used during the signature operation var response = new SignatureStartResponse() { Success = true, ProcessId = signatureProcess.Id, ToSign = toSign, DigestAlgorithmOid = signatureAlg.DigestAlgorithm.Oid }; return Ok(response); }
private void startNextSignature() { // Increment the index of the document currently being signed. DocumentIndex += 1; // Check if we have reached the end of the batch, in which case we fill the hidden field // "ToSignHashField" with value "(end)", which signals to the javascript on batch-signature-form.js // that the process is completed and the page can be unblocked. if (DocumentIndex == DocumentIds.Count) { ToSignHashField.Value = "(end)"; return; } // Get the ID of the document currently being signed. var docId = DocumentIds[DocumentIndex]; byte[] toSignBytes; SignatureAlgorithm signatureAlg; try { // Decode the user's certificate. var cert = PKCertificate.Decode(Convert.FromBase64String(CertificateField.Value)); // Instantiate a CadesSigner class. var cadesSigner = new CadesSigner(); // Set the data to sign, which in the case of this example is a fixed sample document. cadesSigner.SetDataToSign(Storage.GetBatchDocContent(docId)); // Set the signer certificate. cadesSigner.SetSigningCertificate(cert); // Set the signature policy. cadesSigner.SetPolicy(getSignaturePolicy()); // 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. toSignBytes = cadesSigner.GenerateToSignBytes(out signatureAlg); } catch (ValidationException ex) { // One or more validations failed. We log the error, update the page with a summary of what // happened to this document and start the next signature. logger.Error(ex, "Validation error starting the signature of a batch document"); setValidationError(ex.ValidationResults); startNextSignature(); return; } catch (Exception ex) { // An error has occurred. We log the error, update the page with a summary of what happened to // this document and start the next signature. logger.Error(ex, "Error starting the signature of a batch document"); setError(ex.Message); startNextSignature(); return; } // Send to the javascript the "to sign hash" of the document (digest of the "to-sign-bytes") and the // digest algorithm that must be used on the signature algorithm computation. ToSignBytesField.Value = Convert.ToBase64String(toSignBytes); ToSignHashField.Value = Convert.ToBase64String(signatureAlg.DigestAlgorithm.ComputeHash(toSignBytes)); DigestAlgorithmField.Value = signatureAlg.DigestAlgorithm.Oid; }