Search in sources :

Example 1 with SecurityKeys

use of org.eclipse.milo.opcua.stack.core.channel.ChannelSecurity.SecurityKeys in project milo by eclipse.

the class UascServerAsymmetricHandler method openSecureChannel.

private OpenSecureChannelResponse openSecureChannel(ChannelHandlerContext ctx, OpenSecureChannelRequest request) throws UaException {
    SecurityTokenRequestType requestType = request.getRequestType();
    if (requestType == SecurityTokenRequestType.Issue) {
        secureChannel.setMessageSecurityMode(request.getSecurityMode());
        String endpointUrl = ctx.channel().attr(UascServerHelloHandler.ENDPOINT_URL_KEY).get();
        EndpointDescription endpoint = stackServer.getEndpointDescriptions().stream().filter(e -> {
            boolean transportMatch = Objects.equals(e.getTransportProfileUri(), transportProfile.getUri());
            boolean pathMatch = Objects.equals(EndpointUtil.getPath(e.getEndpointUrl()), EndpointUtil.getPath(endpointUrl));
            boolean securityPolicyMatch = Objects.equals(e.getSecurityPolicyUri(), secureChannel.getSecurityPolicy().getUri());
            boolean securityModeMatch = Objects.equals(e.getSecurityMode(), request.getSecurityMode());
            return transportMatch && pathMatch && securityPolicyMatch && securityModeMatch;
        }).findFirst().orElseThrow(() -> {
            String message = String.format("no matching endpoint found: transportProfile=%s, " + "endpointUrl=%s, securityPolicy=%s, securityMode=%s", transportProfile, endpointUrl, secureChannel.getSecurityPolicy(), request.getSecurityMode());
            return new UaException(StatusCodes.Bad_SecurityChecksFailed, message);
        });
        ctx.channel().attr(ENDPOINT_KEY).set(endpoint);
    }
    if (requestType == SecurityTokenRequestType.Renew && secureChannel.getMessageSecurityMode() != request.getSecurityMode()) {
        throw new UaException(StatusCodes.Bad_SecurityChecksFailed, "secure channel renewal requested a different MessageSecurityMode.");
    }
    long channelLifetime = request.getRequestedLifetime().longValue();
    channelLifetime = Math.min(channelLifetime, stackServer.getConfig().getMaximumSecureChannelLifetime().longValue());
    channelLifetime = Math.max(channelLifetime, stackServer.getConfig().getMinimumSecureChannelLifetime().longValue());
    ChannelSecurityToken newToken = new ChannelSecurityToken(uint(secureChannel.getChannelId()), uint(stackServer.getNextTokenId()), DateTime.now(), uint(channelLifetime));
    SecurityKeys newKeys = null;
    if (secureChannel.isSymmetricSigningEnabled()) {
        // Validate the remote nonce; it must be non-null and the correct length for the security algorithm.
        ByteString remoteNonce = request.getClientNonce();
        NonceUtil.validateNonce(remoteNonce, secureChannel.getSecurityPolicy());
        ByteString localNonce = generateNonce(secureChannel.getSecurityPolicy());
        secureChannel.setLocalNonce(localNonce);
        secureChannel.setRemoteNonce(remoteNonce);
        newKeys = ChannelSecurity.generateKeyPair(secureChannel, secureChannel.getRemoteNonce(), secureChannel.getLocalNonce());
    }
    ChannelSecurity oldSecrets = secureChannel.getChannelSecurity();
    SecurityKeys oldKeys = oldSecrets != null ? oldSecrets.getCurrentKeys() : null;
    ChannelSecurityToken oldToken = oldSecrets != null ? oldSecrets.getCurrentToken() : null;
    ChannelSecurity newSecrets = new ChannelSecurity(newKeys, newToken, oldKeys, oldToken);
    secureChannel.setChannelSecurity(newSecrets);
    /*
         * Cancel the previous timeout, if it exists, and start a new one.
         */
    if (secureChannelTimeout == null || secureChannelTimeout.cancel()) {
        final long lifetime = channelLifetime;
        secureChannelTimeout = Stack.sharedWheelTimer().newTimeout(timeout -> {
            logger.debug("SecureChannel renewal timed out after {}ms. id={}, channel={}", lifetime, secureChannel.getChannelId(), ctx.channel());
            ctx.close();
        }, channelLifetime, TimeUnit.MILLISECONDS);
    }
    ResponseHeader responseHeader = new ResponseHeader(DateTime.now(), request.getRequestHeader().getRequestHandle(), StatusCode.GOOD, null, null, null);
    return new OpenSecureChannelResponse(responseHeader, uint(PROTOCOL_VERSION), newToken, secureChannel.getLocalNonce());
}
Also used : X509Certificate(java.security.cert.X509Certificate) AttributeKey(io.netty.util.AttributeKey) ErrorMessage(org.eclipse.milo.opcua.stack.core.channel.messages.ErrorMessage) KeyPair(java.security.KeyPair) ChannelSecurityToken(org.eclipse.milo.opcua.stack.core.types.structured.ChannelSecurityToken) ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString) LoggerFactory(org.slf4j.LoggerFactory) SecurityKeys(org.eclipse.milo.opcua.stack.core.channel.ChannelSecurity.SecurityKeys) DateTime(org.eclipse.milo.opcua.stack.core.types.builtin.DateTime) MessageEncodeException(org.eclipse.milo.opcua.stack.core.channel.MessageEncodeException) Unsigned.uint(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint) CertificateManager(org.eclipse.milo.opcua.stack.core.security.CertificateManager) TransportProfile(org.eclipse.milo.opcua.stack.core.transport.TransportProfile) SerializationQueue(org.eclipse.milo.opcua.stack.core.channel.SerializationQueue) Objects(java.util.Objects) CompositeByteBuf(io.netty.buffer.CompositeByteBuf) List(java.util.List) StatusCode(org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) CertificateValidator(org.eclipse.milo.opcua.stack.core.security.CertificateValidator) EncodedMessage(org.eclipse.milo.opcua.stack.core.channel.ChunkEncoder.EncodedMessage) Optional(java.util.Optional) MessageType(org.eclipse.milo.opcua.stack.core.channel.messages.MessageType) BufferUtil(org.eclipse.milo.opcua.stack.core.util.BufferUtil) EndpointUtil(org.eclipse.milo.opcua.stack.core.util.EndpointUtil) ChunkDecoder(org.eclipse.milo.opcua.stack.core.channel.ChunkDecoder) ExceptionHandler(org.eclipse.milo.opcua.stack.core.channel.ExceptionHandler) HeaderDecoder(org.eclipse.milo.opcua.stack.core.channel.headers.HeaderDecoder) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) MessageDecodeException(org.eclipse.milo.opcua.stack.core.channel.MessageDecodeException) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) Stack(org.eclipse.milo.opcua.stack.core.Stack) EndpointDescription(org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription) ByteToMessageDecoder(io.netty.handler.codec.ByteToMessageDecoder) SecurityPolicy(org.eclipse.milo.opcua.stack.core.security.SecurityPolicy) UaStackServer(org.eclipse.milo.opcua.stack.server.UaStackServer) StatusCodes(org.eclipse.milo.opcua.stack.core.StatusCodes) Timeout(io.netty.util.Timeout) AsymmetricSecurityHeader(org.eclipse.milo.opcua.stack.core.channel.headers.AsymmetricSecurityHeader) Logger(org.slf4j.Logger) NonceUtil.generateNonce(org.eclipse.milo.opcua.stack.core.util.NonceUtil.generateNonce) IOException(java.io.IOException) UaSerializationException(org.eclipse.milo.opcua.stack.core.UaSerializationException) OpenSecureChannelRequest(org.eclipse.milo.opcua.stack.core.types.structured.OpenSecureChannelRequest) MessageAbortException(org.eclipse.milo.opcua.stack.core.channel.MessageAbortException) ServerSecureChannel(org.eclipse.milo.opcua.stack.core.channel.ServerSecureChannel) OpenSecureChannelResponse(org.eclipse.milo.opcua.stack.core.types.structured.OpenSecureChannelResponse) TimeUnit(java.util.concurrent.TimeUnit) NonceUtil(org.eclipse.milo.opcua.stack.core.util.NonceUtil) ChannelSecurity(org.eclipse.milo.opcua.stack.core.channel.ChannelSecurity) UaException(org.eclipse.milo.opcua.stack.core.UaException) SecurityTokenRequestType(org.eclipse.milo.opcua.stack.core.types.enumerated.SecurityTokenRequestType) ResponseHeader(org.eclipse.milo.opcua.stack.core.types.structured.ResponseHeader) ResponseHeader(org.eclipse.milo.opcua.stack.core.types.structured.ResponseHeader) OpenSecureChannelResponse(org.eclipse.milo.opcua.stack.core.types.structured.OpenSecureChannelResponse) UaException(org.eclipse.milo.opcua.stack.core.UaException) ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString) SecurityKeys(org.eclipse.milo.opcua.stack.core.channel.ChannelSecurity.SecurityKeys) ChannelSecurity(org.eclipse.milo.opcua.stack.core.channel.ChannelSecurity) SecurityTokenRequestType(org.eclipse.milo.opcua.stack.core.types.enumerated.SecurityTokenRequestType) ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString) EndpointDescription(org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription) ChannelSecurityToken(org.eclipse.milo.opcua.stack.core.types.structured.ChannelSecurityToken)

Aggregations

ByteBuf (io.netty.buffer.ByteBuf)1 CompositeByteBuf (io.netty.buffer.CompositeByteBuf)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 ByteToMessageDecoder (io.netty.handler.codec.ByteToMessageDecoder)1 AttributeKey (io.netty.util.AttributeKey)1 ReferenceCountUtil (io.netty.util.ReferenceCountUtil)1 Timeout (io.netty.util.Timeout)1 IOException (java.io.IOException)1 KeyPair (java.security.KeyPair)1 X509Certificate (java.security.cert.X509Certificate)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1 TimeUnit (java.util.concurrent.TimeUnit)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Stack (org.eclipse.milo.opcua.stack.core.Stack)1 StatusCodes (org.eclipse.milo.opcua.stack.core.StatusCodes)1 UaException (org.eclipse.milo.opcua.stack.core.UaException)1 UaSerializationException (org.eclipse.milo.opcua.stack.core.UaSerializationException)1