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.processor;
018
019 import java.security.KeyStore;
020 import java.security.PrivateKey;
021 import java.security.SecureRandom;
022 import java.security.Signature;
023 import static java.lang.String.format;
024
025 import org.apache.camel.Exchange;
026 import org.apache.camel.Message;
027 import org.apache.camel.component.crypto.DigitalSignatureConfiguration;
028 import org.apache.camel.component.crypto.DigitalSignatureConstants;
029 import org.apache.commons.codec.binary.Base64;
030
031 import static org.apache.camel.component.crypto.DigitalSignatureConstants.SIGNATURE_PRIVATE_KEY;
032
033 public class SigningProcessor extends DigitalSignatureProcessor {
034
035 public SigningProcessor(DigitalSignatureConfiguration configuration) {
036 super(configuration);
037 }
038
039 public void process(Exchange exchange) throws Exception {
040 Signature service = initSignatureService(exchange);
041 calculateSignature(exchange, service);
042 byte[] signature = service.sign();
043
044 Message in = exchange.getIn();
045 clearMessageHeaders(in);
046 Message out = exchange.getOut();
047 out.copyFrom(in);
048 out.setHeader(config.getSignatureHeader(), new Base64().encode(signature));
049 }
050
051 protected Signature initSignatureService(Exchange exchange) throws Exception {
052 PrivateKey pk = getPrivateKeyFromKeystoreOrExchange(exchange);
053 SecureRandom random = config.getSecureRandom();
054 Signature service = createSignatureService();
055 if (random != null) {
056 service.initSign(pk, random);
057 } else {
058 service.initSign(pk);
059 }
060 return service;
061 }
062
063 private PrivateKey getPrivateKeyFromKeystoreOrExchange(Exchange exchange) throws Exception {
064 PrivateKey pk = config.getPrivateKey(getAlias(exchange), getKeyPassword(exchange));
065
066 if (pk == null) {
067 pk = exchange.getIn().getHeader(SIGNATURE_PRIVATE_KEY, PrivateKey.class);
068 if (pk == null) {
069 throw new IllegalStateException(format("Cannot sign message as no Private Key has been supplied. Either supply one in"
070 + " the route definition sign(keystore, alias) or sign(privateKey) or via the message header '%s'", SIGNATURE_PRIVATE_KEY));
071 }
072 }
073 return pk;
074 }
075
076 protected char[] getKeyPassword(Exchange exchange) throws Exception {
077 KeyStore keystore = config.getKeystore();
078 char[] password = null;
079 if (keystore != null) {
080 password = exchange.getIn().getHeader(DigitalSignatureConstants.KEYSTORE_PASSWORD, char[].class);
081 if (password == null) {
082 password = config.getPassword();
083 }
084 }
085 return password;
086 }
087 }