/// <summary> /// <p><strong>Purpose:</strong></p> <p>This method processes the references and creates the digital signature /// of the contents, and returns the whole XML Node of the signed contents. It produces an XmlNode /// of type signature.</p> /// <p>Note: Current implementation does not create a KeyInfoNode</p> /// </summary> /// <param name="references">references that we will be signing</param> /// <param name="canonicalizer">the specific canonicalizer to use</param> /// <param name="signer">the specific signer to use</param> /// <param name="signID">Signature id</param> /// <returns>Xml Node with digitally signed representation of the data</returns> /// <exception cref="ArgumentNullException">if any element is null</exception> /// <exception cref="SignatureManagerException">any internal exception thrown in this function /// is wrapped up as SignatureManagerException</exception> public XmlNode Sign(IList <IReference> references, InstantiationVO canonicalizer, InstantiationVO signer, string signID) { //Validate not null ExceptionHelper.ValidateNotNull(references, "references"); ExceptionHelper.ValidateNotNull(canonicalizer, "canonicalizer"); ExceptionHelper.ValidateNotNull(signer, "signer"); ExceptionHelper.ValidateNotNull(signID, "signID"); XmlDocument doc = new XmlDocument(); try { //Create Signature node XmlNode signatureNode = doc.CreateNode(XmlNodeType.Element, "Signature", null); //Create SignedInfo Node XmlNode signedInfoNode = CreateSignedInfoNode(doc, canonicalizer, signer, references); //Add an attribute representing default namespace to SignedInfo node //since the two have the exact literal format ((XmlElement)signedInfoNode).SetAttribute("xmlns", DEF_XMLDSIG_NS); //Get Canonicalizer and canonicalize ICanonicalizer canonInst = registry.GetCanonicalizerInstance(canonicalizer.Key, canonicalizer.Params); string canonicalized = canonInst.BringToCanonicalForm(signedInfoNode.OuterXml); //Add SignedInfo node to Signature node signatureNode.InnerXml += canonicalized; //Get Signer Instance, sign, assign to signatureValue node ISigner signerInst = registry.GetSignerInstance(signer.Key, signer.Params); string signed = signerInst.Sign(Encoding.UTF8.GetBytes(canonicalized)); XmlNode signValueNode = CreateSignatureValue(doc, signed); //Append signatureValue to Signature node signatureNode.InnerXml += signValueNode.OuterXml; //Add an attribute representing default namespace to Signature node XmlAttribute defNs = doc.CreateAttribute("xmlns"); defNs.Value = DEF_XMLDSIG_NS; signatureNode.Attributes.Append(defNs); //Add Id attribute to Signature node XmlAttribute idAttr = doc.CreateAttribute("Id"); idAttr.Value = signID; signatureNode.Attributes.Append(idAttr); //Let default namespace takes effect doc.LoadXml(signatureNode.OuterXml); return(doc.DocumentElement); } catch (Exception ex) { throw new SignatureManagerException(SIGN_MAN_EXCP_MSG, ex); } }
/// <summary> /// <p>Process the Signature node and verify the digital signatire of the contents.</p> /// </summary> /// <exception cref="VerificationException">if something went wrong during verification</exception> /// <exception cref="VerificationFailedException">if the signature is invalid</exception> /// <exception cref="ArgumentNullException">If any input parameter is null</exception> /// <param name="node">xml node with digital signature to be verified</param> /// <param name="keyInfoProvider">The key information for verifying the signature</param> /// /// <example> /// <para>If Signature node to be verified contains all non soap references /// <code> /// SignatureManager sm = new SignatureManager(); /// sm.VerifySignature(node, keyInfoProvider, null); /// </code> /// </para> /// <para>If Signature node to be verified contains soap references /// <code> /// SignatureManager sm = new SignatureManager(); /// SoapMessageReferenceLoader smrl = new SoapMessageRefernceLoader(theSoapMessage); /// sm.VerifySignature(node, keyInfoProvider, smrl); /// </code> /// Here theSoapMessage is the soap message that was signed. /// </para> /// For more information see the demo in CS and in test cases. /// </example> public void VerifySignature(XmlNode node, InstantiationVO keyInfoProvider) { //Validate not null ExceptionHelper.ValidateNotNull(node, "node"); ExceptionHelper.ValidateNotNull(keyInfoProvider, "keyInfoProvider"); try { // we use namespace manager since <Signature> has default namespace XmlNamespaceManager nsMgr = new XmlNamespaceManager(node.OwnerDocument.NameTable); nsMgr.AddNamespace("ds", DEF_XMLDSIG_NS); //Get SignedInfo node XmlNode signedInfoNode = node.SelectSingleNode("ds:SignedInfo", nsMgr); //Get CanonicalizationNode XmlNode canonNode = signedInfoNode.SelectSingleNode("ds:CanonicalizationMethod", nsMgr); string canonMethod = canonNode.Attributes.GetNamedItem("Algorithm").Value; //Get Canonicalization instance ICanonicalizer canonInst = registry.GetCanonicalizerInstance(canonMethod, emptyDic); string canonicalized = canonInst.BringToCanonicalForm(signedInfoNode.OuterXml); //Get Signing Algo XmlNode signAlgoNode = node.SelectSingleNode("ds:SignedInfo/ds:SignatureMethod", nsMgr); string signingAlgo = signAlgoNode.Attributes.GetNamedItem("Algorithm").Value; //Get Signer instance using the Signature mEthos Algorithm attribute value ISigner signer = registry.GetSignerInstance(signingAlgo, emptyDic); //Get keyInfoProvider instance IKeyInfoProvider keyInfoProviderInst = registry.GetKeyInfoProviderInstance(keyInfoProvider.Key, keyInfoProvider.Params); //Verify the sign signer.Verify(canonicalized, keyInfoProviderInst, node); //Now proceed to check all references XmlNodeList list = node.SelectNodes("ds:SignedInfo/ds:Reference", nsMgr); VerifyReferences(list, null); } catch (VerificationFailedException ex) { throw ex; } catch (Exception ex) { throw new VerificationException(VERIF_EXCP_MSG, ex); } }
/// <summary> /// <p>Process the Signature node and verify the digital signatire of the contents.</p> /// </summary> /// <exception cref="VerificationException">if something went wrong during verification</exception> /// <exception cref="VerificationFailedException">if the signature is invalid</exception> /// <exception cref="ArgumentNullException">If any input parameter is null</exception> /// <param name="node">xml node with digital signature to be verified</param> /// <param name="keyInfoProvider">The key information for verifying the signature</param> /// <param name="soapRefLoader">SoapMessageRefernceLoader instance if the Signature was used on a /// SoapMessage. Should not be null incase of verification of soapMessage. /// Can be null if verification is of a web reference. /// </param> /// /// <example> /// <para>If Signature node to be verified contains all non soap references /// <code> /// SignatureManager sm = new SignatureManager(); /// sm.VerifySignature(node, keyInfoProvider, null); /// </code> /// </para> /// <para>If Signature node to be verified contains soap references /// <code> /// SignatureManager sm = new SignatureManager(); /// SoapMessageReferenceLoader smrl = new SoapMessageRefernceLoader(theSoapMessage); /// sm.VerifySignature(node, keyInfoProvider, smrl); /// </code> /// Here theSoapMessage is the soap message that was signed. /// </para> /// For more information see the demo in CS and in test cases. /// </example> public void VerifySignature(XmlNode node, InstantiationVO keyInfoProvider, IReferenceLoader soapRefLoader) { //Validate not null ExceptionHelper.ValidateNotNull(node, "node"); ExceptionHelper.ValidateNotNull(keyInfoProvider, "keyInfoProvider"); try { //Get SignedInfo node XmlNode signedInfoNode = node.SelectSingleNode("SignedInfo"); //Get CanonicalizationNode XmlNode canonNode = signedInfoNode.SelectSingleNode("CanonicalizationMethod"); string canonMethod = canonNode.Attributes.GetNamedItem("Algorithm").Value; //Get Canonicalization instance ICanonicalizer canonInst = registry.GetCanonicalizerInstance(canonMethod, emptyDic); string canonicalized = canonInst.BringToCanonicalForm(signedInfoNode.OuterXml); //Get Signing Algo XmlNode signAlgoNode = node.SelectSingleNode("SignedInfo/SignatureMethod"); string signingAlgo = signAlgoNode.Attributes.GetNamedItem("Algorithm").Value; //Get Signer instance using the Signature mEthos Algorithm attribute value ISigner signer = registry.GetSignerInstance(signingAlgo, emptyDic); //Get keyInfoProvider instance IKeyInfoProvider keyInfoProviderInst = registry.GetKeyInfoProviderInstance(keyInfoProvider.Key, keyInfoProvider.Params); //Verify the sign signer.Verify(canonicalized, keyInfoProviderInst, node); //Now proceed to check all references XmlNodeList list = node.SelectNodes("SignedInfo/Reference"); VerifyReferences(list, soapRefLoader); } catch (VerificationFailedException ex) { throw ex; } catch (Exception ex) { throw new VerificationException(VERIF_EXCP_MSG, ex); } }