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.PublicKey;
020 import java.security.Signature;
021 import java.security.SignatureException;
022 import java.security.cert.Certificate;
023
024 import org.apache.camel.Exchange;
025 import org.apache.camel.component.crypto.DigitalSignatureConfiguration;
026 import org.apache.camel.util.ExchangeHelper;
027 import org.apache.commons.codec.binary.Base64;
028
029 import static org.apache.camel.component.crypto.DigitalSignatureConstants.SIGNATURE_PUBLIC_KEY_OR_CERT;
030
031 /**
032 * <code>VerifyingProcessor</code>
033 */
034 public class VerifyingProcessor extends DigitalSignatureProcessor {
035
036 public VerifyingProcessor(DigitalSignatureConfiguration configuration) {
037 super(configuration);
038 }
039
040 public void process(Exchange exchange) throws Exception {
041 Signature signer = createSignatureService();
042 Certificate cert = getCertificate(exchange);
043 if (cert == null) {
044 PublicKey pk = getPublicKeyOrCertificateFromHeader(exchange, PublicKey.class, config.getPublicKey());
045 if (pk == null) {
046 throw new IllegalStateException(String.format("Cannot verify signature as no Public Key or Certificate has been supplied."
047 + " Either supply one in the route definition or via the message header '%s'", SIGNATURE_PUBLIC_KEY_OR_CERT));
048 }
049 signer.initVerify(pk);
050 } else {
051 signer.initVerify(cert);
052 }
053
054 calculateSignature(exchange, signer);
055
056 byte[] signature = getSignatureFromExchange(exchange);
057 if (!signer.verify(signature)) {
058 throw new SignatureException("Cannot verify signature of exchange");
059 }
060 clearMessageHeaders(exchange.getIn());
061 }
062
063 private byte[] getSignatureFromExchange(Exchange exchange) throws Exception {
064 String encodedSignature = ExchangeHelper.getMandatoryHeader(exchange, config.getSignatureHeader(), String.class);
065 if (encodedSignature == null) {
066 throw new IllegalStateException("Cannot verify exchange as no " + config.getSignatureHeader() + " header is present.");
067 }
068 return new Base64().decode(encodedSignature);
069 }
070
071 private Certificate getCertificate(Exchange exchange) throws Exception {
072 Certificate cert = config.getCertificate(getAlias(exchange));
073 return getPublicKeyOrCertificateFromHeader(exchange, Certificate.class, cert);
074 }
075
076 private <T> T getPublicKeyOrCertificateFromHeader(Exchange exchange, Class<? extends T> verificationType, T defaultsTo) {
077 T pkOrCert = exchange.getIn().getHeader(SIGNATURE_PUBLIC_KEY_OR_CERT, verificationType);
078 if (pkOrCert == null) {
079 pkOrCert = defaultsTo;
080 }
081 return pkOrCert;
082 }
083
084 }