| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.camel.converter.crypto; |
| |
| import java.security.InvalidKeyException; |
| import java.security.Key; |
| import java.security.NoSuchAlgorithmException; |
| |
| import javax.crypto.KeyGenerator; |
| import javax.crypto.Mac; |
| |
| import org.apache.camel.converter.crypto.HMACAccumulator.CircularBuffer; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| import static org.junit.Assert.assertEquals; |
| |
| public class HMACAccumulatorTest { |
| private byte[] payload = {0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77, (byte)0x88, (byte)0x88, (byte)0x99, (byte)0x99}; |
| private byte[] expected; |
| private Key key; |
| |
| @Before |
| public void setupKeyAndExpectedMac() throws Exception { |
| KeyGenerator generator = KeyGenerator.getInstance("DES"); |
| key = generator.generateKey(); |
| createExpectedMac(); |
| } |
| |
| private void createExpectedMac() throws NoSuchAlgorithmException, InvalidKeyException { |
| Mac mac = Mac.getInstance("HmacSHA1"); |
| mac.init(key); |
| expected = mac.doFinal(payload); |
| } |
| |
| @Test |
| public void testEncryptionPhaseCalculation() throws Exception { |
| int buffersize = 256; |
| byte[] buffer = new byte[buffersize]; |
| System.arraycopy(payload, 0, buffer, 0, payload.length); |
| |
| HMACAccumulator builder = new HMACAccumulator(key, "HmacSHA1", null, buffersize); |
| builder.encryptUpdate(buffer, 20); |
| assertMacs(expected, builder.getCalculatedMac()); |
| } |
| |
| @Test |
| public void testDecryptionWhereBufferSizeIsGreaterThanDataSize() throws Exception { |
| int buffersize = 256; |
| byte[] buffer = initializeBuffer(buffersize); |
| |
| HMACAccumulator builder = new HMACAccumulator(key, "HmacSHA1", null, buffersize); |
| builder.decryptUpdate(buffer, 40); |
| validate(builder); |
| } |
| |
| @Test |
| public void testDecryptionWhereMacOverlaps() throws Exception { |
| int buffersize = 32; |
| byte[] buffer = new byte[buffersize]; |
| int overlap = buffersize - payload.length; |
| System.arraycopy(payload, 0, buffer, 0, payload.length); |
| System.arraycopy(expected, 0, buffer, payload.length, overlap); |
| |
| HMACAccumulator builder = new HMACAccumulator(key, "HmacSHA1", null, buffersize); |
| builder.decryptUpdate(buffer, buffersize); |
| System.arraycopy(expected, overlap, buffer, 0, 20 - overlap); |
| builder.decryptUpdate(buffer, 20 - overlap); |
| validate(builder); |
| } |
| |
| @Test |
| public void testDecryptionWhereDataIsMultipleOfBufferLength() throws Exception { |
| int buffersize = 20; |
| byte[] buffer = new byte[buffersize]; |
| System.arraycopy(payload, 0, buffer, 0, payload.length); |
| |
| HMACAccumulator builder = new HMACAccumulator(key, "HmacSHA1", null, buffersize); |
| builder.decryptUpdate(buffer, buffersize); |
| System.arraycopy(expected, 0, buffer, 0, expected.length); |
| builder.decryptUpdate(buffer, 20); |
| validate(builder); |
| } |
| |
| @Test |
| public void testDecryptionWhereThereIsNoPayloadData() throws Exception { |
| int buffersize = 20; |
| byte[] buffer = new byte[buffersize]; |
| payload = new byte[0]; |
| createExpectedMac(); |
| |
| HMACAccumulator builder = new HMACAccumulator(key, "HmacSHA1", null, buffersize); |
| System.arraycopy(expected, 0, buffer, 0, expected.length); |
| builder.decryptUpdate(buffer, 20); |
| validate(builder); |
| } |
| |
| @Test |
| public void testDecryptionMultipleReadsSmallerThanBufferSize() throws Exception { |
| int buffersize = 256; |
| byte[] buffer = new byte[buffersize]; |
| |
| HMACAccumulator builder = new HMACAccumulator(key, "HmacSHA1", null, buffersize); |
| int read = payload.length / 2; |
| System.arraycopy(payload, 0, buffer, 0, read); |
| builder.decryptUpdate(buffer, read); |
| System.arraycopy(payload, read, buffer, 0, read); |
| builder.decryptUpdate(buffer, read); |
| System.arraycopy(expected, 0, buffer, 0, expected.length); |
| builder.decryptUpdate(buffer, 20); |
| validate(builder); |
| } |
| |
| private void validate(HMACAccumulator builder) { |
| assertMacs(builder.getCalculatedMac(), builder.getCalculatedMac()); |
| assertMacs(builder.getAppendedMac(), builder.getAppendedMac()); |
| assertMacs(expected, builder.getCalculatedMac()); |
| assertMacs(expected, builder.getAppendedMac()); |
| builder.validate(); |
| } |
| |
| private void assertMacs(byte[] expected, byte[] actual) { |
| assertEquals(HexUtils.byteArrayToHexString(expected), HexUtils.byteArrayToHexString(actual)); |
| } |
| |
| @Test |
| public void testBufferAdd() throws Exception { |
| CircularBuffer buffer = new CircularBuffer(payload.length * 2); |
| buffer.write(payload, 0, payload.length); |
| assertEquals(payload.length, buffer.availableForWrite()); |
| buffer.write(payload, 0, payload.length); |
| assertEquals(0, buffer.availableForWrite()); |
| buffer.write(payload, 0, payload.length); |
| assertEquals(0, buffer.availableForWrite()); |
| } |
| |
| @Test |
| public void testBufferDrain() throws Exception { |
| CircularBuffer buffer = new CircularBuffer(payload.length * 2); |
| buffer.write(payload, 0, payload.length); |
| |
| byte[] data = new byte[payload.length >> 1]; |
| assertEquals(data.length, buffer.read(data, 0, data.length)); |
| assertEquals(data.length, buffer.read(data, 0, data.length)); |
| assertEquals(0, buffer.read(data, 0, data.length)); |
| } |
| |
| @Test |
| public void testBufferCompare() throws Exception { |
| CircularBuffer buffer = new CircularBuffer(payload.length * 2); |
| buffer.write(new byte[payload.length >> 1], 0, payload.length >> 1); |
| buffer.write(payload, 0, payload.length); |
| buffer.compareTo(payload, 0, payload.length); |
| } |
| |
| private byte[] initializeBuffer(int buffersize) { |
| byte[] buffer = new byte[buffersize]; |
| System.arraycopy(payload, 0, buffer, 0, payload.length); |
| System.arraycopy(expected, 0, buffer, payload.length, expected.length); |
| return buffer; |
| } |
| } |