View Javadoc
1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.wss4j.stax.impl.processor.input;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.lang.reflect.Constructor;
24  import java.lang.reflect.InvocationTargetException;
25  import java.security.Key;
26  import java.util.ArrayList;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.Map;
30  
31  import javax.crypto.Cipher;
32  import javax.security.auth.callback.Callback;
33  import javax.security.auth.callback.CallbackHandler;
34  import jakarta.xml.bind.JAXBElement;
35  import javax.xml.namespace.QName;
36  import javax.xml.stream.XMLStreamException;
37  
38  import org.apache.wss4j.binding.wss10.SecurityTokenReferenceType;
39  import org.apache.wss4j.common.bsp.BSPRule;
40  import org.apache.wss4j.common.ext.Attachment;
41  import org.apache.wss4j.common.ext.AttachmentRequestCallback;
42  import org.apache.wss4j.common.ext.AttachmentResultCallback;
43  import org.apache.wss4j.common.ext.WSSecurityException;
44  import org.apache.wss4j.common.util.AttachmentUtils;
45  import org.apache.wss4j.stax.ext.WSInboundSecurityContext;
46  import org.apache.wss4j.stax.ext.WSSConstants;
47  import org.apache.wss4j.stax.ext.WSSSecurityProperties;
48  import org.apache.wss4j.stax.securityEvent.EncryptedPartSecurityEvent;
49  import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
50  import org.apache.wss4j.stax.utils.LimitingInputStream;
51  import org.apache.wss4j.stax.utils.WSSUtils;
52  import org.apache.xml.security.binding.xmldsig.KeyInfoType;
53  import org.apache.xml.security.binding.xmldsig.TransformType;
54  import org.apache.xml.security.binding.xmldsig.TransformsType;
55  import org.apache.xml.security.binding.xmlenc.CipherReferenceType;
56  import org.apache.xml.security.binding.xmlenc.EncryptedDataType;
57  import org.apache.xml.security.binding.xmlenc.ReferenceList;
58  import org.apache.xml.security.binding.xmlenc.ReferenceType;
59  import org.apache.xml.security.exceptions.XMLSecurityException;
60  import org.apache.xml.security.stax.config.ConfigurationProperties;
61  import org.apache.xml.security.stax.config.TransformerAlgorithmMapper;
62  import org.apache.xml.security.stax.ext.DocumentContext;
63  import org.apache.xml.security.stax.ext.InboundSecurityContext;
64  import org.apache.xml.security.stax.ext.InputProcessorChain;
65  import org.apache.xml.security.stax.ext.SecurePart;
66  import org.apache.xml.security.stax.ext.XMLSecurityConstants;
67  import org.apache.xml.security.stax.ext.XMLSecurityProperties;
68  import org.apache.xml.security.stax.ext.XMLSecurityUtils;
69  import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
70  import org.apache.xml.security.stax.impl.processor.input.AbstractDecryptInputProcessor;
71  import org.apache.xml.security.stax.securityEvent.ContentEncryptedElementSecurityEvent;
72  import org.apache.xml.security.stax.securityEvent.EncryptedElementSecurityEvent;
73  import org.apache.xml.security.stax.securityEvent.TokenSecurityEvent;
74  import org.apache.xml.security.stax.securityToken.InboundSecurityToken;
75  import org.apache.xml.security.stax.securityToken.SecurityToken;
76  
77  /**
78   * Processor for decryption of EncryptedData XML structures
79   */
80  public class DecryptInputProcessor extends AbstractDecryptInputProcessor {
81  
82      private static final transient org.slf4j.Logger LOG =
83          org.slf4j.LoggerFactory.getLogger(DecryptInputProcessor.class);
84  
85      private static final Long MAX_ALLOWED_DECOMPRESSED_BYTES =
86              Long.valueOf(ConfigurationProperties.getProperty("MaximumAllowedDecompressedBytes"));
87  
88      private List<DeferredAttachment> attachmentReferences = new ArrayList<>();
89  
90      public DecryptInputProcessor(KeyInfoType keyInfoType, ReferenceList referenceList,
91                                   WSSSecurityProperties securityProperties, WSInboundSecurityContext securityContext)
92              throws XMLSecurityException {
93  
94          super(keyInfoType, referenceList, securityProperties);
95          checkBSPCompliance(keyInfoType, referenceList, securityContext, BSPRule.R3006);
96      }
97  
98      private void checkBSPCompliance(KeyInfoType keyInfoType, ReferenceList referenceList, WSInboundSecurityContext securityContext,
99                                      BSPRule bspRule) throws WSSecurityException {
100         if (keyInfoType != null) {
101             if (keyInfoType.getContent().size() != 1) {
102                 securityContext.handleBSPRule(BSPRule.R5424);
103             }
104             SecurityTokenReferenceType securityTokenReferenceType = XMLSecurityUtils.getQNameType(keyInfoType.getContent(),
105                     WSSConstants.TAG_WSSE_SECURITY_TOKEN_REFERENCE);
106             if (securityTokenReferenceType == null) {
107                 securityContext.handleBSPRule(BSPRule.R5426);
108             }
109         }
110 
111         if (referenceList != null) {
112             List<JAXBElement<ReferenceType>> references = referenceList.getDataReferenceOrKeyReference();
113             Iterator<JAXBElement<ReferenceType>> referenceTypeIterator = references.iterator();
114             while (referenceTypeIterator.hasNext()) {
115                 ReferenceType referenceType = referenceTypeIterator.next().getValue();
116                 if (!referenceType.getURI().startsWith("#")) {
117                     securityContext.handleBSPRule(bspRule);
118                 }
119             }
120         }
121     }
122 
123     @Override
124     protected InputStream applyTransforms(ReferenceType referenceType, InputStream inputStream) throws XMLSecurityException {
125         if (referenceType != null) {
126             TransformsType transformsType =
127                     XMLSecurityUtils.getQNameType(referenceType.getAny(), XMLSecurityConstants.TAG_dsig_Transforms);
128             if (transformsType != null) {
129                 List<TransformType> transformTypes = transformsType.getTransform();
130                 //to do don't forget to limit the count of transformations if more transformations will be supported!
131                 if (transformTypes.size() > 1) {
132                     throw new XMLSecurityException("stax.encryption.Transforms.NotYetImplemented");
133                 }
134                 TransformType transformType = transformTypes.get(0);
135                 @SuppressWarnings("unchecked")
136                 Class<InputStream> transformerClass =
137                         (Class<InputStream>) TransformerAlgorithmMapper.getTransformerClass(
138                                 transformType.getAlgorithm(), XMLSecurityConstants.DIRECTION.IN);
139                 try {
140                     Constructor<InputStream> constructor = transformerClass.getConstructor(InputStream.class);
141                     inputStream = new LimitingInputStream(
142                             constructor.newInstance(inputStream), MAX_ALLOWED_DECOMPRESSED_BYTES);
143                 } catch (InvocationTargetException | NoSuchMethodException
144                     | InstantiationException | IllegalAccessException e) {
145                     throw new XMLSecurityException(e);
146                 }
147             }
148         }
149         return inputStream;
150     }
151 
152     @Override
153     protected void handleEncryptedContent(
154             InputProcessorChain inputProcessorChain, XMLSecStartElement parentStartXMLEvent,
155             InboundSecurityToken inboundSecurityToken, EncryptedDataType encryptedDataType) throws XMLSecurityException {
156 
157         final DocumentContext documentContext = inputProcessorChain.getDocumentContext();
158         List<QName> elementPath = parentStartXMLEvent.getElementPath();
159         if (elementPath.size() == 2 && WSSUtils.isInSOAPBody(elementPath)) {
160             //soap:body content encryption counts as EncryptedPart
161             EncryptedPartSecurityEvent encryptedPartSecurityEvent =
162                     new EncryptedPartSecurityEvent(inboundSecurityToken, true, documentContext.getProtectionOrder());
163             encryptedPartSecurityEvent.setElementPath(elementPath);
164             encryptedPartSecurityEvent.setXmlSecEvent(parentStartXMLEvent);
165             encryptedPartSecurityEvent.setCorrelationID(encryptedDataType.getId());
166             inputProcessorChain.getSecurityContext().registerSecurityEvent(encryptedPartSecurityEvent);
167         } else {
168             ContentEncryptedElementSecurityEvent contentEncryptedElementSecurityEvent =
169                     new ContentEncryptedElementSecurityEvent(inboundSecurityToken, true, documentContext.getProtectionOrder());
170             contentEncryptedElementSecurityEvent.setElementPath(elementPath);
171             contentEncryptedElementSecurityEvent.setXmlSecEvent(parentStartXMLEvent);
172             contentEncryptedElementSecurityEvent.setCorrelationID(encryptedDataType.getId());
173             inputProcessorChain.getSecurityContext().registerSecurityEvent(contentEncryptedElementSecurityEvent);
174         }
175     }
176 
177     @Override
178     protected void handleCipherReference(InputProcessorChain inputProcessorChain, EncryptedDataType encryptedDataType,
179                                          Cipher cipher, InboundSecurityToken inboundSecurityToken) throws XMLSecurityException {
180 
181         String typeStr = encryptedDataType.getType();
182         if (typeStr != null
183             && (WSSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_CONTENT_ONLY.equals(typeStr)
184                 || WSSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(typeStr))) {
185 
186             CipherReferenceType cipherReferenceType = encryptedDataType.getCipherData().getCipherReference();
187             if (cipherReferenceType == null) {
188                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
189             }
190 
191             final String uri = cipherReferenceType.getURI();
192             if (uri == null || uri.length() < 5) {
193                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
194             }
195             if (!uri.startsWith("cid:")) {
196                 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
197             }
198 
199             //we need to do a deferred processing of the attachments for two reasons:
200             //1.) if an attachment is encrypted and signed the order is preserved
201             //2.) the attachments are processed after the SOAP-Document which allows us to stream everything
202             attachmentReferences.add(
203                     new DeferredAttachment(encryptedDataType, cipher, inboundSecurityToken) //NOPMD
204             );
205         }
206     }
207 
208     @Override
209     protected InputStream handleXOPInclude(InputProcessorChain inputProcessorChain, EncryptedDataType encryptedDataType, String href,
210                                            Cipher cipher, InboundSecurityToken inboundSecurityToken) throws XMLSecurityException {
211         if (href == null || href.length() < 5) {
212             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
213         }
214         if (!href.startsWith("cid:")) {
215             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
216         }
217 
218         final String attachmentId = AttachmentUtils.getAttachmentId(href);
219 
220         CallbackHandler attachmentCallbackHandler =
221             ((WSSSecurityProperties) getSecurityProperties()).getAttachmentCallbackHandler();
222         if (attachmentCallbackHandler == null) {
223             throw new WSSecurityException(
224                 WSSecurityException.ErrorCode.INVALID_SECURITY,
225                 "empty", new Object[] {"no attachment callbackhandler supplied"}
226             );
227         }
228 
229         AttachmentRequestCallback attachmentRequestCallback = new AttachmentRequestCallback();
230         attachmentRequestCallback.setAttachmentId(attachmentId);
231         try {
232             attachmentCallbackHandler.handle(new Callback[]{attachmentRequestCallback});
233         } catch (Exception e) {
234             throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e);
235         }
236         List<Attachment> attachments = attachmentRequestCallback.getAttachments();
237         if (attachments == null || attachments.isEmpty() || !attachmentId.equals(attachments.get(0).getId())) {
238             throw new WSSecurityException(
239                 WSSecurityException.ErrorCode.INVALID_SECURITY,
240                 "empty", new Object[] {"Attachment not found"}
241             );
242         }
243 
244         final Attachment attachment = attachments.get(0);
245 
246         final String encAlgo = encryptedDataType.getEncryptionMethod().getAlgorithm();
247         final Key symmetricKey =
248             inboundSecurityToken.getSecretKey(encAlgo, XMLSecurityConstants.Enc, encryptedDataType.getId());
249 
250         return
251             AttachmentUtils.setupAttachmentDecryptionStream(encAlgo, cipher, symmetricKey, attachment.getSourceStream());
252     }
253 
254     @Override
255     protected AbstractDecryptedEventReaderInputProcessor newDecryptedEventReaderInputProcessor(
256             boolean encryptedHeader, XMLSecStartElement xmlSecStartElement, EncryptedDataType encryptedDataType,
257             InboundSecurityToken inboundSecurityToken, InboundSecurityContext inboundSecurityContext) throws XMLSecurityException {
258 
259         // Check encryption algorithm against the required algorithm, if defined
260         String encryptionAlgorithm = encryptedDataType.getEncryptionMethod().getAlgorithm();
261         if (this.getSecurityProperties().getEncryptionSymAlgorithm() != null
262             && !this.getSecurityProperties().getEncryptionSymAlgorithm().equals(encryptionAlgorithm)) {
263             LOG.warn(
264                 "The Key encryption method does not match the requirement"
265             );
266             throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
267         }
268 
269         if (!WSSConstants.NS_XENC_TRIPLE_DES.equals(encryptionAlgorithm)
270                 && !WSSConstants.NS_XENC_AES128.equals(encryptionAlgorithm)
271                 && !WSSConstants.NS_XENC11_AES128_GCM.equals(encryptionAlgorithm)
272                 && !WSSConstants.NS_XENC_AES256.equals(encryptionAlgorithm)
273                 && !WSSConstants.NS_XENC11_AES256_GCM.equals(encryptionAlgorithm)) {
274             ((WSInboundSecurityContext) inboundSecurityContext).handleBSPRule(BSPRule.R5620);
275         }
276 
277         return new DecryptedEventReaderInputProcessor(getSecurityProperties(),
278                 SecurePart.Modifier.getModifier(encryptedDataType.getType()),
279                 encryptedHeader, xmlSecStartElement, encryptedDataType, this, inboundSecurityToken);
280     }
281 
282     @Override
283     protected void handleSecurityToken(InboundSecurityToken inboundSecurityToken, InboundSecurityContext inboundSecurityContext,
284                                        EncryptedDataType encryptedDataType) throws XMLSecurityException {
285         inboundSecurityToken.addTokenUsage(WSSecurityTokenConstants.TokenUsage_Encryption);
286         TokenSecurityEvent<? extends SecurityToken> tokenSecurityEvent =
287             WSSUtils.createTokenSecurityEvent(inboundSecurityToken, encryptedDataType.getId());
288         inboundSecurityContext.registerSecurityEvent(tokenSecurityEvent);
289     }
290 
291     @Override
292     public void doFinal(InputProcessorChain inputProcessorChain) throws XMLStreamException, XMLSecurityException {
293         //find already processed references by the EncryptedDataHandler
294         List<String> encryptedDataRefs = inputProcessorChain.getSecurityContext().getAsList(WSSConstants.PROP_ENCRYPTED_DATA_REFS);
295         if (encryptedDataRefs != null && !encryptedDataRefs.isEmpty()) {
296             Map<String, ReferenceType> references = getReferences();
297             List<ReferenceType> processedReferences = getProcessedReferences();
298             if (references != null) {
299                 Iterator<Map.Entry<String, ReferenceType>> iterator = references.entrySet().iterator();
300                 while (iterator.hasNext()) {
301                     Map.Entry<String, ReferenceType> next = iterator.next();
302                     final ReferenceType referenceType = next.getValue();
303                     String uri = WSSUtils.dropReferenceMarker(referenceType.getURI());
304 
305                     Iterator<String> encryptedDataIterator = encryptedDataRefs.iterator();
306                     while (encryptedDataIterator.hasNext()) {
307                         String s = encryptedDataIterator.next();
308                         if (s.equals(uri)) {
309                             processedReferences.add(referenceType);
310                         }
311                     }
312                 }
313             }
314         }
315         super.doFinal(inputProcessorChain);
316 
317         //now process the (deferred-) attachments:
318         for (int i = 0; i < attachmentReferences.size(); i++) {
319             DeferredAttachment deferredAttachment = attachmentReferences.get(i);
320 
321             final EncryptedDataType encryptedDataType = deferredAttachment.getEncryptedDataType();
322             final InboundSecurityToken inboundSecurityToken = deferredAttachment.getInboundSecurityToken();
323             final Cipher cipher = deferredAttachment.getCipher();
324             final String uri = encryptedDataType.getCipherData().getCipherReference().getURI();
325             final String attachmentId = AttachmentUtils.getAttachmentId(uri);
326 
327             CallbackHandler attachmentCallbackHandler =
328                 ((WSSSecurityProperties) getSecurityProperties()).getAttachmentCallbackHandler();
329             if (attachmentCallbackHandler == null) {
330                 throw new WSSecurityException(
331                     WSSecurityException.ErrorCode.INVALID_SECURITY,
332                     "empty", new Object[] {"no attachment callbackhandler supplied"}
333                 );
334             }
335 
336             AttachmentRequestCallback attachmentRequestCallback = new AttachmentRequestCallback();
337             attachmentRequestCallback.setAttachmentId(attachmentId);
338             try {
339                 attachmentCallbackHandler.handle(new Callback[]{attachmentRequestCallback});
340             } catch (Exception e) {
341                 throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e);
342             }
343             List<Attachment> attachments = attachmentRequestCallback.getAttachments();
344             if (attachments == null || attachments.isEmpty() || !attachmentId.equals(attachments.get(0).getId())) {
345                 throw new WSSecurityException(
346                     WSSecurityException.ErrorCode.INVALID_SECURITY,
347                     "empty", new Object[] {"Attachment not found"}
348                 );
349             }
350 
351             final Attachment attachment = attachments.get(0);
352 
353             final String encAlgo = encryptedDataType.getEncryptionMethod().getAlgorithm();
354             final Key symmetricKey =
355                 inboundSecurityToken.getSecretKey(encAlgo, XMLSecurityConstants.Enc, encryptedDataType.getId());
356 
357             InputStream attachmentInputStream = //NOPMD
358                 AttachmentUtils.setupAttachmentDecryptionStream(encAlgo, cipher, symmetricKey, attachment.getSourceStream());
359 
360             Attachment resultAttachment = new Attachment();
361             resultAttachment.setId(attachment.getId());
362             resultAttachment.setMimeType(encryptedDataType.getMimeType());
363             resultAttachment.setSourceStream(attachmentInputStream);
364             resultAttachment.addHeaders(attachment.getHeaders());
365 
366             if (WSSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(encryptedDataType.getType())) {
367                 try {
368                     AttachmentUtils.readAndReplaceEncryptedAttachmentHeaders(
369                         resultAttachment.getHeaders(), attachmentInputStream);
370                 } catch (IOException e) {
371                     throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e);
372                 }
373             }
374 
375             AttachmentResultCallback attachmentResultCallback = new AttachmentResultCallback();
376             attachmentResultCallback.setAttachment(resultAttachment);
377             attachmentResultCallback.setAttachmentId(resultAttachment.getId());
378             try {
379                 attachmentCallbackHandler.handle(new Callback[]{attachmentResultCallback});
380             } catch (Exception e) {
381                 throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e);
382             }
383 
384             // Create a security event for this encrypted Attachment
385             final DocumentContext documentContext = inputProcessorChain.getDocumentContext();
386             EncryptedPartSecurityEvent encryptedPartSecurityEvent =
387                 new EncryptedPartSecurityEvent(inboundSecurityToken, true, documentContext.getProtectionOrder());
388             encryptedPartSecurityEvent.setAttachment(true);
389             encryptedPartSecurityEvent.setCorrelationID(encryptedDataType.getId());
390             inputProcessorChain.getSecurityContext().registerSecurityEvent(encryptedPartSecurityEvent);
391         }
392     }
393 
394     private static final class DeferredAttachment {
395 
396         private EncryptedDataType encryptedDataType;
397         private Cipher cipher;
398         private InboundSecurityToken inboundSecurityToken;
399 
400         private DeferredAttachment(
401             EncryptedDataType encryptedDataType, Cipher cipher,
402             InboundSecurityToken inboundSecurityToken) {
403 
404             this.encryptedDataType = encryptedDataType;
405             this.cipher = cipher;
406             this.inboundSecurityToken = inboundSecurityToken;
407         }
408 
409         private EncryptedDataType getEncryptedDataType() {
410             return encryptedDataType;
411         }
412 
413         private Cipher getCipher() {
414             return cipher;
415         }
416 
417         private InboundSecurityToken getInboundSecurityToken() {
418             return inboundSecurityToken;
419         }
420     }
421 
422     /**
423      * The DecryptedEventReaderInputProcessor reads the decrypted stream with a StAX reader and
424      * forwards the generated XMLEvents
425      */
426     class DecryptedEventReaderInputProcessor extends AbstractDecryptedEventReaderInputProcessor {
427 
428         DecryptedEventReaderInputProcessor(
429                 XMLSecurityProperties securityProperties, SecurePart.Modifier encryptionModifier,
430                 boolean encryptedHeader, XMLSecStartElement xmlSecStartElement,
431                 EncryptedDataType encryptedDataType,
432                 DecryptInputProcessor decryptInputProcessor,
433                 InboundSecurityToken inboundSecurityToken
434         ) {
435             super(securityProperties, encryptionModifier, encryptedHeader, xmlSecStartElement,
436                     encryptedDataType, decryptInputProcessor, inboundSecurityToken);
437         }
438 
439         @Override
440         protected void handleEncryptedElement(
441                 InputProcessorChain inputProcessorChain, XMLSecStartElement xmlSecStartElement,
442                 InboundSecurityToken inboundSecurityToken, EncryptedDataType encryptedDataType) throws XMLSecurityException {
443 
444             //fire a SecurityEvent:
445             final DocumentContext documentContext = inputProcessorChain.getDocumentContext();
446             List<QName> elementPath = xmlSecStartElement.getElementPath();
447             if (elementPath.size() == 3 && WSSUtils.isInSOAPHeader(elementPath)) {
448                 EncryptedPartSecurityEvent encryptedPartSecurityEvent =
449                         new EncryptedPartSecurityEvent(inboundSecurityToken, true, documentContext.getProtectionOrder());
450                 encryptedPartSecurityEvent.setElementPath(elementPath);
451                 encryptedPartSecurityEvent.setXmlSecEvent(xmlSecStartElement);
452                 encryptedPartSecurityEvent.setCorrelationID(encryptedDataType.getId());
453                 inputProcessorChain.getSecurityContext().registerSecurityEvent(encryptedPartSecurityEvent);
454             } else {
455                 EncryptedElementSecurityEvent encryptedElementSecurityEvent =
456                         new EncryptedElementSecurityEvent(inboundSecurityToken, true, documentContext.getProtectionOrder());
457                 encryptedElementSecurityEvent.setElementPath(elementPath);
458                 encryptedElementSecurityEvent.setXmlSecEvent(xmlSecStartElement);
459                 encryptedElementSecurityEvent.setCorrelationID(encryptedDataType.getId());
460                 inputProcessorChain.getSecurityContext().registerSecurityEvent(encryptedElementSecurityEvent);
461             }
462         }
463     }
464 }