Example usage for org.w3c.dom Element setAttributeNS

List of usage examples for org.w3c.dom Element setAttributeNS

Introduction

In this page you can find the example usage for org.w3c.dom Element setAttributeNS.

Prototype

public void setAttributeNS(String namespaceURI, String qualifiedName, String value) throws DOMException;

Source Link

Document

Adds a new attribute.

Usage

From source file:org.apache.ws.security.saml.SAMLIssuerImpl.java

/**
 * Creates a new <code>SAMLAssertion</code>.
 * <p/>//  w  w w .ja  va 2 s .c om
 * <p/>
 * A complete <code>SAMLAssertion</code> is constructed.
 *
 * @return SAMLAssertion
 */
public SAMLAssertion newAssertion() { // throws Exception {
    log.debug("Begin add SAMLAssertion token...");

    /*
     * if (senderVouches == false && userCrypto == null) { throw
     * exception("need user crypto data to insert key") }
     */
    // Issuer must enable crypto functions to get the issuer's certificate
    String issuer = properties.getProperty("org.apache.ws.security.saml.issuer");
    String name = properties.getProperty("org.apache.ws.security.saml.subjectNameId.name");
    String qualifier = properties.getProperty("org.apache.ws.security.saml.subjectNameId.qualifier");
    try {
        SAMLNameIdentifier nameId = new SAMLNameIdentifier(name, qualifier, "");
        String subjectIP = null;
        String authMethod = null;
        if ("password".equals(properties.getProperty("org.apache.ws.security.saml.authenticationMethod"))) {
            authMethod = SAMLAuthenticationStatement.AuthenticationMethod_Password;
        }
        Date authInstant = new Date();
        Collection bindings = null;

        SAMLSubject subject = new SAMLSubject(nameId, Arrays.asList(confirmationMethods), null, null);
        SAMLStatement[] statements = {
                new SAMLAuthenticationStatement(subject, authMethod, authInstant, subjectIP, null, bindings) };
        sa = new SAMLAssertion(issuer, null, null, null, null, Arrays.asList(statements));

        if (!senderVouches) {
            KeyInfo ki = new KeyInfo(instanceDoc);
            try {
                X509Certificate[] certs = userCrypto.getCertificates(username);
                if (sendKeyValue) {
                    PublicKey key = certs[0].getPublicKey();
                    String pubKeyAlgo = key.getAlgorithm();

                    if ("DSA".equalsIgnoreCase(pubKeyAlgo)) {
                        DSAKeyValue dsaKeyValue = new DSAKeyValue(instanceDoc, key);
                        ki.add(dsaKeyValue);
                    } else if ("RSA".equalsIgnoreCase(pubKeyAlgo)) {
                        RSAKeyValue rsaKeyValue = new RSAKeyValue(instanceDoc, key);
                        ki.add(rsaKeyValue);
                    }
                } else {
                    X509Data certElem = new X509Data(instanceDoc);
                    certElem.addCertificate(certs[0]);
                    ki.add(certElem);
                }
            } catch (WSSecurityException ex) {
                if (log.isDebugEnabled()) {
                    log.debug(ex.getMessage(), ex);
                }
                return null;
            } catch (XMLSecurityException ex) {
                if (log.isDebugEnabled()) {
                    log.debug(ex.getMessage(), ex);
                }
                return null;
            }
            Element keyInfoElement = ki.getElement();
            keyInfoElement.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX,
                    WSConstants.SIG_NS);

            subject.setKeyInfo(ki);
            // prepare to sign the SAML token
            try {
                X509Certificate[] issuerCerts = issuerCrypto.getCertificates(issuerKeyName);

                String sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_RSA;
                String pubKeyAlgo = issuerCerts[0].getPublicKey().getAlgorithm();
                log.debug("automatic sig algo detection: " + pubKeyAlgo);
                if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
                    sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_DSA;
                }
                java.security.Key issuerPK = issuerCrypto.getPrivateKey(issuerKeyName, issuerKeyPassword);
                sa.sign(sigAlgo, issuerPK, Arrays.asList(issuerCerts));
            } catch (WSSecurityException ex) {
                if (log.isDebugEnabled()) {
                    log.debug(ex.getMessage(), ex);
                }
                return null;
            } catch (Exception ex) {
                if (log.isDebugEnabled()) {
                    log.debug(ex.getMessage(), ex);
                }
                return null;
            }
        }
    } catch (SAMLException ex) {
        if (log.isDebugEnabled()) {
            log.debug(ex.getMessage(), ex);
        }
        throw new RuntimeException(ex.toString(), ex);
    }
    return sa;
}

From source file:org.apache.ws.security.saml.SamlNegativeTest.java

/**
 * Test that creates, sends and processes a signed SAML 2 sender-vouches
 * authentication assertion. The assertion is altered and so the signature validation
 * should fail.//from   ww  w  .  j  av  a  2s  .  c om
 */
@org.junit.Test
public void testSAML2AuthnAssertionModified() throws Exception {
    SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
    callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
    callbackHandler.setConfirmationMethod(SAML2Constants.CONF_SENDER_VOUCHES);
    callbackHandler.setIssuer("www.example.com");

    SAMLParms samlParms = new SAMLParms();
    samlParms.setCallbackHandler(callbackHandler);
    AssertionWrapper assertion = new AssertionWrapper(samlParms);

    WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
    wsSign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);

    Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
    WSSecHeader secHeader = new WSSecHeader();
    secHeader.insertSecurityHeader(doc);

    Document signedDoc = wsSign.build(doc, null, assertion, userCrypto, "wss40", "security", secHeader);

    //
    // Modify the assertion
    //
    Element envelope = signedDoc.getDocumentElement();
    NodeList list = envelope.getElementsByTagNameNS(WSConstants.SAML2_NS, "Assertion");
    Element assertionElement = (org.w3c.dom.Element) list.item(0);
    assertionElement.setAttributeNS(null, "MinorVersion", "5");

    if (LOG.isDebugEnabled()) {
        LOG.debug("SAML 2 Authn Assertion (sender vouches):");
        String outputString = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
        LOG.debug(outputString);
    }

    try {
        verify(signedDoc, trustCrypto);
        fail("Failure expected on a modified SAML Assertion");
    } catch (Exception ex) {
        // expected
    }
}

From source file:org.apache.ws.security.saml.SamlNegativeTest.java

/**
 * Test that creates a signed SAML 1.1 Assertion using HOK, but then modifies the signature
 * object by replacing the enveloped transform with the exclusive c14n transform. 
 * The signature validation should then fail - the enveloped transform is mandatory for
 * a signed assertion.//from   www  . j a v  a2  s  . c o  m
 */
@org.junit.Test
public void testSAML1SignedKeyHolderSigModified() throws Exception {
    SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
    callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
    callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
    callbackHandler.setIssuer("www.example.com");

    SAMLParms samlParms = new SAMLParms();
    samlParms.setCallbackHandler(callbackHandler);
    AssertionWrapper assertion = new AssertionWrapper(samlParms);
    assertion.signAssertion("wss40_server", "security", issuerCrypto, false);

    WSSecSAMLToken wsSign = new WSSecSAMLToken();

    Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
    WSSecHeader secHeader = new WSSecHeader();
    secHeader.insertSecurityHeader(doc);

    Document signedDoc = wsSign.build(doc, assertion, secHeader);

    //
    // Modify the assertion
    //
    Element envelope = signedDoc.getDocumentElement();
    NodeList list = envelope.getElementsByTagNameNS(WSConstants.SAML_NS, "Assertion");
    Element assertionElement = (org.w3c.dom.Element) list.item(0);
    list = assertionElement.getElementsByTagNameNS(WSConstants.SIG_NS, "Signature");
    Element sigElement = (org.w3c.dom.Element) list.item(0);
    list = sigElement.getElementsByTagNameNS(WSConstants.SIG_NS, "Transform");
    Element transformElement = (org.w3c.dom.Element) list.item(0);
    transformElement.setAttributeNS(null, "Algorithm", WSConstants.C14N_EXCL_OMIT_COMMENTS);

    if (LOG.isDebugEnabled()) {
        LOG.debug("Signed (modified) SAML message (key holder):");
        String outputString = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
        LOG.debug(outputString);
    }

    try {
        verify(signedDoc, trustCrypto);
        fail("Expected failure on a modified signature");
    } catch (WSSecurityException ex) {
        // expected
    }
}

From source file:org.apache.ws.security.saml.SamlNegativeTest.java

/**
 * Test that creates a signed SAML 2 Assertion using HOK, but then modifies the assertion.
 * The signature verification should then fail.
 *//*from   ww w  .  j  a  va 2  s  .c  o m*/
@org.junit.Test
public void testSAML2SignedKeyHolderKeyModified() throws Exception {
    SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
    callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
    callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
    callbackHandler.setIssuer("www.example.com");

    SAMLParms samlParms = new SAMLParms();
    samlParms.setCallbackHandler(callbackHandler);
    AssertionWrapper assertion = new AssertionWrapper(samlParms);
    assertion.signAssertion("wss40_server", "security", issuerCrypto, false);

    WSSecSAMLToken wsSign = new WSSecSAMLToken();

    Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
    WSSecHeader secHeader = new WSSecHeader();
    secHeader.insertSecurityHeader(doc);

    Document signedDoc = wsSign.build(doc, assertion, secHeader);
    //
    // Modify the assertion
    //
    Element envelope = signedDoc.getDocumentElement();
    NodeList list = envelope.getElementsByTagNameNS(WSConstants.SAML2_NS, "Assertion");
    Element assertionElement = (org.w3c.dom.Element) list.item(0);
    assertionElement.setAttributeNS(null, "MinorVersion", "5");

    if (LOG.isDebugEnabled()) {
        LOG.debug("Signed (modified) SAML message (key holder):");
        String outputString = org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
        LOG.debug(outputString);
    }

    try {
        verify(signedDoc, trustCrypto);
        fail("Expected failure on a modified signature");
    } catch (WSSecurityException ex) {
        // expected
    }
}

From source file:org.apache.ws.security.saml.WSSecSignatureSAML.java

/**
 * Initialize a WSSec SAML Signature./*from   w  w w  .  j a v  a2 s. c o  m*/
 * 
 * The method sets up and initializes a WSSec SAML Signature structure after
 * the relevant information was set. After setup of the references to
 * elements to sign may be added. After all references are added they can be
 * signed.
 * 
 * This method does not add the Signature element to the security header.
 * See <code>prependSignatureElementToHeader()</code> method.
 * 
 * @param doc
 *            The SOAP envelope as <code>Document</code>
 * @param uCrypto
 *            The user's Crypto instance
 * @param assertion
 *            the complete SAML assertion
 * @param iCrypto
 *            An instance of the Crypto API to handle keystore SAML token
 *            issuer and to generate certificates
 * @param iKeyName
 *            Private key to use in case of "sender-Vouches"
 * @param iKeyPW
 *            Password for issuer private key
 * @param secHeader
 *            The Security header
 * @throws WSSecurityException
 */
public void prepare(Document doc, Crypto uCrypto, SAMLAssertion assertion, Crypto iCrypto, String iKeyName,
        String iKeyPW, WSSecHeader secHeader) throws WSSecurityException {

    if (doDebug) {
        log.debug("Beginning ST signing...");
    }

    userCrypto = uCrypto;
    issuerCrypto = iCrypto;
    document = doc;
    issuerKeyName = iKeyName;
    issuerKeyPW = iKeyPW;

    //
    // Get some information about the SAML token content. This controls how
    // to deal with the whole stuff. First get the Authentication statement
    // (includes Subject), then get the _first_ confirmation method only
    // thats if "senderVouches" is true.
    //
    SAMLSubjectStatement samlSubjS = null;
    Iterator it = assertion.getStatements();
    while (it.hasNext()) {
        SAMLObject so = (SAMLObject) it.next();
        if (so instanceof SAMLSubjectStatement) {
            samlSubjS = (SAMLSubjectStatement) so;
            break;
        }
    }
    SAMLSubject samlSubj = null;
    if (samlSubjS != null) {
        samlSubj = samlSubjS.getSubject();
    }
    if (samlSubj == null) {
        throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLToken",
                new Object[] { "for Signature" });
    }

    String confirmMethod = null;
    it = samlSubj.getConfirmationMethods();
    if (it.hasNext()) {
        confirmMethod = (String) it.next();
    }
    if (SAMLSubject.CONF_SENDER_VOUCHES.equals(confirmMethod)) {
        senderVouches = true;
    }
    //
    // Gather some info about the document to process and store it for
    // retrieval
    //
    wsDocInfo = new WSDocInfo(doc);

    X509Certificate[] certs = null;
    PublicKey publicKey = null;

    if (senderVouches) {
        certs = issuerCrypto.getCertificates(issuerKeyName);
        wsDocInfo.setCrypto(issuerCrypto);
    }
    //
    // in case of key holder: - get the user's certificate that _must_ be
    // included in the SAML token. To ensure the cert integrity the SAML
    // token must be signed (by the issuer). Just check if its signed, but
    // don't verify this SAML token's signature here (maybe later).
    //
    else {
        if (userCrypto == null || !assertion.isSigned()) {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity",
                    new Object[] { "for SAML Signature (Key Holder)" });
        }
        Element e = samlSubj.getKeyInfo();
        try {
            KeyInfo ki = new KeyInfo(e, null);

            if (ki.containsX509Data()) {
                X509Data data = ki.itemX509Data(0);
                if (data != null && data.containsCertificate()) {
                    XMLX509Certificate certElem = data.itemCertificate(0);
                    if (certElem != null) {
                        X509Certificate cert = certElem.getX509Certificate();
                        certs = new X509Certificate[1];
                        certs[0] = cert;
                    }
                } else if (data != null && data.containsIssuerSerial()) {
                    XMLX509IssuerSerial issuerSerial = data.itemIssuerSerial(0);
                    String alias = userCrypto.getAliasForX509Cert(issuerSerial.getIssuerName(),
                            issuerSerial.getSerialNumber());
                    certs = userCrypto.getCertificates(alias);
                }
            } else if (ki.containsKeyValue()) {
                publicKey = ki.getPublicKey();
            }
            // TODO: get alias name for cert, check against username set by
            // caller
        } catch (XMLSecurityException e3) {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity",
                    new Object[] { "cannot get certificate (key holder)" }, e3);
        }
        wsDocInfo.setCrypto(userCrypto);
    }
    if ((certs == null || certs.length == 0 || certs[0] == null) && publicKey == null) {
        throw new WSSecurityException(WSSecurityException.FAILURE, "noCertsFound",
                new Object[] { "SAML signature" });
    }
    if (sigAlgo == null) {
        PublicKey key = null;
        if (certs != null && certs[0] != null) {
            key = certs[0].getPublicKey();
        } else if (publicKey != null) {
            key = publicKey;
        }

        String pubKeyAlgo = key.getAlgorithm();
        log.debug("automatic sig algo detection: " + pubKeyAlgo);
        if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
            sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_DSA;
        } else if (pubKeyAlgo.equalsIgnoreCase("RSA")) {
            sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_RSA;
        } else {
            throw new WSSecurityException(WSSecurityException.FAILURE, "unknownSignatureAlgorithm",
                    new Object[] { pubKeyAlgo });
        }
    }
    sig = null;
    if (canonAlgo.equals(WSConstants.C14N_EXCL_OMIT_COMMENTS)) {
        Element canonElem = XMLUtils.createElementInSignatureSpace(doc, Constants._TAG_CANONICALIZATIONMETHOD);

        canonElem.setAttributeNS(null, Constants._ATT_ALGORITHM, canonAlgo);

        if (wssConfig.isWsiBSPCompliant()) {
            Set prefixes = getInclusivePrefixes(secHeader.getSecurityHeader(), false);

            InclusiveNamespaces inclusiveNamespaces = new InclusiveNamespaces(doc, prefixes);

            canonElem.appendChild(inclusiveNamespaces.getElement());
        }
        try {
            SignatureAlgorithm signatureAlgorithm = new SignatureAlgorithm(doc, sigAlgo);
            sig = new XMLSignature(doc, null, signatureAlgorithm.getElement(), canonElem);
        } catch (XMLSecurityException e) {
            log.error("", e);
            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null, e);
        }
    } else {
        try {
            sig = new XMLSignature(doc, null, sigAlgo, canonAlgo);
        } catch (XMLSecurityException e) {
            log.error("", e);
            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null, e);
        }
    }

    EnvelopeIdResolver resolver = (EnvelopeIdResolver) EnvelopeIdResolver.getInstance();
    resolver.setWsDocInfo(wsDocInfo);
    sig.addResourceResolver(resolver);
    String sigUri = wssConfig.getIdAllocator().createId("Signature-", sig);
    sig.setId(sigUri);

    keyInfo = sig.getKeyInfo();
    keyInfoUri = wssConfig.getIdAllocator().createSecureId("KeyId-", keyInfo);
    keyInfo.setId(keyInfoUri);

    secRef = new SecurityTokenReference(doc);
    strUri = wssConfig.getIdAllocator().createSecureId("STRId-", secRef);
    secRef.setID(strUri);

    if (certs != null && certs.length != 0) {
        certUri = wssConfig.getIdAllocator().createSecureId("CertId-", certs[0]);
    }

    //
    // If the sender vouches, then we must sign the SAML token _and_ at
    // least one part of the message (usually the SOAP body). To do so we
    // need to - put in a reference to the SAML token. Thus we create a STR
    // and insert it into the wsse:Security header - set a reference of the
    // created STR to the signature and use STR Transform during the
    // signature
    //
    Transforms transforms = null;
    try {
        if (senderVouches) {
            secRefSaml = new SecurityTokenReference(doc);
            String strSamlUri = wssConfig.getIdAllocator().createSecureId("STRSAMLId-", secRefSaml);
            secRefSaml.setID(strSamlUri);

            if (WSConstants.X509_KEY_IDENTIFIER == keyIdentifierType) {
                Element keyId = doc.createElementNS(WSConstants.WSSE_NS, "wsse:KeyIdentifier");
                keyId.setAttributeNS(null, "ValueType", WSConstants.WSS_SAML_KI_VALUE_TYPE);
                keyId.appendChild(doc.createTextNode(assertion.getId()));
                Element elem = secRefSaml.getElement();
                elem.appendChild(keyId);
            } else {
                Reference ref = new Reference(doc);
                ref.setURI("#" + assertion.getId());
                ref.setValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
                secRefSaml.setReference(ref);
            }

            Element ctx = createSTRParameter(doc);
            transforms = new Transforms(doc);
            transforms.addTransform(STRTransform.implementedTransformURI, ctx);
            sig.addDocument("#" + strSamlUri, transforms);
            wsDocInfo.setSecurityTokenReference(secRefSaml.getElement());
        }
    } catch (TransformationException e1) {
        throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null, e1);
    } catch (XMLSignatureException e1) {
        throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null, e1);
    }

    if (senderVouches) {
        switch (keyIdentifierType) {
        case WSConstants.BST_DIRECT_REFERENCE:
            Reference ref = new Reference(doc);
            ref.setURI("#" + certUri);
            bstToken = new X509Security(doc);
            ((X509Security) bstToken).setX509Certificate(certs[0]);
            bstToken.setID(certUri);
            wsDocInfo.setBst(bstToken.getElement());
            ref.setValueType(bstToken.getValueType());
            secRef.setReference(ref);
            break;

        case WSConstants.X509_KEY_IDENTIFIER:
            secRef.setKeyIdentifier(certs[0]);
            break;

        default:
            throw new WSSecurityException(WSSecurityException.FAILURE, "unsupportedKeyId");
        }
    } else {
        switch (keyIdentifierType) {
        case WSConstants.BST_DIRECT_REFERENCE:
            Reference ref = new Reference(doc);
            ref.setURI("#" + assertion.getId());
            ref.setValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
            secRef.setReference(ref);
            break;

        case WSConstants.X509_KEY_IDENTIFIER:
            Element keyId = doc.createElementNS(WSConstants.WSSE_NS, "wsse:KeyIdentifier");
            keyId.setAttributeNS(null, "ValueType", WSConstants.WSS_SAML_KI_VALUE_TYPE);
            keyId.appendChild(doc.createTextNode(assertion.getId()));
            Element elem = secRef.getElement();
            elem.appendChild(keyId);
            break;

        default:
            throw new WSSecurityException(WSSecurityException.FAILURE, "unsupportedKeyId");
        }
    }
    keyInfo.addUnknownElement(secRef.getElement());
    wsDocInfo.setSecurityTokenReference(secRef.getElement());

    Element keyInfoElement = keyInfo.getElement();
    keyInfoElement.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX, WSConstants.SIG_NS);

    try {
        samlToken = (Element) assertion.toDOM(doc);
    } catch (SAMLException e2) {
        throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE, "noSAMLdoc", null, e2);
    }
    wsDocInfo.setAssertion(samlToken);
}

From source file:org.apache.ws.security.saml.WSSignSAMLEnvelope.java

/**
 * Builds a signed soap envelope with SAML token. <p/>The method first gets
 * an appropriate security header. According to the defined parameters for
 * certificate handling the signature elements are constructed and inserted
 * into the <code>wsse:Signature</code>
 * /*from   www . ja  v a2s . c  om*/
 * @param doc
 *            The unsigned SOAP envelope as <code>Document</code>
 * @param assertion
 *            the complete SAML assertion
 * @param issuerCrypto
 *            An instance of the Crypto API to handle keystore SAML token
 *            issuer and to generate certificates
 * @param issuerKeyName
 *            Private key to use in case of "sender-Vouches"
 * @param issuerKeyPW
 *            Password for issuer private key
 * @return A signed SOAP envelope as <code>Document</code>
 * @throws org.apache.ws.security.WSSecurityException
 * @deprecated replaced by
 *             {@link WSSecSignatureSAML#build(Document, Crypto, SAMLAssertion, Crypto, String, String, WSSecHeader)}
 */
public Document build(Document doc, Crypto userCrypto, SAMLAssertion assertion, Crypto issuerCrypto,
        String issuerKeyName, String issuerKeyPW) throws WSSecurityException {

    doDebug = log.isDebugEnabled();

    long t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0;
    if (tlog.isDebugEnabled()) {
        t0 = System.currentTimeMillis();
    }
    if (doDebug) {
        log.debug("Beginning ST signing...");
    }
    /*
     * Get some information about the SAML token content. This controls how
     * to deal with the whole stuff. First get the Authentication statement
     * (includes Subject), then get the _first_ confirmation method only.
     */
    SAMLSubjectStatement samlSubjS = null;
    Iterator it = assertion.getStatements();
    while (it.hasNext()) {
        SAMLObject so = (SAMLObject) it.next();
        if (so instanceof SAMLSubjectStatement) {
            samlSubjS = (SAMLSubjectStatement) so;
            break;
        }
    }
    SAMLSubject samlSubj = null;
    if (samlSubjS != null) {
        samlSubj = samlSubjS.getSubject();
    }
    if (samlSubj == null) {
        throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLToken",
                new Object[] { "for Signature" });
    }

    String confirmMethod = null;
    it = samlSubj.getConfirmationMethods();
    if (it.hasNext()) {
        confirmMethod = (String) it.next();
    }
    boolean senderVouches = false;
    if (SAMLSubject.CONF_SENDER_VOUCHES.equals(confirmMethod)) {
        senderVouches = true;
    }
    /*
     * Gather some info about the document to process and store it for
     * retrieval
     */
    WSDocInfo wsDocInfo = new WSDocInfo(doc);

    Element envelope = doc.getDocumentElement();
    SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope);

    Element securityHeader = insertSecurityHeader(doc);
    X509Certificate[] certs = null;

    if (senderVouches) {
        certs = issuerCrypto.getCertificates(issuerKeyName);
        wsDocInfo.setCrypto(issuerCrypto);
    }
    /*
     * in case of key holder: - get the user's certificate that _must_ be
     * included in the SAML token. To ensure the cert integrity the SAML
     * token must be signed (by the issuer). Just check if its signed, but
     * don't verify this SAML token's signature here (maybe later).
     */
    else {
        if (userCrypto == null || assertion.isSigned() == false) {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity",
                    new Object[] { "for SAML Signature (Key Holder)" });
        }
        Element e = samlSubj.getKeyInfo();
        try {
            KeyInfo ki = new KeyInfo(e, null);

            if (ki.containsX509Data()) {
                X509Data data = ki.itemX509Data(0);
                XMLX509Certificate certElem = null;
                if (data != null && data.containsCertificate()) {
                    certElem = data.itemCertificate(0);
                }
                if (certElem != null) {
                    X509Certificate cert = certElem.getX509Certificate();
                    certs = new X509Certificate[1];
                    certs[0] = cert;
                }
            }
            // TODO: get alias name for cert, check against username set by
            // caller
        } catch (XMLSecurityException e3) {
            throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity",
                    new Object[] { "cannot get certificate (key holder)" }, e3);
        }
        wsDocInfo.setCrypto(userCrypto);
    }
    // Set the id of the elements to be used as digest source
    // String id = setBodyID(doc);
    if (certs == null || certs.length <= 0) {
        throw new WSSecurityException(WSSecurityException.FAILURE, "noCertsFound",
                new Object[] { "SAML signature" });
    }
    if (sigAlgo == null) {
        String pubKeyAlgo = certs[0].getPublicKey().getAlgorithm();
        log.debug("automatic sig algo detection: " + pubKeyAlgo);
        if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
            sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_DSA;
        } else if (pubKeyAlgo.equalsIgnoreCase("RSA")) {
            sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_RSA;
        } else {
            throw new WSSecurityException(WSSecurityException.FAILURE, "unknownSignatureAlgorithm",
                    new Object[] { pubKeyAlgo });
        }
    }
    XMLSignature sig = null;
    try {
        sig = new XMLSignature(doc, null, sigAlgo, canonAlgo);
    } catch (XMLSecurityException e) {
        throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null, e);
    }

    KeyInfo info = sig.getKeyInfo();
    String keyInfoUri = wssConfig.getIdAllocator().createSecureId("KeyId-", info);
    info.setId(keyInfoUri);

    SecurityTokenReference secRef = new SecurityTokenReference(doc);
    String strUri = wssConfig.getIdAllocator().createSecureId("STRId-", secRef);
    secRef.setID(strUri);

    String certUri = wssConfig.getIdAllocator().createSecureId("CertId-", certs[0]);

    if (tlog.isDebugEnabled()) {
        t1 = System.currentTimeMillis();
    }

    if (parts == null) {
        parts = new Vector();
        WSEncryptionPart encP = new WSEncryptionPart(soapConstants.getBodyQName().getLocalPart(),
                soapConstants.getEnvelopeURI(), "Content");
        parts.add(encP);
    }

    /*
     * If the sender vouches, then we must sign the SAML token _and_ at
     * least one part of the message (usually the SOAP body). To do so we
     * need to - put in a reference to the SAML token. Thus we create a STR
     * and insert it into the wsse:Security header - set a reference of the
     * created STR to the signature and use STR Transfrom during the
     * signature
     */
    Transforms transforms = null;
    SecurityTokenReference secRefSaml = null;

    try {
        if (senderVouches) {
            secRefSaml = new SecurityTokenReference(doc);
            String strSamlUri = wssConfig.getIdAllocator().createSecureId("STRSAMLId-", secRefSaml);
            secRefSaml.setID(strSamlUri);
            // Decouple Refernce/KeyInfo setup - quick shot here
            Reference ref = new Reference(doc);
            ref.setURI("#" + assertion.getId());
            ref.setValueType(WSConstants.WSS_SAML_NS + WSConstants.WSS_SAML_ASSERTION);
            secRefSaml.setReference(ref);
            // up to here
            Element ctx = createSTRParameter(doc);
            transforms = new Transforms(doc);
            transforms.addTransform(STRTransform.implementedTransformURI, ctx);
            sig.addDocument("#" + strSamlUri, transforms);
        }
        for (int part = 0; part < parts.size(); part++) {
            WSEncryptionPart encPart = (WSEncryptionPart) parts.get(part);
            String elemName = encPart.getName();
            String nmSpace = encPart.getNamespace();

            /*
             * Set up the elements to sign. There are two resevered element
             * names: "Token" and "STRTransform" "Token": Setup the
             * Signature to either sign the information that points to the
             * security token or the token itself. If its a direct reference
             * sign the token, otherwise sign the KeyInfo Element.
             * "STRTransform": Setup the ds:Reference to use STR Transform
             * 
             */
            if (elemName.equals("Token")) {
                transforms = new Transforms(doc);
                transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
                if (keyIdentifierType == WSConstants.BST_DIRECT_REFERENCE) {
                    sig.addDocument("#" + certUri, transforms);
                } else {
                    sig.addDocument("#" + keyInfoUri, transforms);
                }
            } else if (elemName.equals("STRTransform")) { // STRTransform
                Element ctx = createSTRParameter(doc);
                transforms = new Transforms(doc);
                transforms.addTransform(STRTransform.implementedTransformURI, ctx);
                sig.addDocument("#" + strUri, transforms);
            } else {
                Element body = (Element) WSSecurityUtil.findElement(envelope, elemName, nmSpace);
                if (body == null) {
                    throw new WSSecurityException(WSSecurityException.FAILURE, "noEncElement",
                            new Object[] { nmSpace + ", " + elemName });
                }
                transforms = new Transforms(doc);
                transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
                sig.addDocument("#" + setWsuId(body), transforms);
            }
        }
    } catch (TransformationException e1) {
        throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null, e1);
    } catch (XMLSignatureException e1) {
        throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null, e1);
    }

    sig.addResourceResolver(EnvelopeIdResolver.getInstance());

    /*
     * The order to prepend is: - signature - BinarySecurityToken (depends
     * on mode) - SecurityTokenRefrence (depends on mode) - SAML token
     */

    WSSecurityUtil.prependChildElement(securityHeader, sig.getElement());

    if (tlog.isDebugEnabled()) {
        t2 = System.currentTimeMillis();
    }
    switch (keyIdentifierType) {
    case WSConstants.BST_DIRECT_REFERENCE:
        Reference ref = new Reference(doc);
        if (senderVouches) {
            ref.setURI("#" + certUri);
            BinarySecurity bstToken = null;
            bstToken = new X509Security(doc);
            ((X509Security) bstToken).setX509Certificate(certs[0]);
            bstToken.setID(certUri);
            WSSecurityUtil.prependChildElement(securityHeader, bstToken.getElement());
            wsDocInfo.setBst(bstToken.getElement());
            ref.setValueType(bstToken.getValueType());
        } else {
            ref.setURI("#" + assertion.getId());
            ref.setValueType(WSConstants.WSS_SAML_NS + WSConstants.WSS_SAML_ASSERTION);
        }
        secRef.setReference(ref);
        break;
    //
    // case WSConstants.ISSUER_SERIAL :
    // XMLX509IssuerSerial data =
    // new XMLX509IssuerSerial(doc, certs[0]);
    // secRef.setX509IssuerSerial(data);
    // break;
    //
    // case WSConstants.X509_KEY_IDENTIFIER :
    // secRef.setKeyIdentifier(certs[0]);
    // break;
    //
    // case WSConstants.SKI_KEY_IDENTIFIER :
    // secRef.setKeyIdentifierSKI(certs[0], crypto);
    // break;
    //
    default:
        throw new WSSecurityException(WSSecurityException.FAILURE, "unsupportedKeyId");
    }

    if (tlog.isDebugEnabled()) {
        t3 = System.currentTimeMillis();
    }
    info.addUnknownElement(secRef.getElement());

    Element keyInfoElement = info.getElement();
    keyInfoElement.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX, WSConstants.SIG_NS);

    Element samlToken = null;
    try {
        samlToken = (Element) assertion.toDOM(doc);
    } catch (SAMLException e2) {
        throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE, "noSAMLdoc", null, e2);
    }
    if (senderVouches) {
        WSSecurityUtil.prependChildElement(securityHeader, secRefSaml.getElement());
    }

    wsDocInfo.setAssertion(samlToken);
    WSSecurityUtil.prependChildElement(securityHeader, samlToken);

    boolean remove = WSDocInfoStore.store(wsDocInfo);
    try {
        if (senderVouches) {
            sig.sign(issuerCrypto.getPrivateKey(issuerKeyName, issuerKeyPW));
        } else {
            sig.sign(userCrypto.getPrivateKey(user, password));
        }
        signatureValue = sig.getSignatureValue();
    } catch (XMLSignatureException e1) {
        throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE, null, null, e1);
    } catch (Exception e1) {
        throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE, null, null, e1);
    } finally {
        if (remove) {
            WSDocInfoStore.delete(wsDocInfo);
        }
    }
    if (tlog.isDebugEnabled()) {
        t4 = System.currentTimeMillis();
        tlog.debug("SignEnvelope: cre-Sig= " + (t1 - t0) + " set transform= " + (t2 - t1) + " sec-ref= "
                + (t3 - t2) + " signature= " + (t4 - t3));
    }
    if (doDebug) {
        log.debug("Signing complete.");
    }
    return (doc);

}

From source file:org.apache.ws.security.transform.STRTransformUtil.java

protected static Element createBSTX509(Document doc, X509Certificate cert, Element secRefE)
        throws WSSecurityException {
    byte data[];/*from  www. ja  v a  2  s.  co m*/
    try {
        data = cert.getEncoded();
    } catch (CertificateEncodingException e) {
        throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, "encodeError", null, e);
    }
    String prefix = WSSecurityUtil.getPrefixNS(WSConstants.WSSE_NS, secRefE);
    Element elem = doc.createElementNS(WSConstants.WSSE_NS, prefix + ":BinarySecurityToken");
    WSSecurityUtil.setNamespace(elem, WSConstants.WSSE_NS, prefix);
    // elem.setAttributeNS(WSConstants.XMLNS_NS, "xmlns", "");
    elem.setAttributeNS(null, "ValueType", X509Security.X509_V3_TYPE);
    Text certText = doc.createTextNode(Base64.encode(data)); // no line wrap
    elem.appendChild(certText);
    return elem;
}

From source file:org.apache.ws.security.util.WSSecurityUtil.java

/**
 * Set a namespace/prefix on an element if it is not set already. First off, it
 * searches for the element for the prefix associated with the specified
 * namespace. If the prefix isn't null, then this is returned. Otherwise, it
 * creates a new attribute using the namespace/prefix passed as parameters.
 * /*w  w  w  .jav a 2 s. c om*/
 * @param element
 * @param namespace
 * @param prefix
 * @return the prefix associated with the set namespace
 */
public static String setNamespace(Element element, String namespace, String prefix) {
    String pre = getPrefixNS(namespace, element);
    if (pre != null) {
        return pre;
    }
    element.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" + prefix, namespace);
    return prefix;
}

From source file:org.apache.ws.security.util.WSSecurityUtil.java

/**
 * Return a string for a particular QName, mapping a new prefix if
 * necessary.//w  ww.  j av a  2 s .  co  m
 */
public static String getStringForQName(QName qname, Element e) {
    String uri = qname.getNamespaceURI();
    String prefix = getPrefixNS(uri, e);
    if (prefix == null) {
        int i = 1;
        prefix = "ns" + i;
        while (getNamespace(prefix, e) != null) {
            i++;
            prefix = "ns" + i;
        }
        e.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" + prefix, uri);
    }
    return prefix + ":" + qname.getLocalPart();
}

From source file:org.apache.ws.security.util.WSSecurityUtil.java

/**
 * find a ws-security header block for a given actor <p/>
 * //w w w  .j  a  v a  2  s.co m
 * @param doc the DOM document (SOAP request)
 * @param envelope the SOAP envelope
 * @param actor the actor (role) name of the WSS header
 * @param doCreate if true create a new WSS header block if none exists
 * @return the WSS header or null if none found and doCreate is false
 */
public static Element findWsseSecurityHeaderBlock(Document doc, Element envelope, String actor,
        boolean doCreate) {
    SOAPConstants sc = getSOAPConstants(envelope);
    Element wsseSecurity = getSecurityHeader(doc, actor, sc);
    if (wsseSecurity != null) {
        return wsseSecurity;
    }
    Element header = findChildElement(envelope, sc.getEnvelopeURI(), sc.getHeaderQName().getLocalPart());
    if (header == null && doCreate) {
        header = createElementInSameNamespace(envelope, sc.getHeaderQName().getLocalPart());
        header = prependChildElement(envelope, header);
    }
    if (doCreate) {
        wsseSecurity = header.getOwnerDocument().createElementNS(WSConstants.WSSE_NS, "wsse:Security");
        wsseSecurity.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsse", WSConstants.WSSE_NS);
        return prependChildElement(header, wsseSecurity);
    }
    return null;
}