private byte[] doSignature(
      List<WSEncryptionPart> sigs,
      TokenWrapper policyTokenWrapper,
      Token policyToken,
      SecurityToken tok,
      boolean included)
      throws WSSecurityException {
    if (policyToken.isDerivedKeys()) {
      return doSignatureDK(sigs, policyTokenWrapper, policyToken, tok, included);
    } else {
      WSSecSignature sig = new WSSecSignature(wssConfig);
      sig.setWsConfig(wssConfig);
      // If a EncryptedKeyToken is used, set the correct value type to
      // be used in the wsse:Reference in ds:KeyInfo
      int type =
          included ? WSConstants.CUSTOM_SYMM_SIGNING : WSConstants.CUSTOM_SYMM_SIGNING_DIRECT;
      if (policyToken instanceof X509Token) {
        if (isRequestor()) {
          sig.setCustomTokenValueType(
              WSConstants.SOAPMESSAGE_NS11 + "#" + WSConstants.ENC_KEY_VALUE_TYPE);
          sig.setKeyIdentifierType(type);
        } else {
          // the tok has to be an EncryptedKey token
          sig.setEncrKeySha1value(tok.getSHA1());
          sig.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
        }
      } else if (policyToken instanceof UsernameToken) {
        sig.setCustomTokenValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
        sig.setKeyIdentifierType(type);
      } else {
        // Setting the AttachedReference or the UnattachedReference according to the flag
        Element ref;
        if (included) {
          ref = tok.getAttachedReference();
        } else {
          ref = tok.getUnattachedReference();
        }

        if (ref != null) {
          SecurityTokenReference secRef = new SecurityTokenReference(cloneElement(ref), false);
          sig.setSecurityTokenReference(secRef);
          sig.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
        } else {
          String tokenType = tok.getTokenType();
          if (WSConstants.WSS_SAML_TOKEN_TYPE.equals(tokenType)
              || WSConstants.SAML_NS.equals(tokenType)) {
            sig.setCustomTokenValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
            sig.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
          } else if (WSConstants.WSS_SAML2_TOKEN_TYPE.equals(tokenType)
              || WSConstants.SAML2_NS.equals(tokenType)) {
            sig.setCustomTokenValueType(WSConstants.WSS_SAML2_KI_VALUE_TYPE);
            sig.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
          } else {
            sig.setCustomTokenValueType(tokenType);
            sig.setKeyIdentifierType(type);
          }
        }
      }

      String sigTokId;
      if (included) {
        sigTokId = tok.getWsuId();
        if (sigTokId == null) {
          if (policyToken instanceof SecureConversationToken
              || policyToken instanceof SecurityContextToken) {
            sig.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING_DIRECT);
          }
          sigTokId = tok.getId();
        }
        if (sigTokId.startsWith("#")) {
          sigTokId = sigTokId.substring(1);
        }
      } else {
        sigTokId = tok.getId();
      }

      if (included && sbinding.isTokenProtection()) {
        sigs.add(new WSEncryptionPart(sigTokId));
      }

      sig.setCustomTokenId(sigTokId);
      sig.setSecretKey(tok.getSecret());
      sig.setSignatureAlgorithm(sbinding.getAlgorithmSuite().getSymmetricSignature());
      Crypto crypto = null;
      if (sbinding.getProtectionToken() != null) {
        crypto = getEncryptionCrypto(sbinding.getProtectionToken());
      } else {
        crypto = getSignatureCrypto(policyTokenWrapper);
      }
      this.message.getExchange().put(SecurityConstants.SIGNATURE_CRYPTO, crypto);
      sig.prepare(saaj.getSOAPPart(), crypto, secHeader);
      sig.setParts(sigs);
      List<Reference> referenceList = sig.addReferencesToSign(sigs, secHeader);

      // Do signature
      if (bottomUpElement == null) {
        sig.computeSignature(referenceList, false, null);
      } else {
        sig.computeSignature(referenceList, true, bottomUpElement);
      }
      bottomUpElement = sig.getSignatureElement();

      this.mainSigId = sig.getId();
      return sig.getSignatureValue();
    }
  }
  private WSSecBase doEncryption(
      TokenWrapper recToken,
      SecurityToken encrTok,
      boolean attached,
      List<WSEncryptionPart> encrParts,
      boolean atEnd) {
    // Do encryption
    if (recToken != null && recToken.getToken() != null && encrParts.size() > 0) {
      Token encrToken = recToken.getToken();
      policyAsserted(recToken);
      policyAsserted(encrToken);
      AlgorithmSuite algorithmSuite = sbinding.getAlgorithmSuite();
      if (encrToken.isDerivedKeys()) {
        return doEncryptionDerived(recToken, encrTok, encrToken, attached, encrParts, atEnd);
      } else {
        try {
          WSSecEncrypt encr = new WSSecEncrypt(wssConfig);
          String encrTokId = encrTok.getId();
          if (attached) {
            encrTokId = encrTok.getWsuId();
            if (encrTokId == null
                && (encrToken instanceof SecureConversationToken
                    || encrToken instanceof SecurityContextToken)) {
              encr.setEncKeyIdDirectId(true);
              encrTokId = encrTok.getId();
            } else if (encrTokId == null) {
              encrTokId = encrTok.getId();
            }
            if (encrTokId.startsWith("#")) {
              encrTokId = encrTokId.substring(1);
            }
          } else {
            encr.setEncKeyIdDirectId(true);
          }
          if (encrTok.getTokenType() != null) {
            encr.setCustomReferenceValue(encrTok.getTokenType());
          }
          encr.setEncKeyId(encrTokId);
          encr.setEphemeralKey(encrTok.getSecret());
          Crypto crypto = getEncryptionCrypto(recToken);
          if (crypto != null) {
            this.message.getExchange().put(SecurityConstants.ENCRYPT_CRYPTO, crypto);
            setEncryptionUser(encr, recToken, false, crypto);
          }

          encr.setDocument(saaj.getSOAPPart());
          encr.setEncryptSymmKey(false);
          encr.setSymmetricEncAlgorithm(algorithmSuite.getEncryption());

          if (encrToken instanceof IssuedToken || encrToken instanceof SpnegoContextToken) {
            // Setting the AttachedReference or the UnattachedReference according to the flag
            Element ref;
            if (attached) {
              ref = encrTok.getAttachedReference();
            } else {
              ref = encrTok.getUnattachedReference();
            }

            String tokenType = encrTok.getTokenType();
            if (ref != null) {
              SecurityTokenReference secRef = new SecurityTokenReference(cloneElement(ref), false);
              encr.setSecurityTokenReference(secRef);
            } else if (WSConstants.WSS_SAML_TOKEN_TYPE.equals(tokenType)
                || WSConstants.SAML_NS.equals(tokenType)) {
              encr.setCustomReferenceValue(WSConstants.WSS_SAML_KI_VALUE_TYPE);
              encr.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
            } else if (WSConstants.WSS_SAML2_TOKEN_TYPE.equals(tokenType)
                || WSConstants.SAML2_NS.equals(tokenType)) {
              encr.setCustomReferenceValue(WSConstants.WSS_SAML2_KI_VALUE_TYPE);
              encr.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
            } else {
              encr.setCustomReferenceValue(tokenType);
              encr.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
            }
          } else if (encrToken instanceof UsernameToken) {
            encr.setCustomReferenceValue(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
          } else if (!isRequestor()) {
            if (encrTok.getSHA1() != null) {
              encr.setCustomReferenceValue(encrTok.getSHA1());
              encr.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
            } else {
              encr.setKeyIdentifierType(WSConstants.EMBED_SECURITY_TOKEN_REF);
            }
          }

          encr.prepare(saaj.getSOAPPart(), crypto);

          if (encr.getBSTTokenId() != null) {
            encr.prependBSTElementToHeader(secHeader);
          }

          Element refList = encr.encryptForRef(null, encrParts);
          if (atEnd) {
            this.insertBeforeBottomUp(refList);
          } else {
            this.addDerivedKeyElement(refList);
          }
          return encr;
        } catch (WSSecurityException e) {
          policyNotAsserted(recToken, e);
        }
      }
    }
    return null;
  }
  private byte[] doSignatureDK(
      List<WSEncryptionPart> sigs,
      TokenWrapper policyTokenWrapper,
      Token policyToken,
      SecurityToken tok,
      boolean included)
      throws WSSecurityException {
    Document doc = saaj.getSOAPPart();
    WSSecDKSign dkSign = new WSSecDKSign(wssConfig);
    if (policyTokenWrapper.getToken().getSPConstants() == SP12Constants.INSTANCE) {
      dkSign.setWscVersion(ConversationConstants.VERSION_05_12);
    }

    // Check for whether the token is attached in the message or not
    boolean attached = false;
    if (includeToken(policyToken.getInclusion())) {
      attached = true;
    }

    // Setting the AttachedReference or the UnattachedReference according to the flag
    Element ref;
    if (attached) {
      ref = tok.getAttachedReference();
    } else {
      ref = tok.getUnattachedReference();
    }

    if (ref != null) {
      dkSign.setExternalKey(tok.getSecret(), cloneElement(ref));
    } else if (!isRequestor() && policyToken.isDerivedKeys() && tok.getSHA1() != null) {
      // If the Encrypted key used to create the derived key is not
      // attached use key identifier as defined in WSS1.1 section
      // 7.7 Encrypted Key reference
      SecurityTokenReference tokenRef = new SecurityTokenReference(doc);
      if (tok.getSHA1() != null) {
        tokenRef.setKeyIdentifierEncKeySHA1(tok.getSHA1());
        String tokenType = tok.getTokenType();
        if (tokenType == null) {
          tokenType = WSConstants.WSS_ENC_KEY_VALUE_TYPE;
        }
        tokenRef.addTokenType(tokenType);
      }
      dkSign.setExternalKey(tok.getSecret(), tokenRef.getElement());
    } else {
      if ((!attached && !isRequestor())
          || policyToken instanceof SecureConversationToken
          || policyToken instanceof SecurityContextToken) {
        dkSign.setTokenIdDirectId(true);
      }
      dkSign.setExternalKey(tok.getSecret(), tok.getId());
    }

    // Set the algo info
    dkSign.setSignatureAlgorithm(sbinding.getAlgorithmSuite().getSymmetricSignature());
    dkSign.setDerivedKeyLength(sbinding.getAlgorithmSuite().getSignatureDerivedKeyLength() / 8);
    if (tok.getSHA1() != null) {
      // Set the value type of the reference
      String tokenType = tok.getTokenType();
      if (tokenType == null) {
        tokenType = WSConstants.WSS_ENC_KEY_VALUE_TYPE;
      }
      dkSign.setCustomValueType(tokenType);
    } else {
      String tokenType = tok.getTokenType();
      if (WSConstants.WSS_SAML_TOKEN_TYPE.equals(tokenType)
          || WSConstants.SAML_NS.equals(tokenType)) {
        dkSign.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
        dkSign.setCustomValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
      } else if (WSConstants.WSS_SAML2_TOKEN_TYPE.equals(tokenType)
          || WSConstants.SAML2_NS.equals(tokenType)) {
        dkSign.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
        dkSign.setCustomValueType(WSConstants.WSS_SAML2_KI_VALUE_TYPE);
      } else if (policyToken instanceof UsernameToken) {
        dkSign.setCustomValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
      } else {
        dkSign.setCustomValueType(tokenType);
      }
    }

    try {
      dkSign.prepare(doc, secHeader);
    } catch (ConversationException e) {
      throw new WSSecurityException(e.getMessage(), e);
    }

    if (sbinding.isTokenProtection()) {
      String sigTokId = tok.getId();
      if (included) {
        sigTokId = tok.getWsuId();
        if (sigTokId == null) {
          sigTokId = tok.getId();
        }
        if (sigTokId.startsWith("#")) {
          sigTokId = sigTokId.substring(1);
        }
      }
      sigs.add(new WSEncryptionPart(sigTokId));
    }

    dkSign.setParts(sigs);
    List<Reference> referenceList = dkSign.addReferencesToSign(sigs, secHeader);

    // Add elements to header
    Element el = dkSign.getdktElement();
    addDerivedKeyElement(el);

    // Do signature
    if (bottomUpElement == null) {
      dkSign.computeSignature(referenceList, false, null);
    } else {
      dkSign.computeSignature(referenceList, true, bottomUpElement);
    }
    bottomUpElement = dkSign.getSignatureElement();

    this.mainSigId = dkSign.getSignatureId();

    return dkSign.getSignatureValue();
  }
  private WSSecBase doEncryptionDerived(
      TokenWrapper recToken,
      SecurityToken encrTok,
      Token encrToken,
      boolean attached,
      List<WSEncryptionPart> encrParts,
      boolean atEnd) {
    try {
      WSSecDKEncrypt dkEncr = new WSSecDKEncrypt(wssConfig);
      if (recToken.getToken().getSPConstants() == SP12Constants.INSTANCE) {
        dkEncr.setWscVersion(ConversationConstants.VERSION_05_12);
      }

      if (attached && encrTok.getAttachedReference() != null) {
        dkEncr.setExternalKey(encrTok.getSecret(), cloneElement(encrTok.getAttachedReference()));
      } else if (encrTok.getUnattachedReference() != null) {
        dkEncr.setExternalKey(encrTok.getSecret(), cloneElement(encrTok.getUnattachedReference()));
      } else if (!isRequestor() && encrTok.getSHA1() != null) {
        // If the Encrypted key used to create the derived key is not
        // attached use key identifier as defined in WSS1.1 section
        // 7.7 Encrypted Key reference
        SecurityTokenReference tokenRef = new SecurityTokenReference(saaj.getSOAPPart());
        tokenRef.setKeyIdentifierEncKeySHA1(encrTok.getSHA1());
        String tokenType = encrTok.getTokenType();
        if (tokenType == null) {
          tokenType = WSConstants.WSS_ENC_KEY_VALUE_TYPE;
        }
        tokenRef.addTokenType(tokenType);
        dkEncr.setExternalKey(encrTok.getSecret(), tokenRef.getElement());
      } else {
        if (attached) {
          String id = encrTok.getWsuId();
          if (id == null
              && (encrToken instanceof SecureConversationToken
                  || encrToken instanceof SecurityContextToken)) {
            dkEncr.setTokenIdDirectId(true);
            id = encrTok.getId();
          } else if (id == null) {
            id = encrTok.getId();
          }
          if (id.startsWith("#")) {
            id = id.substring(1);
          }
          dkEncr.setExternalKey(encrTok.getSecret(), id);
        } else {
          dkEncr.setTokenIdDirectId(true);
          dkEncr.setExternalKey(encrTok.getSecret(), encrTok.getId());
        }
      }

      if (encrTok.getSHA1() != null) {
        String tokenType = encrTok.getTokenType();
        if (tokenType == null) {
          tokenType = WSConstants.WSS_ENC_KEY_VALUE_TYPE;
        }
        dkEncr.setCustomValueType(tokenType);
      } else {
        String tokenType = encrTok.getTokenType();
        if (WSConstants.WSS_SAML_TOKEN_TYPE.equals(tokenType)
            || WSConstants.SAML_NS.equals(tokenType)) {
          dkEncr.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
          dkEncr.setCustomValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
        } else if (WSConstants.WSS_SAML2_TOKEN_TYPE.equals(tokenType)
            || WSConstants.SAML2_NS.equals(tokenType)) {
          dkEncr.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
          dkEncr.setCustomValueType(WSConstants.WSS_SAML2_KI_VALUE_TYPE);
        } else if (encrToken instanceof UsernameToken) {
          dkEncr.setCustomValueType(WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE);
        } else {
          dkEncr.setCustomValueType(tokenType);
        }
      }

      dkEncr.setSymmetricEncAlgorithm(sbinding.getAlgorithmSuite().getEncryption());
      dkEncr.setDerivedKeyLength(sbinding.getAlgorithmSuite().getEncryptionDerivedKeyLength() / 8);
      dkEncr.prepare(saaj.getSOAPPart());
      Element encrDKTokenElem = null;
      encrDKTokenElem = dkEncr.getdktElement();
      addDerivedKeyElement(encrDKTokenElem);
      Element refList = dkEncr.encryptForExternalRef(null, encrParts);
      if (atEnd) {
        this.insertBeforeBottomUp(refList);
      } else {
        this.addDerivedKeyElement(refList);
      }
      return dkEncr;
    } catch (Exception e) {
      policyNotAsserted(recToken, e);
    }
    return null;
  }