예제 #1
0
파일: XRD.cs 프로젝트: AArnott/dotnetxri
        //throws XMLSecurityException
        /**
        * This will verify the XRD against the given public key.  DOM
        * must already be associated with this descriptor.
        * @param oPubKey
        * @throws XMLSecurityException
        */
        public void verifySignature(PublicKey oPubKey)
        {
            if (moElem == null) {
                throw new XMLSecurityException(
                "Cannot verify the signature. No DOM stored for XRD");
            }

            // make sure the ID attribute is present
            string sIDAttr = Tags.ATTR_ID_LOW;
            string sIDAttrNS = Tags.NS_XML;
            string sID = moElem.getAttributeNS(sIDAttrNS, sIDAttr);
            if ((sID == null) || (sID.Equals(""))) {
                throw new XMLSecurityException(
                        "Cannot verify the signature. ID is missing for " +
                        moElem.LocalName);
            }
            string sRef = "#" + sID;

            // Set the DOM so that it can be verified
            DOM3Utils.bestEffortSetIDAttr(moElem, sIDAttrNS, sIDAttr);

            XmlElement oAssertionElem =
                DOMUtils.getFirstChildElement(
                        moElem, Tags.NS_SAML, Tags.TAG_ASSERTION);

            if (oAssertionElem == null) {
                throw new XMLSecurityException(
                "Cannot verify the signature. No Assertion in XRD");
            }

            XmlElement oSigElem =
                DOMUtils.getFirstChildElement(
                        oAssertionElem, Tags.NS_XMLDSIG, Tags.TAG_SIGNATURE);

            if (oSigElem == null) {
                throw new XMLSecurityException(
                "Cannot verify the signature. No signature in Assertion");
            }

            // create the signature element to verify
            XMLSignature oSig = null;
            oSig = new XMLSignature(oSigElem, null);

            // Validate the signature content by checking the references
            string sFailedRef = null;
            SignedInfo oSignedInfo = oSig.getSignedInfo();
            if (oSignedInfo.getLength() != 1) {
                throw new XMLSecurityException(
                        "Cannot verify the signature. Expected 1 reference, got " +
                        oSignedInfo.getLength());
            }

            // make sure it references the correct element
            Reference oRef = oSignedInfo.item(0);
            string sURI = oRef.getURI();
            if (!sRef.Equals(sURI)) {
                throw new XMLSecurityException(
                "Cannot verify the signature. Reference Uri did not match ID");
            }

            // check that the transforms are ok
            bool bEnvelopedFound = false;
            Transforms oTransforms = oRef.getTransforms();
            for (int i = 0; i < oTransforms.getLength(); i++) {
                string sTransform = oTransforms.item(i).getURI();
                if (Transforms.TRANSFORM_ENVELOPED_SIGNATURE.Equals(sTransform)) {
                    // mark that we got the required transform
                    bEnvelopedFound = true;
                } else if (
                        !Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS.Equals(
                                sTransform)) {
                    // bonk if we don't have one of the two acceptable transforms
                    throw new XMLSecurityException(
                    "Unexpected transform in signature");
                }
            }

            if (!bEnvelopedFound) {
                throw new XMLSecurityException(
                        "Could not find expected " +
                        Transforms.TRANSFORM_ENVELOPED_SIGNATURE +
                " transform in signature");
            }

            // finally check the signature
            if (!oSig.checkSignatureValue(oPubKey)) {
                throw new RuntimeException("Signature failed to verify.");
            }
        }