/// <summary> /// Will return the resources for the provided digital signature. /// </summary> /// <param name="signature">The signature to get resources for.</param> /// <returns>The signature resources.</returns> internal static SignatureResources GetResources(DigitalSignature signature, CertificatePriorityStatus certStatus) { const int defaultHeight = 35; const int defaultWidth = 35; SignatureResources resources = new SignatureResources(); string none = SR.Get(SRID.SignatureResourceHelperNone); resources._displayImage = GetImageFromStatus( defaultHeight, defaultWidth, signature.SignatureState, certStatus); resources._location = string.IsNullOrEmpty(signature.Location) ? none : signature.Location; resources._reason = string.IsNullOrEmpty(signature.Reason) ? none : signature.Reason; resources._signBy = GetFormattedDate(signature.SignedOn); resources._subjectName = signature.SubjectName; resources._summaryMessage = GetSummaryMessage(signature, certStatus); Trace.SafeWrite( Trace.Rights, "Resources generated for {0} summary: {1}", resources._subjectName, resources._summaryMessage); return(resources); }
/// <summary> /// See IDigitalSignatureProvider /// </summary> Guid IDigitalSignatureProvider.AddRequestSignature(DigitalSignature digitalSignature) { AssertIsSignable(); // Create guid used for signature ID Guid guidID = Guid.NewGuid(); // Create a new SignatureDefinition XpsSignatureDefinition xpsSignatureDefinition = new XpsSignatureDefinition(); // Use the digSig to setup the SignatureDefinition. xpsSignatureDefinition.RequestedSigner = digitalSignature.SubjectName; xpsSignatureDefinition.Intent = digitalSignature.Reason; xpsSignatureDefinition.SigningLocale = digitalSignature.Location; xpsSignatureDefinition.SignBy = digitalSignature.SignedOn; // Use our new guid to setup the ID xpsSignatureDefinition.SpotId = guidID; // Add the signature definition to the document FixedDocument.AddSignatureDefinition(xpsSignatureDefinition); FixedDocument.CommitSignatureDefinition(); // Set the signature's status to Not Signed before adding to our list digitalSignature.SignatureState = SignatureStatus.NotSigned; // Add the new signature to our list of signatures and definitions DigitalSignatureList.Add(digitalSignature); return(guidID); }
/// <summary> /// See IDigitalSignatureProvider /// </summary> void IDigitalSignatureProvider.SignDocument(DigitalSignature digitalSignature) { AssertIsSignable(); XpsDigSigPartAlteringRestrictions reachRestrictions = XpsDigSigPartAlteringRestrictions.None; if (digitalSignature.IsDocumentPropertiesRestricted) { reachRestrictions |= XpsDigSigPartAlteringRestrictions.CoreMetadata; } // If additional signatures should invalidate this signature, we // need to sign the signature origin part if (digitalSignature.IsAddingSignaturesRestricted) { reachRestrictions |= XpsDigSigPartAlteringRestrictions.SignatureOrigin; } // a null guid means there was no associated spot, so create a guid if (digitalSignature.GuidID == null) { digitalSignature.GuidID = Guid.NewGuid(); } XpsDigitalSignature xpsDigitalSignature = XpsDocument.SignDigitally( digitalSignature.Certificate, true, reachRestrictions, (Guid)digitalSignature.GuidID, false /* don't re-verify IsSignable, we've already done it */ ); if (xpsDigitalSignature != null) { // Fill in relevant fields from the XPS signature digitalSignature.XpsDigitalSignature = xpsDigitalSignature; digitalSignature.SignatureState = SignatureStatus.Valid; digitalSignature.SignedOn = xpsDigitalSignature.SigningTime; // Save the simple name from the certificate as the subject name // in the signature digitalSignature.SubjectName = digitalSignature.Certificate.GetNameInfo( X509NameType.SimpleName, false /* don't include issuer name */); // Add the new signature to the list (if it isn't already there). // That is a possibility since the first signature in a document // is always added as a signature definition and a signature. if (!DigitalSignatureList.Contains(digitalSignature)) { DigitalSignatureList.Add(digitalSignature); } } }
/// <summary> /// Maps an XpsSignatureDefinition to our DigitalSignature. /// </summary> /// <param name="signatureDefinition">The signature definition to /// convert</param> /// <returns>A DigitalSignature representing a requested signature with /// signature status NotSigned</returns> private static DigitalSignature ConvertXpsSignatureDefinition(XpsSignatureDefinition signatureDefinition) { //Create new DigSig. This is a request and will have the status NotSigned. DigitalSignature digitalSignature = new DigitalSignature(); digitalSignature.SignatureState = SignatureStatus.NotSigned; //set fields using the definition. digitalSignature.SubjectName = signatureDefinition.RequestedSigner; digitalSignature.Reason = signatureDefinition.Intent; digitalSignature.SignedOn = signatureDefinition.SignBy; digitalSignature.Location = signatureDefinition.SigningLocale; digitalSignature.GuidID = signatureDefinition.SpotId; return(digitalSignature); }
//------------------------------------------------------ // // Private Methods // //------------------------------------------------------ /// <summary> /// Method for Signing and Save/SaveAs. /// </summary> private void SignAndSave(bool isSaveAs) { //Create new DigSig DigitalSignature digSig = null; //If this is a request, re-use the requested signature, so we update the request //to the signed version in place. if (_digitalSignatureRequest != null && _digitalSignatureRequest.GuidID != null) { digSig = _digitalSignatureRequest; } else { digSig = new DigitalSignature(); } //Get this user input and set to DigSig. digSig.Certificate = this.Certificate; // If this is a second signature that was not requested, then set the // default values for Reason and Location. if (_isSecondSignatureNotRequested) { string none = SR.Get(SRID.SignatureResourceHelperNone); digSig.Reason = none; digSig.Location = none; } else { digSig.Reason = Intent; digSig.Location = LocationText; } digSig.IsDocumentPropertiesRestricted = IsDocPropsRestricted; digSig.IsAddingSignaturesRestricted = IsDigSigRestricted; // if signing worked close because we are done // else do nothing to leave the dialog open // signing may have failed either because the user cancled or there // was a non-fatal error like the destination file was in use if (_docSigManager.SignDocument(digSig, this, isSaveAs)) { Close(); } }
/// <summary> /// Maps an XpsDigitalSignature to our DigitalSignature. /// </summary> /// <param name="xpsDigitalSignature">The signature to convert</param> /// <returns>A DigitalSignature that corresponds to the signature /// passed in as a parameter</returns> private static DigitalSignature ConvertXpsDigitalSignature(XpsDigitalSignature xpsDigitalSignature) { DigitalSignature digitalSignature = new DigitalSignature(); digitalSignature.XpsDigitalSignature = xpsDigitalSignature; X509Certificate2 x509Certificate2 = xpsDigitalSignature.SignerCertificate as X509Certificate2; digitalSignature.SignatureState = SignatureStatus.Unknown; // Copy simple fields if cert isn't null. If it is null then the // cert wasn't embedded into container so don't copy cert related // fields. if (x509Certificate2 != null) { digitalSignature.Certificate = x509Certificate2; digitalSignature.SignedOn = xpsDigitalSignature.SigningTime; // save the simple name from the certificate as the subject name // in the signature digitalSignature.SubjectName = x509Certificate2.GetNameInfo( X509NameType.SimpleName, false /* don't include issuer name */); } digitalSignature.IsDocumentPropertiesRestricted = xpsDigitalSignature.DocumentPropertiesRestricted; // If the signature origin part is signed, adding new signatures // will invalidate this signature digitalSignature.IsAddingSignaturesRestricted = xpsDigitalSignature.SignatureOriginRestricted; //These fields come from a Signature Definition. digitalSignature.Reason = string.Empty; digitalSignature.Location = string.Empty; return(digitalSignature); }
//------------------------------------------------------ // // Constructors // //------------------------------------------------------ /// <summary> /// The constructor /// </summary> internal SigningDialog(X509Certificate2 x509Certificate2, DigitalSignature digitalSignatureRequest, DocumentSignatureManager docSigManager) { if (x509Certificate2 == null) { throw new ArgumentNullException("x509Certificate2"); } if (docSigManager == null) { throw new ArgumentNullException("docSigManager"); } _docSigManager = docSigManager; _x509Certificate2 = x509Certificate2; // setting critical data. //This can be null and if so means this is a regular first signing //(not signing a request or 2nd/3rd.. regular request which can't have //signatureDefinitions.) _digitalSignatureRequest = digitalSignatureRequest; //Now we need to set all DigSig Specific Text ApplySignatureSpecificResources(); _signButton.Enabled = false; // Check DocumentManager to see if we can save package DocumentManager documentManager = DocumentManager.CreateDefault(); if (documentManager != null) { _signButton.Enabled = documentManager.CanSave; } if (DocumentRightsManagementManager.Current != null) { _signSaveAsButton.Enabled = DocumentRightsManagementManager.Current.HasPermissionToSave; } }
/// <summary> /// Builds the summary message. /// </summary> /// <param name="signature">A DigitalSignature</param> /// <returns>A summary message.</returns> private static string GetSummaryMessage(DigitalSignature signature, CertificatePriorityStatus certStatus) { if (signature == null) { return(string.Empty); } // Setup the location text. If not currently set, replace with the // string "<none>" to denote that no value was set. string location = (String.IsNullOrEmpty(signature.Location)) ? SR.Get(SRID.SignatureResourceHelperNone) : signature.Location; string result = String.Empty; switch (signature.SignatureState) { case SignatureStatus.Valid: case SignatureStatus.Invalid: case SignatureStatus.Unverifiable: // Verify that if the signature is valid, it has a certificate Invariant.Assert( !(signature.SignatureState == SignatureStatus.Valid && signature.Certificate == null), SR.Get(SRID.SignatureResourceHelperMissingCertificate)); // Create the signature status message string sigSummary = string.Format(CultureInfo.CurrentCulture, SR.Get(SRID.SignatureResourceHelperSummaryBreakLine), GetSignatureSummaryMessage(signature.SignatureState, certStatus)); // Create the certificate status message (if required) string certSummary = String.Empty; if (certStatus != CertificatePriorityStatus.Ok) { certSummary = string.Format(CultureInfo.CurrentCulture, SR.Get(SRID.SignatureResourceHelperSummaryBreakLine), GetCertificateSummaryMessage(certStatus)); } // Create the summary message using the signature and certificate messages // along with details from the current signature. result = string.Format(CultureInfo.CurrentCulture, SR.Get(SRID.SignatureResourceHelperSummaryFormat), sigSummary, certSummary, signature.SubjectName, signature.SignedOn, location); break; case SignatureStatus.NotSigned: // Create the summary message using signature information result = string.Format(CultureInfo.CurrentCulture, SR.Get(SRID.SignatureResourceHelperValidSigSummaryPending), signature.SubjectName, GetFormattedDate(signature.SignedOn), location); break; } return(result); }
//------------------------------------------------------ // // Private Methods // //------------------------------------------------------ /// <summary> /// Returns a list of all the DigitalSignature objects from the package. /// </summary> /// <returns>A list of DigitalSignature objects</returns> private IList <DigitalSignature> GetSignaturesFromPackage() { IList <DigitalSignature> signatureList = new List <DigitalSignature>(); // This will contain a mapping of GUIDs to signature definitions so // that we can easily look up the signature definition (if any) that // corresponds with a signature IDictionary <Guid, XpsSignatureDefinition> signatureDefinitionMap = new Dictionary <Guid, XpsSignatureDefinition>(); // This will contain a list of all the signature definitions that do // not have an associated GUID, which means that they have to be // requested signatures IList <XpsSignatureDefinition> requestedSignatureList = new List <XpsSignatureDefinition>(); // Enumerate all the signature definitions in all of the fixed // documents in the XPS document to generate the map of GUIDs to // signature definitions foreach (IXpsFixedDocumentReader fixedDocument in FixedDocumentSequence.FixedDocuments) { ICollection <XpsSignatureDefinition> documentSignatureDefinitionList = fixedDocument.SignatureDefinitions; if (documentSignatureDefinitionList != null) { // Add each signature definition to either the GUID map or // the list of requested signatures foreach (XpsSignatureDefinition signatureDefinition in documentSignatureDefinitionList) { // If the signature definition has a GUID, add it to the map if (signatureDefinition.SpotId != null) { signatureDefinitionMap.Add(signatureDefinition.SpotId.Value, signatureDefinition); } // If it does not have a GUID it cannot match a signature yet, // so add it to the list of requested signatures else { requestedSignatureList.Add(signatureDefinition); } } } } // Now loop through all the XpsDigitalSignatures, matching them with // signature definitions by GUID to get the signature fields that // are only found in signature definitions. foreach (XpsDigitalSignature xpsDigitalSignature in XpsDocument.Signatures) { // Convert the XPS signature into our format DigitalSignature digitalSignature = ConvertXpsDigitalSignature(xpsDigitalSignature); // Check if the signature corresponds to a definition by seeing // if the GUID is in the signature definition map bool definitionFound = xpsDigitalSignature.Id.HasValue && signatureDefinitionMap.ContainsKey(xpsDigitalSignature.Id.Value); // If the signature corresponds to a signature definition, copy // fields from the corresponding definition if (definitionFound) { XpsSignatureDefinition signatureDefinition = signatureDefinitionMap[xpsDigitalSignature.Id.Value]; // Copy SignatureDefinition fields digitalSignature.Reason = signatureDefinition.Intent; digitalSignature.Location = signatureDefinition.SigningLocale; // Now that we have found a signature that matches this // signature definition, it can no longer match any other // signatures by GUID and we can remove it from the map. signatureDefinitionMap.Remove(xpsDigitalSignature.Id.Value); } signatureList.Add(digitalSignature); } // What is left over in the signatureDefinitionMap are definitions // that don't have matching XpsDigSigs. Add these as requested // signatures. foreach (XpsSignatureDefinition signatureDefinition in signatureDefinitionMap.Values) { //Add this request signature to our list. signatureList.Add(ConvertXpsSignatureDefinition(signatureDefinition)); } // Add all the definitions we already knew were requested signatures foreach (XpsSignatureDefinition definition in requestedSignatureList) { //Add this request signature to our list. signatureList.Add(ConvertXpsSignatureDefinition(definition)); } return(signatureList); }