001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.model.dataformat; 018 019import java.util.HashMap; 020import java.util.Map; 021import javax.xml.bind.annotation.XmlAccessType; 022import javax.xml.bind.annotation.XmlAccessorType; 023import javax.xml.bind.annotation.XmlAttribute; 024import javax.xml.bind.annotation.XmlRootElement; 025import javax.xml.bind.annotation.XmlTransient; 026 027import org.apache.camel.CamelContext; 028import org.apache.camel.model.DataFormatDefinition; 029import org.apache.camel.spi.DataFormat; 030import org.apache.camel.spi.Metadata; 031import org.apache.camel.spi.NamespaceAware; 032import org.apache.camel.util.jsse.KeyStoreParameters; 033 034/** 035 * The XML Security data format facilitates encryption and decryption of XML payloads. 036 */ 037@Metadata(firstVersion = "2.0.0", label = "dataformat,transformation,xml,security", title = "XML Security") 038@XmlRootElement(name = "secureXML") 039@XmlAccessorType(XmlAccessType.FIELD) 040public class XMLSecurityDataFormat extends DataFormatDefinition implements NamespaceAware { 041 042 private static final String TRIPLEDES = "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"; 043 044 @XmlAttribute @Metadata(defaultValue = "TRIPLEDES") 045 private String xmlCipherAlgorithm; 046 @XmlAttribute 047 private String passPhrase; 048 @XmlAttribute 049 private String secureTag; 050 @XmlAttribute 051 private Boolean secureTagContents; 052 @XmlAttribute @Metadata(defaultValue = "RSA_OAEP") 053 private String keyCipherAlgorithm; 054 @XmlAttribute 055 private String recipientKeyAlias; 056 @XmlAttribute 057 // TODO: rename to keyOrTrustStoreParametersRef 058 private String keyOrTrustStoreParametersId; 059 @XmlAttribute 060 private String keyPassword; 061 @XmlAttribute @Metadata(defaultValue = "SHA1") 062 private String digestAlgorithm; 063 @XmlAttribute @Metadata(defaultValue = "MGF1_SHA1") 064 private String mgfAlgorithm; 065 @XmlAttribute @Metadata(defaultValue = "true") 066 private Boolean addKeyValueForEncryptedKey; 067 @XmlTransient 068 private KeyStoreParameters keyOrTrustStoreParameters; 069 @XmlTransient 070 private Map<String, String> namespaces; 071 072 public XMLSecurityDataFormat() { 073 super("secureXML"); 074 } 075 076 // all the parameter constructors is deprecated as people should use getter/setter to configure 077 078 @Deprecated 079 public XMLSecurityDataFormat(String secureTag, boolean secureTagContents) { 080 this(); 081 this.setSecureTag(secureTag); 082 this.setSecureTagContents(secureTagContents); 083 } 084 085 @Deprecated 086 public XMLSecurityDataFormat(String secureTag, Map<String, String> namespaces, boolean secureTagContents) { 087 this(); 088 this.setSecureTag(secureTag); 089 this.setSecureTagContents(secureTagContents); 090 this.setNamespaces(namespaces); 091 } 092 093 @Deprecated 094 public XMLSecurityDataFormat(String secureTag, boolean secureTagContents, String passPhrase) { 095 this(secureTag, secureTagContents); 096 this.setPassPhrase(passPhrase); 097 } 098 099 @Deprecated 100 public XMLSecurityDataFormat(String secureTag, Map<String, String> namespaces, boolean secureTagContents, 101 String passPhrase) { 102 this(secureTag, secureTagContents); 103 this.setPassPhrase(passPhrase); 104 this.setNamespaces(namespaces); 105 } 106 107 @Deprecated 108 public XMLSecurityDataFormat(String secureTag, boolean secureTagContents, String passPhrase, 109 String xmlCipherAlgorithm) { 110 this(secureTag, secureTagContents, passPhrase); 111 this.setXmlCipherAlgorithm(xmlCipherAlgorithm); 112 } 113 114 @Deprecated 115 public XMLSecurityDataFormat(String secureTag, Map<String, String> namespaces, boolean secureTagContents, String passPhrase, 116 String xmlCipherAlgorithm) { 117 this(secureTag, secureTagContents, passPhrase); 118 this.setXmlCipherAlgorithm(xmlCipherAlgorithm); 119 this.setNamespaces(namespaces); 120 } 121 122 /** 123 * @deprecated use {{@link #XMLSecurityDataFormat(String, boolean, String, String, String, String)} or 124 * {{@link #XMLSecurityDataFormat(String, boolean, String, String, String, KeyStoreParameters)} instead 125 */ 126 @Deprecated 127 public XMLSecurityDataFormat(String secureTag, boolean secureTagContents, String recipientKeyAlias, 128 String xmlCipherAlgorithm, String keyCipherAlgorithm) { 129 this(secureTag, secureTagContents); 130 this.setRecipientKeyAlias(recipientKeyAlias); 131 this.setXmlCipherAlgorithm(xmlCipherAlgorithm); 132 this.setKeyCipherAlgorithm(keyCipherAlgorithm); 133 } 134 135 @Deprecated 136 public XMLSecurityDataFormat(String secureTag, boolean secureTagContents, String recipientKeyAlias, 137 String xmlCipherAlgorithm, String keyCipherAlgorithm, String keyOrTrustStoreParametersId) { 138 this(secureTag, secureTagContents); 139 this.setRecipientKeyAlias(recipientKeyAlias); 140 this.setXmlCipherAlgorithm(xmlCipherAlgorithm); 141 this.setKeyCipherAlgorithm(keyCipherAlgorithm); 142 this.setKeyOrTrustStoreParametersId(keyOrTrustStoreParametersId); 143 } 144 145 @Deprecated 146 public XMLSecurityDataFormat(String secureTag, boolean secureTagContents, String recipientKeyAlias, 147 String xmlCipherAlgorithm, String keyCipherAlgorithm, KeyStoreParameters keyOrTrustStoreParameters) { 148 this(secureTag, secureTagContents); 149 this.setRecipientKeyAlias(recipientKeyAlias); 150 this.setXmlCipherAlgorithm(xmlCipherAlgorithm); 151 this.setKeyCipherAlgorithm(keyCipherAlgorithm); 152 this.setKeyOrTrustStoreParameters(keyOrTrustStoreParameters); 153 } 154 155 @Deprecated 156 public XMLSecurityDataFormat(String secureTag, boolean secureTagContents, String recipientKeyAlias, 157 String xmlCipherAlgorithm, String keyCipherAlgorithm, String keyOrTrustStoreParametersId, String keyPassword) { 158 this(secureTag, secureTagContents); 159 this.setRecipientKeyAlias(recipientKeyAlias); 160 this.setXmlCipherAlgorithm(xmlCipherAlgorithm); 161 this.setKeyCipherAlgorithm(keyCipherAlgorithm); 162 this.setKeyOrTrustStoreParametersId(keyOrTrustStoreParametersId); 163 this.setKeyPassword(keyPassword); 164 } 165 166 @Deprecated 167 public XMLSecurityDataFormat(String secureTag, boolean secureTagContents, String recipientKeyAlias, 168 String xmlCipherAlgorithm, String keyCipherAlgorithm, KeyStoreParameters keyOrTrustStoreParameters, String keyPassword) { 169 this(secureTag, secureTagContents); 170 this.setRecipientKeyAlias(recipientKeyAlias); 171 this.setXmlCipherAlgorithm(xmlCipherAlgorithm); 172 this.setKeyCipherAlgorithm(keyCipherAlgorithm); 173 this.setKeyOrTrustStoreParameters(keyOrTrustStoreParameters); 174 this.setKeyPassword(keyPassword); 175 } 176 177 /** 178 * @deprecated use {{@link #XMLSecurityDataFormat(String, Map, boolean, String, String, String, String)} or 179 * {{@link #XMLSecurityDataFormat(String, Map, boolean, String, String, String, KeyStoreParameters)} instead 180 */ 181 @Deprecated 182 public XMLSecurityDataFormat(String secureTag, Map<String, String> namespaces, boolean secureTagContents, String recipientKeyAlias, 183 String xmlCipherAlgorithm, String keyCipherAlgorithm) { 184 this(secureTag, secureTagContents); 185 this.setRecipientKeyAlias(recipientKeyAlias); 186 this.setXmlCipherAlgorithm(xmlCipherAlgorithm); 187 this.setKeyCipherAlgorithm(keyCipherAlgorithm); 188 this.setNamespaces(namespaces); 189 } 190 191 @Deprecated 192 public XMLSecurityDataFormat(String secureTag, Map<String, String> namespaces, boolean secureTagContents, String recipientKeyAlias, 193 String xmlCipherAlgorithm, String keyCipherAlgorithm, String keyOrTrustStoreParametersId) { 194 this(secureTag, secureTagContents); 195 this.setRecipientKeyAlias(recipientKeyAlias); 196 this.setXmlCipherAlgorithm(xmlCipherAlgorithm); 197 this.setKeyCipherAlgorithm(keyCipherAlgorithm); 198 this.setNamespaces(namespaces); 199 this.setKeyOrTrustStoreParametersId(keyOrTrustStoreParametersId); 200 } 201 202 @Deprecated 203 public XMLSecurityDataFormat(String secureTag, Map<String, String> namespaces, boolean secureTagContents, String recipientKeyAlias, 204 String xmlCipherAlgorithm, String keyCipherAlgorithm, KeyStoreParameters keyOrTrustStoreParameters) { 205 this(secureTag, secureTagContents); 206 this.setRecipientKeyAlias(recipientKeyAlias); 207 this.setXmlCipherAlgorithm(xmlCipherAlgorithm); 208 this.setKeyCipherAlgorithm(keyCipherAlgorithm); 209 this.setNamespaces(namespaces); 210 this.setKeyOrTrustStoreParameters(keyOrTrustStoreParameters); 211 } 212 213 @Deprecated 214 public XMLSecurityDataFormat(String secureTag, Map<String, String> namespaces, boolean secureTagContents, String recipientKeyAlias, 215 String xmlCipherAlgorithm, String keyCipherAlgorithm, String keyOrTrustStoreParametersId, String keyPassword) { 216 this(secureTag, secureTagContents); 217 this.setRecipientKeyAlias(recipientKeyAlias); 218 this.setXmlCipherAlgorithm(xmlCipherAlgorithm); 219 this.setKeyCipherAlgorithm(keyCipherAlgorithm); 220 this.setNamespaces(namespaces); 221 this.setKeyOrTrustStoreParametersId(keyOrTrustStoreParametersId); 222 this.setKeyPassword(keyPassword); 223 } 224 225 @Deprecated 226 public XMLSecurityDataFormat(String secureTag, Map<String, String> namespaces, boolean secureTagContents, String recipientKeyAlias, 227 String xmlCipherAlgorithm, String keyCipherAlgorithm, KeyStoreParameters keyOrTrustStoreParameters, String keyPassword) { 228 this(secureTag, secureTagContents); 229 this.setRecipientKeyAlias(recipientKeyAlias); 230 this.setXmlCipherAlgorithm(xmlCipherAlgorithm); 231 this.setKeyCipherAlgorithm(keyCipherAlgorithm); 232 this.setNamespaces(namespaces); 233 this.setKeyOrTrustStoreParameters(keyOrTrustStoreParameters); 234 this.setKeyPassword(keyPassword); 235 } 236 237 @Deprecated 238 public XMLSecurityDataFormat(String secureTag, Map<String, String> namespaces, boolean secureTagContents, String recipientKeyAlias, 239 String xmlCipherAlgorithm, String keyCipherAlgorithm, KeyStoreParameters keyOrTrustStoreParameters, String keyPassword, 240 String digestAlgorithm) { 241 this(secureTag, secureTagContents); 242 this.setRecipientKeyAlias(recipientKeyAlias); 243 this.setXmlCipherAlgorithm(xmlCipherAlgorithm); 244 this.setKeyCipherAlgorithm(keyCipherAlgorithm); 245 this.setNamespaces(namespaces); 246 this.setKeyOrTrustStoreParameters(keyOrTrustStoreParameters); 247 this.setKeyPassword(keyPassword); 248 this.setDigestAlgorithm(digestAlgorithm); 249 } 250 251 @Override 252 protected void configureDataFormat(DataFormat dataFormat, CamelContext camelContext) { 253 if (getSecureTag() != null) { 254 setProperty(camelContext, dataFormat, "secureTag", getSecureTag()); 255 } else { 256 setProperty(camelContext, dataFormat, "secureTag", ""); 257 } 258 259 boolean isSecureTagContents = getSecureTagContents() != null && getSecureTagContents(); 260 setProperty(camelContext, dataFormat, "secureTagContents", isSecureTagContents); 261 262 if (passPhrase != null) { 263 setProperty(camelContext, dataFormat, "passPhrase", getPassPhrase().getBytes()); 264 } else { 265 setProperty(camelContext, dataFormat, "passPhrase", "Just another 24 Byte key".getBytes()); 266 } 267 if (getXmlCipherAlgorithm() != null) { 268 setProperty(camelContext, dataFormat, "xmlCipherAlgorithm", getXmlCipherAlgorithm()); 269 } else { 270 setProperty(camelContext, dataFormat, "xmlCipherAlgorithm", TRIPLEDES); 271 } 272 if (getKeyCipherAlgorithm() != null) { 273 setProperty(camelContext, dataFormat, "keyCipherAlgorithm", getKeyCipherAlgorithm()); 274 } 275 if (getRecipientKeyAlias() != null) { 276 setProperty(camelContext, dataFormat, "recipientKeyAlias", getRecipientKeyAlias()); 277 } 278 if (getKeyOrTrustStoreParametersId() != null) { 279 setProperty(camelContext, dataFormat, "keyOrTrustStoreParametersId", getKeyOrTrustStoreParametersId()); 280 } 281 if (keyOrTrustStoreParameters != null) { 282 setProperty(camelContext, dataFormat, "keyOrTrustStoreParameters", this.keyOrTrustStoreParameters); 283 } 284 if (namespaces != null) { 285 setProperty(camelContext, dataFormat, "namespaces", this.namespaces); 286 } 287 if (keyPassword != null) { 288 setProperty(camelContext, dataFormat, "keyPassword", this.getKeyPassword()); 289 } 290 if (digestAlgorithm != null) { 291 setProperty(camelContext, dataFormat, "digestAlgorithm", this.getDigestAlgorithm()); 292 } 293 if (mgfAlgorithm != null) { 294 setProperty(camelContext, dataFormat, "mgfAlgorithm", this.getMgfAlgorithm()); 295 } 296 // should be true by default 297 boolean isAddKeyValueForEncryptedKey = getAddKeyValueForEncryptedKey() == null || getAddKeyValueForEncryptedKey(); 298 setProperty(camelContext, dataFormat, "addKeyValueForEncryptedKey", isAddKeyValueForEncryptedKey); 299 } 300 301 public String getXmlCipherAlgorithm() { 302 return xmlCipherAlgorithm; 303 } 304 305 /** 306 * The cipher algorithm to be used for encryption/decryption of the XML message content. The available choices are: 307 * <ul> 308 * <li>XMLCipher.TRIPLEDES</li> 309 * <li>XMLCipher.AES_128</li> 310 * <li>XMLCipher.AES_128_GCM</li> 311 * <li>XMLCipher.AES_192</li> 312 * <li>XMLCipher.AES_192_GCM</li> 313 * <li>XMLCipher.AES_256</li> 314 * <li>XMLCipher.AES_256_GCM</li> 315 * <li>XMLCipher.SEED_128</li> 316 * <li>XMLCipher.CAMELLIA_128</li> 317 * <li>XMLCipher.CAMELLIA_192</li> 318 * <li>XMLCipher.CAMELLIA_256</li> 319 * </ul> 320 * The default value is MLCipher.TRIPLEDES 321 */ 322 public void setXmlCipherAlgorithm(String xmlCipherAlgorithm) { 323 this.xmlCipherAlgorithm = xmlCipherAlgorithm; 324 } 325 326 public String getPassPhrase() { 327 return passPhrase; 328 } 329 330 /** 331 * A String used as passPhrase to encrypt/decrypt content. The passPhrase has to be provided. 332 * If no passPhrase is specified, a default passPhrase is used. 333 * The passPhrase needs to be put together in conjunction with the appropriate encryption algorithm. 334 * For example using TRIPLEDES the passPhase can be a "Only another 24 Byte key" 335 */ 336 public void setPassPhrase(String passPhrase) { 337 this.passPhrase = passPhrase; 338 } 339 340 public String getSecureTag() { 341 return secureTag; 342 } 343 344 /** 345 * The XPath reference to the XML Element selected for encryption/decryption. If no tag is specified, the entire payload is encrypted/decrypted. 346 */ 347 public void setSecureTag(String secureTag) { 348 this.secureTag = secureTag; 349 } 350 351 public Boolean getSecureTagContents() { 352 return secureTagContents; 353 } 354 355 /** 356 * A boolean value to specify whether the XML Element is to be encrypted or the contents of the XML Element 357 * false = Element Level 358 * true = Element Content Level 359 */ 360 public void setSecureTagContents(Boolean secureTagContents) { 361 this.secureTagContents = secureTagContents; 362 } 363 364 /** 365 * The cipher algorithm to be used for encryption/decryption of the asymmetric key. The available choices are: 366 * <ul> 367 * <li>XMLCipher.RSA_v1dot5</li> 368 * <li>XMLCipher.RSA_OAEP</li> 369 * <li>XMLCipher.RSA_OAEP_11</li> 370 * </ul> 371 * The default value is XMLCipher.RSA_OAEP 372 */ 373 public void setKeyCipherAlgorithm(String keyCipherAlgorithm) { 374 this.keyCipherAlgorithm = keyCipherAlgorithm; 375 } 376 377 public String getKeyCipherAlgorithm() { 378 return keyCipherAlgorithm; 379 } 380 381 /** 382 * The key alias to be used when retrieving the recipient's public or private key from a KeyStore when performing asymmetric key encryption or decryption. 383 */ 384 public void setRecipientKeyAlias(String recipientKeyAlias) { 385 this.recipientKeyAlias = recipientKeyAlias; 386 } 387 388 public String getRecipientKeyAlias() { 389 return recipientKeyAlias; 390 } 391 392 /** 393 * Refers to a KeyStore instance to lookup in the registry, which is used for 394 * configuration options for creating and loading a KeyStore instance that represents the sender's trustStore or recipient's keyStore. 395 */ 396 public void setKeyOrTrustStoreParametersId(String id) { 397 this.keyOrTrustStoreParametersId = id; 398 } 399 400 public String getKeyOrTrustStoreParametersId() { 401 return this.keyOrTrustStoreParametersId; 402 } 403 404 public KeyStoreParameters getKeyOrTrustStoreParameters() { 405 return keyOrTrustStoreParameters; 406 } 407 408 /** 409 * Configuration options for creating and loading a KeyStore instance that represents the sender's trustStore or recipient's keyStore. 410 */ 411 private void setKeyOrTrustStoreParameters(KeyStoreParameters keyOrTrustStoreParameters) { 412 this.keyOrTrustStoreParameters = keyOrTrustStoreParameters; 413 } 414 415 public String getKeyPassword() { 416 return this.keyPassword; 417 } 418 419 /** 420 * The password to be used for retrieving the private key from the KeyStore. This key is used for asymmetric decryption. 421 */ 422 public void setKeyPassword(String keyPassword) { 423 this.keyPassword = keyPassword; 424 } 425 426 public String getDigestAlgorithm() { 427 return digestAlgorithm; 428 } 429 430 /** 431 * The digest algorithm to use with the RSA OAEP algorithm. The available choices are: 432 * <ul> 433 * <li>XMLCipher.SHA1</li> 434 * <li>XMLCipher.SHA256</li> 435 * <li>XMLCipher.SHA512</li> 436 * </ul> 437 * The default value is XMLCipher.SHA1 438 */ 439 public void setDigestAlgorithm(String digestAlgorithm) { 440 this.digestAlgorithm = digestAlgorithm; 441 } 442 443 public String getMgfAlgorithm() { 444 return mgfAlgorithm; 445 } 446 447 /** 448 * The MGF Algorithm to use with the RSA OAEP algorithm. The available choices are: 449 * <ul> 450 * <li>EncryptionConstants.MGF1_SHA1</li> 451 * <li>EncryptionConstants.MGF1_SHA256</li> 452 * <li>EncryptionConstants.MGF1_SHA512</li> 453 * </ul> 454 * The default value is EncryptionConstants.MGF1_SHA1 455 */ 456 public void setMgfAlgorithm(String mgfAlgorithm) { 457 this.mgfAlgorithm = mgfAlgorithm; 458 } 459 460 public Boolean getAddKeyValueForEncryptedKey() { 461 return addKeyValueForEncryptedKey; 462 } 463 464 /** 465 * Whether to add the public key used to encrypt the session key as a KeyValue in the EncryptedKey structure or not. 466 */ 467 public void setAddKeyValueForEncryptedKey(Boolean addKeyValueForEncryptedKey) { 468 this.addKeyValueForEncryptedKey = addKeyValueForEncryptedKey; 469 } 470 471 @Override 472 public void setNamespaces(Map<String, String> nspaces) { 473 if (this.namespaces == null) { 474 this.namespaces = new HashMap<>(); 475 } 476 this.namespaces.putAll(nspaces); 477 } 478 479 @Override 480 public Map<String, String> getNamespaces() { 481 return namespaces; 482 } 483}