private void setupEncryptionKey()

in ws-security-stax/src/main/java/org/apache/wss4j/stax/setup/OutboundWSSec.java [333:446]


    private void setupEncryptionKey(
        OutputProcessorChainImpl outputProcessorChain,
        WSSSecurityProperties securityProperties
    ) throws XMLSecurityException {
        final String symmetricEncryptionAlgorithm = securityProperties.getEncryptionSymAlgorithm();

        // First check to see if a Symmetric key is available
        GenericOutboundSecurityToken securityToken =
            getOutboundSecurityToken(outputProcessorChain, WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION);
        if (securityToken == null || securityToken.getSecretKey(symmetricEncryptionAlgorithm) == null) {
            //prepare the symmetric session key for all encryption parts
            String keyAlgorithm = JCEAlgorithmMapper.getJCEKeyAlgorithmFromURI(securityProperties.getEncryptionSymAlgorithm());
            KeyGenerator keyGen;
            try {
                keyGen = KeyGenerator.getInstance(keyAlgorithm);
            } catch (NoSuchAlgorithmException e) {
                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
            }
            //the sun JCE provider expects the real key size for 3DES (112 or 168 bit)
            //whereas bouncy castle expects the block size of 128 or 192 bits
            if (keyAlgorithm.contains("AES")) {
                int keyLength = JCEAlgorithmMapper.getKeyLengthFromURI(securityProperties.getEncryptionSymAlgorithm());
                keyGen.init(keyLength);
            }

            final Key symmetricKey = keyGen.generateKey();
            final String symmId = IDGenerator.generateID(null);

            final GenericOutboundSecurityToken symmetricSecurityToken =
                new GenericOutboundSecurityToken(symmId, WSSecurityTokenConstants.EncryptedKeyToken, symmetricKey);
            securityToken = symmetricSecurityToken;
            final SecurityTokenProvider<OutboundSecurityToken> securityTokenProvider =
                new SecurityTokenProvider<OutboundSecurityToken>() {

                @Override
                public OutboundSecurityToken getSecurityToken() throws XMLSecurityException {
                    return symmetricSecurityToken;
                }

                @Override
                public String getId() {
                    return symmId;
                }
            };

            outputProcessorChain.getSecurityContext().registerSecurityTokenProvider(symmId, securityTokenProvider);
            outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION, symmId);
        }

        if (!securityProperties.isEncryptSymmetricEncryptionKey()) {
            // No EncryptedKey Token required here, so return
            return;
        }

        // Set up a security token with the certs required to encrypt the symmetric key
        X509Certificate[] x509Certificates = null;
        PublicKey publicKey = null;
        if (securityProperties.isUseReqSigCertForEncryption()) {
            X509Certificate x509Certificate = getReqSigCert(outputProcessorChain.getSecurityContext());
            if (x509Certificate == null) {
                publicKey = getReqSigPublicKey(outputProcessorChain.getSecurityContext());
                if (publicKey == null) {
                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, "noCert");
                }
            } else {
                x509Certificates = new X509Certificate[1];
                x509Certificates[0] = x509Certificate;
            }
        } else if (securityProperties.getEncryptionUseThisCertificate() != null) {
            x509Certificates = new X509Certificate[1];
            x509Certificates[0] = securityProperties.getEncryptionUseThisCertificate();
        } else {
            CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
            cryptoType.setAlias(securityProperties.getEncryptionUser());
            Crypto crypto = securityProperties.getEncryptionCrypto();
            x509Certificates = crypto.getX509Certificates(cryptoType);
            if (x509Certificates == null || x509Certificates.length == 0) {
                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, "noUserCertsFound",
                                              new Object[] {securityProperties.getEncryptionUser(), "encryption"});
            }
        }

        // Check for Revocation
        if (securityProperties.isEnableRevocation() && x509Certificates != null) {
            Crypto crypto = securityProperties.getEncryptionCrypto();
            crypto.verifyTrust(x509Certificates, true, null, null);
        }

        // Create a new outbound EncryptedKey token for the cert
        final String id = IDGenerator.generateID(null);
        final GenericOutboundSecurityToken encryptedKeyToken =
            new GenericOutboundSecurityToken(id, WSSecurityTokenConstants.X509V3Token, publicKey, x509Certificates);

        encryptedKeyToken.addWrappedToken(securityToken);
        securityToken.setKeyWrappingToken(encryptedKeyToken);

        // binarySecurityToken.setSha1Identifier(reference);
        final SecurityTokenProvider<OutboundSecurityToken> encryptedKeyTokenProvider =
            new SecurityTokenProvider<OutboundSecurityToken>() {

            @Override
            public OutboundSecurityToken getSecurityToken() throws WSSecurityException {
                return encryptedKeyToken;
            }

            @Override
            public String getId() {
                return id;
            }
        };

        outputProcessorChain.getSecurityContext().registerSecurityTokenProvider(id, encryptedKeyTokenProvider);
        outputProcessorChain.getSecurityContext().put(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTED_KEY, id);
    }