private void doSignature(
      AbstractTokenWrapper wrapper,
      AbstractToken policyToken,
      SecurityToken tok,
      List<SecurePart> sigParts)
      throws WSSecurityException, SOAPException {

    // Action
    WSSSecurityProperties properties = getProperties();
    WSSConstants.Action actionToPerform = WSSConstants.SIGNATURE;
    if (wrapper.getToken().getDerivedKeys() == DerivedKeys.RequireDerivedKeys) {
      actionToPerform = WSSConstants.SIGNATURE_WITH_DERIVED_KEY;
      if (MessageUtils.isRequestor(message) && policyToken instanceof X509Token) {
        properties.setDerivedKeyTokenReference(WSSConstants.DerivedKeyTokenReference.EncryptedKey);
      } else {
        properties.setDerivedKeyTokenReference(
            WSSConstants.DerivedKeyTokenReference.DirectReference);
      }
      AlgorithmSuiteType algSuiteType = sbinding.getAlgorithmSuite().getAlgorithmSuiteType();
      properties.setDerivedSignatureKeyLength(algSuiteType.getSignatureDerivedKeyLength() / 8);
    }

    if (policyToken.getVersion() == SPConstants.SPVersion.SP12) {
      properties.setUse200512Namespace(true);
    }

    List<WSSConstants.Action> actionList = properties.getActions();
    // Add a Signature directly before Kerberos, otherwise just append it
    boolean actionAdded = false;
    for (int i = 0; i < actionList.size(); i++) {
      WSSConstants.Action action = actionList.get(i);
      if (action.equals(WSSConstants.KERBEROS_TOKEN)) {
        actionList.add(i, actionToPerform);
        actionAdded = true;
        break;
      }
    }
    if (!actionAdded) {
      actionList.add(actionToPerform);
    }

    properties.getSignatureSecureParts().addAll(sigParts);

    AbstractToken sigToken = wrapper.getToken();
    if (sbinding.isProtectTokens() && sigToken instanceof X509Token && isRequestor()) {
      SecurePart securePart =
          new SecurePart(new QName(WSSConstants.NS_XMLENC, "EncryptedKey"), Modifier.Element);
      properties.addSignaturePart(securePart);
    }

    configureSignature(sigToken, false);

    if (policyToken instanceof X509Token) {
      properties.setIncludeSignatureToken(false);
      if (isRequestor()) {
        properties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_EncryptedKey);
      } else {
        properties.setSignatureKeyIdentifier(
            WSSecurityTokenConstants.KEYIDENTIFIER_ENCRYPTED_KEY_SHA1_IDENTIFIER);
        if (wrapper.getToken().getDerivedKeys() == DerivedKeys.RequireDerivedKeys) {
          properties.setDerivedKeyKeyIdentifier(
              WSSecurityTokenConstants.KEYIDENTIFIER_ENCRYPTED_KEY_SHA1_IDENTIFIER);
          properties.setSignatureKeyIdentifier(
              WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
        }
      }
    } else if (policyToken instanceof KerberosToken) {
      if (isRequestor()) {
        properties.setDerivedKeyKeyIdentifier(
            WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
      } else {
        if (wrapper.getToken().getDerivedKeys() == DerivedKeys.RequireDerivedKeys) {
          properties.setSignatureKeyIdentifier(
              WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
        } else {
          properties.setSignatureKeyIdentifier(
              WSSecurityTokenConstants.KEYIDENTIFIER_KERBEROS_SHA1_IDENTIFIER);
        }
        properties.setDerivedKeyKeyIdentifier(
            WSSecurityTokenConstants.KEYIDENTIFIER_KERBEROS_SHA1_IDENTIFIER);
      }
    } else if (policyToken instanceof IssuedToken
        || policyToken instanceof SecurityContextToken
        || policyToken instanceof SecureConversationToken
        || policyToken instanceof SpnegoContextToken) {
      if (!isRequestor()) {
        properties.setIncludeSignatureToken(false);
      } else {
        properties.setIncludeSignatureToken(true);
      }
      properties.setDerivedKeyKeyIdentifier(
          WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
    }

    if (sigToken.getDerivedKeys() == DerivedKeys.RequireDerivedKeys) {
      properties.setSignatureAlgorithm(sbinding.getAlgorithmSuite().getSymmetricSignature());
    }
  }
  private void doEncryption(
      AbstractTokenWrapper recToken, List<SecurePart> encrParts, boolean externalRef)
      throws SOAPException {
    // Do encryption
    if (recToken != null && recToken.getToken() != null) {
      AbstractToken encrToken = recToken.getToken();
      AlgorithmSuite algorithmSuite = sbinding.getAlgorithmSuite();

      // Action
      WSSSecurityProperties properties = getProperties();
      WSSConstants.Action actionToPerform = WSSConstants.ENCRYPT;
      if (recToken.getToken().getDerivedKeys() == DerivedKeys.RequireDerivedKeys) {
        actionToPerform = WSSConstants.ENCRYPT_WITH_DERIVED_KEY;
        if (MessageUtils.isRequestor(message) && recToken.getToken() instanceof X509Token) {
          properties.setDerivedKeyTokenReference(
              WSSConstants.DerivedKeyTokenReference.EncryptedKey);
        } else {
          properties.setDerivedKeyTokenReference(
              WSSConstants.DerivedKeyTokenReference.DirectReference);
        }
        AlgorithmSuiteType algSuiteType = sbinding.getAlgorithmSuite().getAlgorithmSuiteType();
        properties.setDerivedEncryptionKeyLength(algSuiteType.getEncryptionDerivedKeyLength() / 8);
      }

      if (recToken.getVersion() == SPConstants.SPVersion.SP12) {
        properties.setUse200512Namespace(true);
      }

      properties.getEncryptionSecureParts().addAll(encrParts);
      properties.addAction(actionToPerform);

      if (isRequestor()) {
        properties.setEncryptionKeyIdentifier(getKeyIdentifierType(encrToken));
        properties.setDerivedKeyKeyIdentifier(
            WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
      } else if (recToken.getToken() instanceof KerberosToken && !isRequestor()) {
        properties.setEncryptionKeyIdentifier(
            WSSecurityTokenConstants.KEYIDENTIFIER_KERBEROS_SHA1_IDENTIFIER);
        properties.setDerivedKeyKeyIdentifier(
            WSSecurityTokenConstants.KEYIDENTIFIER_KERBEROS_SHA1_IDENTIFIER);
        if (recToken.getToken().getDerivedKeys() == DerivedKeys.RequireDerivedKeys) {
          properties.setEncryptionKeyIdentifier(
              WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
        }
      } else if ((recToken.getToken() instanceof IssuedToken
              || recToken.getToken() instanceof SecureConversationToken
              || recToken.getToken() instanceof SpnegoContextToken)
          && !isRequestor()) {
        properties.setEncryptionKeyIdentifier(
            WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
      } else {
        properties.setEncryptionKeyIdentifier(
            WSSecurityTokenConstants.KEYIDENTIFIER_ENCRYPTED_KEY_SHA1_IDENTIFIER);
        if (recToken.getToken().getDerivedKeys() == DerivedKeys.RequireDerivedKeys) {
          properties.setDerivedKeyKeyIdentifier(
              WSSecurityTokenConstants.KEYIDENTIFIER_ENCRYPTED_KEY_SHA1_IDENTIFIER);
          properties.setEncryptionKeyIdentifier(
              WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE);
          properties.setEncryptSymmetricEncryptionKey(false);
        }
      }

      // Find out do we also need to include the token as per the Inclusion requirement
      WSSecurityTokenConstants.KeyIdentifier keyIdentifier =
          properties.getEncryptionKeyIdentifier();
      if (encrToken instanceof X509Token
          && isTokenRequired(encrToken.getIncludeTokenType())
          && (WSSecurityTokenConstants.KeyIdentifier_IssuerSerial.equals(keyIdentifier)
              || WSSecurityTokenConstants.KEYIDENTIFIER_THUMBPRINT_IDENTIFIER.equals(keyIdentifier)
              || WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE.equals(
                  keyIdentifier))) {
        properties.setIncludeEncryptionToken(true);
      } else {
        properties.setIncludeEncryptionToken(false);
      }

      properties.setEncryptionKeyTransportAlgorithm(
          algorithmSuite.getAlgorithmSuiteType().getAsymmetricKeyWrap());
      properties.setEncryptionSymAlgorithm(algorithmSuite.getAlgorithmSuiteType().getEncryption());

      String encUser =
          (String)
              SecurityUtils.getSecurityPropertyValue(SecurityConstants.ENCRYPT_USERNAME, message);
      if (encUser == null) {
        encUser =
            (String) SecurityUtils.getSecurityPropertyValue(SecurityConstants.USERNAME, message);
      }
      if (encUser != null && properties.getEncryptionUser() == null) {
        properties.setEncryptionUser(encUser);
      }
      if (ConfigurationConstants.USE_REQ_SIG_CERT.equals(encUser)) {
        properties.setUseReqSigCertForEncryption(true);
      }

      if (encrToken instanceof KerberosToken
          || encrToken instanceof IssuedToken
          || encrToken instanceof SpnegoContextToken
          || encrToken instanceof SecurityContextToken
          || encrToken instanceof SecureConversationToken) {
        properties.setEncryptSymmetricEncryptionKey(false);
      }
    }
  }