protected Token processIssueResponse()

in modules/rampart-trust/src/main/java/org/apache/rahas/client/STSClient.java [391:605]


    protected Token processIssueResponse(int version, OMElement result,
            String issuerAddress) throws TrustException {
        OMElement rstr = result;

        /**
         * TODO :-
         * There are 3 mechanisms to establish a security context token.
         * They are,
         * 1. Security context token created by a security token service
         * 2. Security context token created by one of the communicating parties and propagated with a
         * message
         * 3. Security context token created through negotiation/exchanges
         *
         * As per now we are only supporting case 1. Therefore we always expect a
         * wst:RequestSecurityTokenResponseCollection in the incoming message.
         *
         * This only applies when we use specification http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512
         */

        if (version == RahasConstants.VERSION_05_12) {
            //The WS-SX result will be an RSTRC
            rstr = result.getFirstElement();
        }

        String ns = TrustUtil.getWSTNamespace(version);

        //Get the RequestedAttachedReference
        OMElement reqAttElem = rstr.getFirstChildWithName(new QName(
                ns, RahasConstants.IssuanceBindingLocalNames.REQUESTED_ATTACHED_REFERENCE));
        OMElement reqAttRef = reqAttElem == null ? null : reqAttElem.getFirstElement();

        //Get the RequestedUnattachedReference
        OMElement reqUnattElem =
                rstr.getFirstChildWithName(new QName(ns,
                                                     RahasConstants.IssuanceBindingLocalNames.
                                                             REQUESTED_UNATTACHED_REFERENCE));
        OMElement reqUnattRef = reqUnattElem == null ? null : reqUnattElem.getFirstElement();

        //Get the security token
        OMElement reqSecTok =
                rstr.getFirstChildWithName(new QName(ns,
                                                     RahasConstants.IssuanceBindingLocalNames.
                                                             REQUESTED_SECURITY_TOKEN));
        if (reqSecTok == null) {
            throw new TrustException("reqestedSecTokMissing");
        }

        OMElement tokenElem = reqSecTok.getFirstElement();

        String id = this.findIdentifier(reqAttRef, reqUnattRef, tokenElem);

        if (id == null) {
            throw new TrustException("cannotObtainTokenIdentifier");
        }

        OMElement lifeTimeEle =
                rstr.getFirstChildWithName(new QName(ns,
                                                     RahasConstants.IssuanceBindingLocalNames.
                                                             LIFETIME));

        Token token = new Token(id, tokenElem, lifeTimeEle);
        token.setIssuerAddress(issuerAddress);
        token.setAttachedReference(reqAttRef);
        token.setUnattachedReference(reqUnattRef);

        //Handle proof token
        OMElement rpt =
                rstr.getFirstChildWithName(new QName(ns,
                                                     RahasConstants.LocalNames.
                                                             REQUESTED_PROOF_TOKEN));

        byte[] secret = null;

        if (rpt != null) {
            OMElement child = rpt.getFirstElement();
            if (child == null) {
                throw new TrustException("invalidRPT");
            }
            if (child.getQName().equals(new QName(ns,
                                                  RahasConstants.LocalNames.
                                                          BINARY_SECRET))) {
                //First check for the binary secret
                String b64Secret = child.getText();
                secret = Base64Utils.decode(b64Secret);
            } else if (child.getQName().equals(new QName(ns, WSConstants.ENC_KEY_LN))) {

                Element domChild = (Element)OMXMLBuilderFactory.createStAXOMBuilder(
                        OMAbstractFactory.getMetaFactory(
                                OMAbstractFactory.FEATURE_DOM).getOMFactory(),
                        child.getXMLStreamReader()).getDocumentElement();

                try {
                    RequestData requestData = new RequestData();
	            boolean disableBSPEnforcement = false;
                    if (this.options != null && this.options.getProperty(RahasConstants.DISABLE_BSP_ENFORCEMENT) != null) {
	                disableBSPEnforcement = Boolean.parseBoolean((String) this.options.getProperty(RahasConstants.DISABLE_BSP_ENFORCEMENT));
                        requestData.setDisableBSPEnforcement(disableBSPEnforcement);
		    }
	            boolean allowUsernameTokenNoPassword = false;
                    if (this.options != null && this.options.getProperty(RahasConstants.ALLOW_USERNAME_TOKEN_NO_PASSWORD) != null) {
	                allowUsernameTokenNoPassword = Boolean.parseBoolean((String) this.options.getProperty(RahasConstants.ALLOW_USERNAME_TOKEN_NO_PASSWORD));
                        requestData.setAllowUsernameTokenNoPassword(allowUsernameTokenNoPassword);
		    }

                    int timeStampFutureTTL = 60;
                    if (this.options != null && this.options.getProperty(RahasConstants.TIMESTAMP_FUTURE_TTL) != null) {
	                timeStampFutureTTL = Integer.valueOf((String) this.options.getProperty(RahasConstants.TIMESTAMP_FUTURE_TTL));
                        requestData.setTimeStampFutureTTL(timeStampFutureTTL);
		    }

                    int utTTL = 300;
                    if (this.options != null && this.options.getProperty(RahasConstants.UT_TTL) != null) {
	                utTTL = Integer.valueOf((String) this.options.getProperty(RahasConstants.UT_TTL));
                        requestData.setUtTTL(utTTL);
		    }

                    int utFutureTTL = 60;
                    if (this.options != null && this.options.getProperty(RahasConstants.UT_FUTURE_TTL) != null) {
	                utFutureTTL = Integer.valueOf((String) this.options.getProperty(RahasConstants.UT_FUTURE_TTL));
                        requestData.setUtFutureTTL(utFutureTTL);
		    }

                    /* WSS4J sets this as false however before 1.8.0 this was hard-coded to true */
                    boolean handleCustomPasswordTypes = true;
                    if (this.options != null && this.options.getProperty(RahasConstants.HANDLE_CUSTOM_PASSWORD_TYPES) != null) {
	                handleCustomPasswordTypes = Boolean.valueOf((String) this.options.getProperty(RahasConstants.HANDLE_CUSTOM_PASSWORD_TYPES));
                        requestData.setHandleCustomPasswordTypes(handleCustomPasswordTypes);
		    }

                    boolean allowNamespaceQualifiedPasswordTypes = false;
                    if (this.options != null && this.options.getProperty(RahasConstants.ALLOW_NAMESPACE_QUALIFIED_PASSWORDTYPES) != null) {
	                allowNamespaceQualifiedPasswordTypes = Boolean.valueOf((String) this.options.getProperty(RahasConstants.ALLOW_NAMESPACE_QUALIFIED_PASSWORDTYPES));
                        requestData.setAllowNamespaceQualifiedPasswordTypes(allowNamespaceQualifiedPasswordTypes);
		    }

                    boolean encodePasswords = false;
                    if (this.options != null && this.options.getProperty(RahasConstants.ENCODE_PASSWORDS) != null) {
	                encodePasswords = Boolean.valueOf((String) this.options.getProperty(RahasConstants.ENCODE_PASSWORDS));
                        requestData.setEncodePasswords(encodePasswords);
		    }

                    boolean validateSamlSubjectConfirmation = false; // backward compatibility
                    if (this.options != null && this.options.getProperty(RahasConstants.VALIDATE_SAML_SUBJECT_CONFIRMATION) != null) {
	                validateSamlSubjectConfirmation = Boolean.valueOf((String) this.options.getProperty(RahasConstants.VALIDATE_SAML_SUBJECT_CONFIRMATION));
                        requestData.setValidateSamlSubjectConfirmation(validateSamlSubjectConfirmation);
		    }

                    boolean allowRSA15KeyTransportAlgorithm = true; // backward compatibility
                    if (this.options != null && this.options.getProperty(RahasConstants.ALLOW_RSA15_KEY_TRANSPORT_ALGORITHM) != null) {
	                allowRSA15KeyTransportAlgorithm = Boolean.valueOf((String) this.options.getProperty(RahasConstants.ALLOW_RSA15_KEY_TRANSPORT_ALGORITHM));
                        requestData.setAllowRSA15KeyTransportAlgorithm(allowRSA15KeyTransportAlgorithm);
		    }

                    boolean timestampStrict = false;
                    if (this.options != null && this.options.getProperty(RahasConstants.TIMESTAMP_STRICT_LN) != null) {
	                timestampStrict = Boolean.valueOf((String) this.options.getProperty(RahasConstants.TIMESTAMP_STRICT_LN));
                        requestData.setTimeStampStrict(timestampStrict);
		    }

                    boolean timestampPrecisionInMs = false;
                    if (this.options != null && this.options.getProperty(RahasConstants.TIMESTAMP_STRICT_LN) != null) {
	                timestampPrecisionInMs = Boolean.valueOf((String) this.options.getProperty(RahasConstants.TIMESTAMP_PRECISION_IN_MS_LN));
                        requestData.setPrecisionInMilliSeconds(timestampPrecisionInMs);
		    }

                    secret = CommonUtil.getDecryptedBytes(this.cbHandler, this.crypto, domChild, requestData);
                } catch (WSSecurityException e) {
                    log.error("Error decrypting encrypted key element", e);
                    throw new TrustException("errorInProcessingEncryptedKey", e);
                }

            } else if (child.getQName().equals(new QName(ns,
                    RahasConstants.IssuanceBindingLocalNames.
                            COMPUTED_KEY))) {
                //Handle the computed key

                //Get service entropy
                OMElement serviceEntrElem = rstr
                        .getFirstChildWithName(new QName(ns,
                                                         RahasConstants.IssuanceBindingLocalNames.
                                                                 ENTROPY));

                OMElement binSecElem = serviceEntrElem.getFirstElement();

                if (binSecElem != null && binSecElem.getText() != null
                    && !"".equals(binSecElem.getText().trim())) {

                    byte[] serviceEntr = Base64Utils.decode(binSecElem.getText());

                    //Right now we only use PSHA1 as the computed key algo                    
                    P_SHA1 p_sha1 = new P_SHA1();

                    int length = (this.keySize > 0) ? keySize
                                 : this.algorithmSuite
                            .getMaximumSymmetricKeyLength();
                    try {
                        secret = p_sha1.createKey(this.requestorEntropy, serviceEntr, 0, length/8);
                    } catch (WSSecurityException e) {
                        throw new TrustException("keyDerivationError", e);
                    }
                } else {
                    //Service entropy missing
                    throw new TrustException("serviceEntropyMissing");
                }
            }

        } else {
            if (this.requestorEntropy != null) {
                //Use requester entropy as the key
                secret = this.requestorEntropy;
            }
        }
        token.setSecret(secret);
        return token;
    }