protected void setupAttachmentEncryptionStreams()

in ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/EncryptOutputProcessor.java [194:299]


    protected void setupAttachmentEncryptionStreams(OutputProcessorChain outputProcessorChain) throws XMLSecurityException {

        SecurePart attachmentSecurePart = null;

        Map<Object, SecurePart> dynamicSecureParts =
            outputProcessorChain.getSecurityContext().getAsMap(XMLSecurityConstants.ENCRYPTION_PARTS);
        Iterator<Map.Entry<Object, SecurePart>> securePartsMapIterator = dynamicSecureParts.entrySet().iterator();
        String externalId = "";
        while (securePartsMapIterator.hasNext()) {
            Map.Entry<Object, SecurePart> securePartEntry = securePartsMapIterator.next();
            final SecurePart securePart = securePartEntry.getValue();
            final String externalReference = securePart.getExternalReference();
            if (externalReference != null && externalReference.startsWith("cid:")) {
                attachmentSecurePart = securePart;
                externalId = AttachmentUtils.getAttachmentId(externalReference);
                break;
            }
        }
        if (attachmentSecurePart == null) {
            return;
        }

        CallbackHandler attachmentCallbackHandler =
                ((WSSSecurityProperties) getSecurityProperties()).getAttachmentCallbackHandler();
        if (attachmentCallbackHandler == null) {
            throw new WSSecurityException(
                    WSSecurityException.ErrorCode.FAILURE,
                    "empty", new Object[] {"no attachment callbackhandler supplied"}
            );
        }

        AttachmentRequestCallback attachmentRequestCallback = new AttachmentRequestCallback();
        attachmentRequestCallback.setAttachmentId(externalId);
        try {
            attachmentCallbackHandler.handle(new Callback[]{attachmentRequestCallback});
        } catch (Exception e) {
            throw new WSSecurityException(
                    WSSecurityException.ErrorCode.FAILURE, e
            );
        }

        List<Attachment> attachments = attachmentRequestCallback.getAttachments();
        if (attachments != null) {
            for (int i = 0; i < attachments.size(); i++) {
                final Attachment attachment = attachments.get(i);
                final String attachmentId = attachment.getId();

                String tokenId = outputProcessorChain.getSecurityContext().get(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTION);
                SecurityTokenProvider<OutboundSecurityToken> securityTokenProvider =
                        outputProcessorChain.getSecurityContext().getSecurityTokenProvider(tokenId);
                OutboundSecurityToken securityToken = securityTokenProvider.getSecurityToken();
                EncryptionPartDef encryptionPartDef = new EncryptionPartDef();
                encryptionPartDef.setSecurePart(attachmentSecurePart);
                encryptionPartDef.setModifier(attachmentSecurePart.getModifier());
                encryptionPartDef.setCipherReferenceId(attachment.getId());
                encryptionPartDef.setMimeType(attachment.getMimeType());
                encryptionPartDef.setEncRefId(IDGenerator.generateID(null));
                encryptionPartDef.setKeyId(securityTokenProvider.getId());
                encryptionPartDef.setSymmetricKey(securityToken.getSecretKey(getSecurityProperties().getEncryptionSymAlgorithm()));
                outputProcessorChain.getSecurityContext().putAsList(EncryptionPartDef.class, encryptionPartDef);

                final Attachment resultAttachment = new Attachment();
                resultAttachment.setId(attachmentId);
                resultAttachment.setMimeType("application/octet-stream");

                String encryptionSymAlgorithm = getSecurityProperties().getEncryptionSymAlgorithm();
                String jceAlgorithm = JCEAlgorithmMapper.translateURItoJCEID(encryptionSymAlgorithm);
                if (jceAlgorithm == null) {
                    throw new XMLSecurityException("algorithms.NoSuchMap", new Object[] {encryptionSymAlgorithm});
                }
                //initialize the cipher
                Cipher cipher = null;
                try {
                    cipher = Cipher.getInstance(jceAlgorithm);

                    int ivLen = JCEMapper.getIVLengthFromURI(encryptionSymAlgorithm) / 8;
                    byte[] iv = XMLSecurityConstants.generateBytes(ivLen);
                    AlgorithmParameterSpec paramSpec =
                        XMLCipherUtil.constructBlockCipherParameters(encryptionSymAlgorithm, iv);
                    cipher.init(Cipher.ENCRYPT_MODE, encryptionPartDef.getSymmetricKey(), paramSpec);

                } catch (Exception e) {
                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
                }

                final Map<String, String> headers = new HashMap<>();
                headers.putAll(attachment.getHeaders());
                resultAttachment.setSourceStream(
                        AttachmentUtils.setupAttachmentEncryptionStream(
                                cipher,
                                SecurePart.Modifier.Element == encryptionPartDef.getModifier(),
                                attachment, headers
                        ));
                resultAttachment.addHeaders(headers);

                final AttachmentResultCallback attachmentResultCallback = new AttachmentResultCallback();
                attachmentResultCallback.setAttachmentId(attachmentId);
                attachmentResultCallback.setAttachment(resultAttachment);
                try {
                    attachmentCallbackHandler.handle(new Callback[]{attachmentResultCallback});
                } catch (Exception e) {
                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
                }
            }
        }
    }