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