Java tutorial
/* * Copyright 2015 Kevin Herron * * Licensed 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 com.digitalpetri.opcua.stack; import java.util.List; import com.digitalpetri.opcua.stack.core.channel.ChannelConfig; import com.digitalpetri.opcua.stack.core.channel.ChannelParameters; import com.digitalpetri.opcua.stack.core.channel.ChunkDecoder; import com.digitalpetri.opcua.stack.core.channel.ChunkEncoder; import com.digitalpetri.opcua.stack.core.channel.ClientSecureChannel; import com.digitalpetri.opcua.stack.core.channel.SecureChannel; import com.digitalpetri.opcua.stack.core.channel.ServerSecureChannel; import com.digitalpetri.opcua.stack.core.channel.messages.MessageType; import com.digitalpetri.opcua.stack.core.security.SecurityPolicy; import com.digitalpetri.opcua.stack.core.types.builtin.unsigned.UInteger; import com.digitalpetri.opcua.stack.core.types.enumerated.MessageSecurityMode; import com.digitalpetri.opcua.stack.core.util.BufferUtil; import com.digitalpetri.opcua.stack.core.util.CryptoRestrictions; import com.digitalpetri.opcua.stack.core.util.LongSequence; import io.netty.buffer.ByteBuf; import io.netty.util.ReferenceCountUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import static org.testng.Assert.assertEquals; public class ChunkSerializationTest extends SecureChannelFixture { static { CryptoRestrictions.remove(); // ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.PARANOID); } Logger logger = LoggerFactory.getLogger(getClass()); ChannelParameters parameters = new ChannelParameters(ChannelConfig.DEFAULT_MAX_MESSAGE_SIZE, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE, ChannelConfig.DEFAULT_MAX_CHUNK_COUNT, ChannelConfig.DEFAULT_MAX_MESSAGE_SIZE, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE, ChannelConfig.DEFAULT_MAX_CHUNK_COUNT); @DataProvider public Object[][] getAsymmetricSecurityParameters() { return new Object[][] { { SecurityPolicy.None, MessageSecurityMode.None, 128 }, { SecurityPolicy.Basic128Rsa15, MessageSecurityMode.Sign, 128 }, { SecurityPolicy.Basic128Rsa15, MessageSecurityMode.SignAndEncrypt, 128 }, { SecurityPolicy.Basic256, MessageSecurityMode.Sign, 128 }, { SecurityPolicy.Basic256, MessageSecurityMode.SignAndEncrypt, 128 }, { SecurityPolicy.Basic256Sha256, MessageSecurityMode.Sign, 128 }, { SecurityPolicy.Basic256Sha256, MessageSecurityMode.SignAndEncrypt, 128 }, { SecurityPolicy.None, MessageSecurityMode.None, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, { SecurityPolicy.Basic128Rsa15, MessageSecurityMode.Sign, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, { SecurityPolicy.Basic128Rsa15, MessageSecurityMode.SignAndEncrypt, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, { SecurityPolicy.Basic256, MessageSecurityMode.Sign, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, { SecurityPolicy.Basic256, MessageSecurityMode.SignAndEncrypt, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, { SecurityPolicy.Basic256Sha256, MessageSecurityMode.Sign, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, { SecurityPolicy.Basic256Sha256, MessageSecurityMode.SignAndEncrypt, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, }; } @Test(dataProvider = "getAsymmetricSecurityParameters") public void testAsymmetricMessage(SecurityPolicy securityPolicy, MessageSecurityMode messageSecurity, int messageSize) throws Exception { logger.info("Asymmetric chunk serialization, securityPolicy={}, messageSecurityMode={}, messageSize={}", securityPolicy, messageSecurity, messageSize); ChunkEncoder encoder = new ChunkEncoder(parameters); ChunkDecoder decoder = new ChunkDecoder(parameters); SecureChannel[] channels = generateChannels(securityPolicy, messageSecurity); ClientSecureChannel clientChannel = (ClientSecureChannel) channels[0]; ServerSecureChannel serverChannel = (ServerSecureChannel) channels[1]; clientChannel.attr(ClientSecureChannel.KEY_REQUEST_ID_SEQUENCE) .setIfAbsent(new LongSequence(1L, UInteger.MAX_VALUE)); LongSequence requestId = clientChannel.attr(ClientSecureChannel.KEY_REQUEST_ID_SEQUENCE).get(); byte[] messageBytes = new byte[messageSize]; for (int i = 0; i < messageBytes.length; i++) { messageBytes[i] = (byte) i; } ByteBuf messageBuffer = BufferUtil.buffer().writeBytes(messageBytes); List<ByteBuf> chunkBuffers = encoder.encodeAsymmetric(clientChannel, MessageType.OpenSecureChannel, messageBuffer, requestId.getAndIncrement()); ByteBuf decodedBuffer = decoder.decodeAsymmetric(serverChannel, chunkBuffers); ReferenceCountUtil.releaseLater(messageBuffer); ReferenceCountUtil.releaseLater(decodedBuffer); messageBuffer.readerIndex(0); assertEquals(decodedBuffer, messageBuffer); } @DataProvider public Object[][] getSymmetricSecurityParameters() { return new Object[][] { { SecurityPolicy.None, MessageSecurityMode.None, 128 }, { SecurityPolicy.Basic128Rsa15, MessageSecurityMode.Sign, 128 }, { SecurityPolicy.Basic128Rsa15, MessageSecurityMode.SignAndEncrypt, 128 }, { SecurityPolicy.Basic256, MessageSecurityMode.Sign, 128 }, { SecurityPolicy.Basic256, MessageSecurityMode.SignAndEncrypt, 128 }, { SecurityPolicy.Basic256Sha256, MessageSecurityMode.Sign, 128 }, { SecurityPolicy.Basic256Sha256, MessageSecurityMode.SignAndEncrypt, 128 }, { SecurityPolicy.None, MessageSecurityMode.None, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, { SecurityPolicy.Basic128Rsa15, MessageSecurityMode.Sign, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, { SecurityPolicy.Basic128Rsa15, MessageSecurityMode.SignAndEncrypt, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, { SecurityPolicy.Basic256, MessageSecurityMode.Sign, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, { SecurityPolicy.Basic256, MessageSecurityMode.SignAndEncrypt, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, { SecurityPolicy.Basic256Sha256, MessageSecurityMode.Sign, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, { SecurityPolicy.Basic256Sha256, MessageSecurityMode.SignAndEncrypt, ChannelConfig.DEFAULT_MAX_CHUNK_SIZE }, { SecurityPolicy.None, MessageSecurityMode.None, ChannelConfig.DEFAULT_MAX_MESSAGE_SIZE }, { SecurityPolicy.Basic128Rsa15, MessageSecurityMode.Sign, ChannelConfig.DEFAULT_MAX_MESSAGE_SIZE }, { SecurityPolicy.Basic128Rsa15, MessageSecurityMode.SignAndEncrypt, ChannelConfig.DEFAULT_MAX_MESSAGE_SIZE }, { SecurityPolicy.Basic256, MessageSecurityMode.Sign, ChannelConfig.DEFAULT_MAX_MESSAGE_SIZE }, { SecurityPolicy.Basic256, MessageSecurityMode.SignAndEncrypt, ChannelConfig.DEFAULT_MAX_MESSAGE_SIZE }, { SecurityPolicy.Basic256Sha256, MessageSecurityMode.Sign, ChannelConfig.DEFAULT_MAX_MESSAGE_SIZE }, { SecurityPolicy.Basic256Sha256, MessageSecurityMode.SignAndEncrypt, ChannelConfig.DEFAULT_MAX_MESSAGE_SIZE }, }; } @Test(dataProvider = "getSymmetricSecurityParameters") public void testSymmetricMessage(SecurityPolicy securityPolicy, MessageSecurityMode messageSecurity, int messageSize) throws Exception { logger.info("Symmetric chunk serialization, securityPolicy={}, messageSecurityMode={}, messageSize={}", securityPolicy, messageSecurity, messageSize); ChunkEncoder encoder = new ChunkEncoder(parameters); ChunkDecoder decoder = new ChunkDecoder(parameters); SecureChannel[] channels = generateChannels(securityPolicy, messageSecurity); ClientSecureChannel clientChannel = (ClientSecureChannel) channels[0]; ServerSecureChannel serverChannel = (ServerSecureChannel) channels[1]; clientChannel.attr(ClientSecureChannel.KEY_REQUEST_ID_SEQUENCE) .setIfAbsent(new LongSequence(1L, UInteger.MAX_VALUE)); LongSequence requestId = clientChannel.attr(ClientSecureChannel.KEY_REQUEST_ID_SEQUENCE).get(); byte[] messageBytes = new byte[messageSize]; for (int i = 0; i < messageBytes.length; i++) { messageBytes[i] = (byte) i; } ByteBuf messageBuffer = BufferUtil.buffer().writeBytes(messageBytes); List<ByteBuf> chunkBuffers = encoder.encodeSymmetric(clientChannel, MessageType.SecureMessage, messageBuffer, requestId.getAndIncrement()); ByteBuf decodedBuffer = decoder.decodeSymmetric(serverChannel, chunkBuffers); ReferenceCountUtil.releaseLater(messageBuffer); ReferenceCountUtil.releaseLater(decodedBuffer); messageBuffer.readerIndex(0); assertEquals(decodedBuffer, messageBuffer); } }