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 */
017 package org.apache.camel.component.crypto;
018
019 import java.security.KeyStore;
020 import java.security.PrivateKey;
021 import java.security.PublicKey;
022 import java.security.SecureRandom;
023 import java.security.Signature;
024 import java.security.cert.Certificate;
025
026 import org.apache.camel.CamelContext;
027 import org.apache.camel.CamelContextAware;
028 import org.apache.camel.RuntimeCamelException;
029
030 import static org.apache.camel.component.crypto.DigitalSignatureConstants.SIGNATURE;
031
032 public class DigitalSignatureConfiguration implements Cloneable, CamelContextAware {
033
034 private PrivateKey privateKey;
035 private KeyStore keystore;
036 private SecureRandom secureRandom;
037 private String algorithm = "DSA";
038 private Integer bufferSize = new Integer(2048);
039 private String provider;
040 private String signatureHeaderName;
041 private String alias;
042 private char[] password;
043 private PublicKey publicKey;
044 private Certificate certificate;
045 private CamelContext context;
046
047 /** references that should be resolved when the context changes */
048 private String publicKeyName;
049 private String certificateName;
050 private String privateKeyName;
051 private String keystoreName;
052 private String randomName;
053 private boolean clearHeaders;
054 private String operation;
055
056 public DigitalSignatureConfiguration copy() {
057 try {
058 return (DigitalSignatureConfiguration)clone();
059 } catch (CloneNotSupportedException e) {
060 throw new RuntimeCamelException(e);
061 }
062 }
063
064 public CamelContext getCamelContext() {
065 return context;
066 }
067
068 public void setCamelContext(CamelContext camelContext) {
069 this.context = camelContext;
070 // try to retrieve the references once the context is available.
071 setKeystore(keystoreName);
072 setPublicKey(publicKeyName);
073 setPrivateKey(privateKeyName);
074 setCertificate(certificateName);
075 setSecureRandom(randomName);
076 }
077
078 /**
079 * Gets the JCE name of the Algorithm that should be used for the signer.
080 */
081 public String getAlgorithm() {
082 return algorithm;
083 }
084
085 /**
086 * Sets the JCE name of the Algorithm that should be used for the signer.
087 */
088 public void setAlgorithm(String algorithm) {
089 this.algorithm = algorithm;
090 }
091
092 /**
093 * Gets the alias used to query the KeyStore for keys and {@link java.security.cert.Certificate Certificates}
094 * to be used in signing and verifying exchanges. This value can be provided at runtime via the message header
095 * {@link org.apache.camel.component.crypto.DigitalSignatureConstants#KEYSTORE_ALIAS}
096 */
097 public String getAlias() {
098 return alias;
099 }
100
101 /**
102 * Sets the alias used to query the KeyStore for keys and {@link java.security.cert.Certificate Certificates}
103 * to be used in signing and verifying exchanges. This value can be provided at runtime via the message header
104 * {@link org.apache.camel.component.crypto.DigitalSignatureConstants#KEYSTORE_ALIAS}
105 */
106 public void setAlias(String alias) {
107 this.alias = alias;
108 }
109
110 /**
111 * Get the PrivateKey that should be used to sign the exchange
112 */
113 public PrivateKey getPrivateKey() throws Exception {
114 return getPrivateKey(alias, password);
115 }
116
117 /**
118 * Get the PrivateKey that should be used to sign the signature in the
119 * exchange using the supplied alias.
120 *
121 * @param alias the alias used to retrieve the Certificate from the keystore.
122 */
123 public PrivateKey getPrivateKey(String alias) throws Exception {
124 return getPrivateKey(alias, password);
125 }
126
127 /**
128 * Get the PrivateKey that should be used to sign the signature in the
129 * exchange using the supplied alias.
130 *
131 * @param alias the alias used to retrieve the Certificate from the keystore.
132 */
133 public PrivateKey getPrivateKey(String alias, char[] password) throws Exception {
134 PrivateKey pk = null;
135 if (alias != null && keystore != null) {
136 pk = (PrivateKey)keystore.getKey(alias, password);
137 }
138 if (pk == null) {
139 pk = privateKey;
140 }
141 return pk;
142 }
143
144 /**
145 * Set the PrivateKey that should be used to sign the exchange
146 *
147 * @param privateKey the key with with to sign the exchange.
148 */
149 public void setPrivateKey(PrivateKey privateKey) {
150 this.privateKey = privateKey;
151 }
152
153 /**
154 * Sets the reference name for a PrivateKey that can be fond in the registry.
155 */
156 public void setPrivateKey(String privateKeyName) {
157 if (context != null && privateKeyName != null) {
158 PrivateKey pk = context.getRegistry().lookup(privateKeyName, PrivateKey.class);
159 if (pk != null) {
160 setPrivateKey(pk);
161 }
162 }
163 if (privateKeyName != null) {
164 this.privateKeyName = privateKeyName;
165 }
166 }
167
168 /**
169 * Set the PublicKey that should be used to verify the signature in the exchange.
170 */
171 public void setPublicKey(PublicKey publicKey) {
172 this.publicKey = publicKey;
173 }
174
175 /**
176 * Sets the reference name for a publicKey that can be fond in the registry.
177 */
178 public void setPublicKey(String publicKeyName) {
179 if (context != null && publicKeyName != null) {
180 PublicKey pk = context.getRegistry().lookup(publicKeyName, PublicKey.class);
181 if (pk != null) {
182 setPublicKey(pk);
183 }
184 }
185 if (publicKeyName != null) {
186 this.publicKeyName = publicKeyName;
187 }
188 }
189
190 /**
191 * get the PublicKey that should be used to verify the signature in the exchange.
192 */
193 public PublicKey getPublicKey() {
194 return publicKey;
195 }
196
197 /**
198 * Set the Certificate that should be used to verify the signature in the
199 * exchange. If a {@link KeyStore} has been configured then this will
200 * attempt to retrieve the {@link Certificate}from it using hte supplied
201 * alias. If either the alias or the Keystore is invalid then the configured
202 * certificate will be returned
203 *
204 * @param alias the alias used to retrieve the Certificate from the keystore.
205 */
206 public Certificate getCertificate(String alias) throws Exception {
207 Certificate cert = null;
208 if (alias != null && keystore != null) {
209 cert = keystore.getCertificate(alias);
210 }
211 if (cert == null) {
212 cert = certificate;
213 }
214 return cert;
215 }
216
217 /**
218 * Get the explicitly configured {@link Certificate} that should be used to
219 * verify the signature in the exchange.
220 */
221 public Certificate getCertificate() throws Exception {
222 return certificate;
223 }
224
225 /**
226 * Set the Certificate that should be used to verify the signature in the
227 * exchange based on its payload.
228 */
229 public void setCertificate(Certificate certificate) {
230
231 this.certificate = certificate;
232 }
233
234 /**
235 * Sets the reference name for a PrivateKey that can be fond in the registry.
236 */
237 public void setCertificate(String certificateName) {
238 if (context != null && certificateName != null) {
239 Certificate certificate = context.getRegistry().lookup(certificateName, Certificate.class);
240 if (certificate != null) {
241 setCertificate(certificate);
242 }
243 }
244 if (certificateName != null) {
245 this.certificateName = certificateName;
246 }
247 }
248
249 /**
250 * Gets the KeyStore that can contain keys and Certficates for use in
251 * signing and verifying exchanges. A {@link KeyStore} is typically used
252 * with an alias, either one supplied in the Route definition or dynamically
253 * via the message header "CamelSignatureKeyStoreAlias". If no alias is
254 * supplied and there is only a single entry in the Keystore, then this
255 * single entry will be used.
256 */
257 public KeyStore getKeystore() {
258 return keystore;
259 }
260
261 /**
262 * Sets the KeyStore that can contain keys and Certficates for use in
263 * signing and verifying exchanges. A {@link KeyStore} is typically used
264 * with an alias, either one supplied in the Route definition or dynamically
265 * via the message header "CamelSignatureKeyStoreAlias". If no alias is
266 * supplied and there is only a single entry in the Keystore, then this
267 * single entry will be used.
268 */
269 public void setKeystore(KeyStore keystore) {
270 this.keystore = keystore;
271 }
272
273 /**
274 * Sets the reference name for a Keystore that can be fond in the registry.
275 */
276 public void setKeystore(String keystoreName) {
277 if (context != null && keystoreName != null) {
278 KeyStore keystore = context.getRegistry().lookup(keystoreName, KeyStore.class);
279 if (keystore != null) {
280 setKeystore(keystore);
281 }
282 }
283 if (keystoreName != null) {
284 this.keystoreName = keystoreName;
285 }
286 }
287
288 /**
289 * Gets the password used to access an aliased {@link PrivateKey} in the KeyStore.
290 */
291 public char[] getPassword() {
292 return password;
293 }
294
295 /**
296 * Sets the password used to access an aliased {@link PrivateKey} in the KeyStore.
297 */
298 public void setPassword(char[] password) {
299 this.password = password;
300 }
301
302 /**
303 * Get the SecureRandom used to initialize the Signature service
304 */
305 public SecureRandom getSecureRandom() {
306 return secureRandom;
307 }
308
309 /**
310 * Sets the reference name for a SecureRandom that can be fond in the registry.
311 */
312 public void setSecureRandom(String randomName) {
313 if (context != null && randomName != null) {
314 SecureRandom random = context.getRegistry().lookup(randomName, SecureRandom.class);
315 if (keystore != null) {
316 setSecureRandom(random);
317 }
318 }
319 if (randomName != null) {
320 this.randomName = randomName;
321 }
322 }
323
324 /**
325 * Set the SecureRandom used to initialize the Signature service
326 *
327 * @param secureRandom the random used to init the Signature service
328 */
329 public void setSecureRandom(SecureRandom secureRandom) {
330 this.secureRandom = secureRandom;
331 }
332
333 /**
334 * Get the size of the buffer used to read in the Exchange payload data.
335 */
336 public Integer getBufferSize() {
337 return bufferSize;
338 }
339
340 /**
341 * Set the size of the buffer used to read in the Exchange payload data.
342 */
343 public void setBufferSize(Integer bufferSize) {
344 this.bufferSize = bufferSize;
345 }
346
347 /**
348 * Get the id of the security provider that provides the configured
349 * {@link Signature} algorithm.
350 */
351 public String getProvider() {
352 return provider;
353 }
354
355 /**
356 * Set the id of the security provider that provides the configured
357 * {@link Signature} algorithm.
358 *
359 * @param provider the id of the security provider
360 */
361 public void setProvider(String provider) {
362 this.provider = provider;
363 }
364
365 /**
366 * Get the name of the message header that should be used to store the
367 * base64 encoded signature. This defaults to 'CamelDigitalSignature'
368 */
369 public String getSignatureHeader() {
370 return signatureHeaderName != null ? signatureHeaderName : SIGNATURE;
371 }
372
373 /**
374 * Set the name of the message header that should be used to store the
375 * base64 encoded signature. This defaults to 'CamelDigitalSignature'
376 */
377 public void setSignatureHeader(String signatureHeaderName) {
378 this.signatureHeaderName = signatureHeaderName;
379 }
380
381 /**
382 * Determines if the Signature specific headers be cleared after signing and
383 * verification. Defaults to true, and should only be made otherwise at your
384 * extreme peril as vital private information such as Keys and passwords may
385 * escape if unset.
386 *
387 * @return true if the Signature headers should be unset, false otherwise
388 */
389 public boolean getClearHeaders() {
390 return clearHeaders;
391 }
392
393 /**
394 * Determines if the Signature specific headers be cleared after signing and
395 * verification. Defaults to true, and should only be made otherwise at your
396 * extreme peril as vital private information such as Keys and passwords may
397 * escape if unset.
398 */
399 public void setClearHeaders(boolean clearHeaders) {
400 this.clearHeaders = clearHeaders;
401 }
402
403 /**
404 * Set the Crypto operation from that supplied after the crypto scheme in the
405 * endpoint uri e.g. crypto:sign sets sign as the operation.
406 *
407 * @param operation the operation supplied after the crypto scheme
408 */
409 public void setCryptoOperation(String operation) {
410 this.operation = operation;
411 }
412
413 /**
414 * Gets the Crypto operation that was supplied in the the crypto scheme in the endpoint uri
415 */
416 public String getCryptoOperation() {
417 return operation;
418 }
419 }