Search in sources :

Example 1 with SignedSoftwareCertificate

use of org.eclipse.milo.opcua.stack.core.types.structured.SignedSoftwareCertificate in project milo by eclipse.

the class SessionManager method activateSession.

private ActivateSessionResponse activateSession(ServiceRequest serviceRequest) throws UaException {
    ActivateSessionRequest request = (ActivateSessionRequest) serviceRequest.getRequest();
    long secureChannelId = serviceRequest.getSecureChannelId();
    NodeId authToken = request.getRequestHeader().getAuthenticationToken();
    List<SignedSoftwareCertificate> clientSoftwareCertificates = l(request.getClientSoftwareCertificates());
    Session session = createdSessions.get(authToken);
    if (session == null) {
        session = activeSessions.get(authToken);
        if (session == null) {
            throw new UaException(StatusCodes.Bad_SessionIdInvalid);
        } else {
            verifyClientSignature(session, request);
            SecurityConfiguration securityConfiguration = session.getSecurityConfiguration();
            if (session.getSecureChannelId() == secureChannelId) {
                /*
                     * Identity change
                     */
                UserIdentityToken identityToken = decodeIdentityToken(request.getUserIdentityToken(), session.getEndpoint().getUserIdentityTokens());
                Object identityObject = validateIdentityToken(session, identityToken, request.getUserTokenSignature());
                StatusCode[] results = new StatusCode[clientSoftwareCertificates.size()];
                Arrays.fill(results, StatusCode.GOOD);
                ByteString serverNonce = NonceUtil.generateNonce(32);
                session.setClientAddress(serviceRequest.getClientAddress());
                session.setIdentityObject(identityObject, identityToken);
                session.setLastNonce(serverNonce);
                session.setLocaleIds(request.getLocaleIds());
                return new ActivateSessionResponse(serviceRequest.createResponseHeader(), serverNonce, results, new DiagnosticInfo[0]);
            } else {
                /*
                     * Associate session with new secure channel if client certificate and identity token match.
                     */
                ByteString clientCertificateBytes = serviceRequest.getClientCertificateBytes();
                UserIdentityToken identityToken = decodeIdentityToken(request.getUserIdentityToken(), session.getEndpoint().getUserIdentityTokens());
                Object identityObject = validateIdentityToken(session, identityToken, request.getUserTokenSignature());
                boolean sameIdentity = Objects.equal(identityObject, session.getIdentityObject());
                boolean sameCertificate = Objects.equal(clientCertificateBytes, securityConfiguration.getClientCertificateBytes());
                if (sameIdentity && sameCertificate) {
                    SecurityConfiguration newSecurityConfiguration = createSecurityConfiguration(serviceRequest.getEndpoint(), clientCertificateBytes);
                    session.setEndpoint(serviceRequest.getEndpoint());
                    session.setSecureChannelId(secureChannelId);
                    session.setSecurityConfiguration(newSecurityConfiguration);
                    logger.debug("Session id={} is now associated with secureChannelId={}", session.getSessionId(), secureChannelId);
                    StatusCode[] results = new StatusCode[clientSoftwareCertificates.size()];
                    Arrays.fill(results, StatusCode.GOOD);
                    ByteString serverNonce = NonceUtil.generateNonce(32);
                    session.setClientAddress(serviceRequest.getClientAddress());
                    session.setLastNonce(serverNonce);
                    session.setLocaleIds(request.getLocaleIds());
                    return new ActivateSessionResponse(serviceRequest.createResponseHeader(), serverNonce, results, new DiagnosticInfo[0]);
                } else {
                    throw new UaException(StatusCodes.Bad_SecurityChecksFailed);
                }
            }
        }
    } else {
        if (secureChannelId != session.getSecureChannelId()) {
            throw new UaException(StatusCodes.Bad_SecurityChecksFailed);
        }
        verifyClientSignature(session, request);
        UserIdentityToken identityToken = decodeIdentityToken(request.getUserIdentityToken(), session.getEndpoint().getUserIdentityTokens());
        Object identityObject = validateIdentityToken(session, identityToken, request.getUserTokenSignature());
        createdSessions.remove(authToken);
        activeSessions.put(authToken, session);
        StatusCode[] results = new StatusCode[clientSoftwareCertificates.size()];
        Arrays.fill(results, StatusCode.GOOD);
        ByteString serverNonce = NonceUtil.generateNonce(32);
        session.setClientAddress(serviceRequest.getClientAddress());
        session.setIdentityObject(identityObject, identityToken);
        session.setLocaleIds(request.getLocaleIds());
        session.setLastNonce(serverNonce);
        return new ActivateSessionResponse(serviceRequest.createResponseHeader(), serverNonce, results, new DiagnosticInfo[0]);
    }
}
Also used : ActivateSessionRequest(org.eclipse.milo.opcua.stack.core.types.structured.ActivateSessionRequest) UaException(org.eclipse.milo.opcua.stack.core.UaException) ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString) StatusCode(org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode) NodeId(org.eclipse.milo.opcua.stack.core.types.builtin.NodeId) SignedSoftwareCertificate(org.eclipse.milo.opcua.stack.core.types.structured.SignedSoftwareCertificate) ExtensionObject(org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject) UserIdentityToken(org.eclipse.milo.opcua.stack.core.types.structured.UserIdentityToken) ActivateSessionResponse(org.eclipse.milo.opcua.stack.core.types.structured.ActivateSessionResponse)

Example 2 with SignedSoftwareCertificate

use of org.eclipse.milo.opcua.stack.core.types.structured.SignedSoftwareCertificate in project milo by eclipse.

the class SessionManager method createSession.

private CreateSessionResponse createSession(ServiceRequest serviceRequest) throws UaException {
    CreateSessionRequest request = (CreateSessionRequest) serviceRequest.getRequest();
    long maxSessionCount = server.getConfig().getLimits().getMaxSessionCount().longValue();
    if (createdSessions.size() + activeSessions.size() >= maxSessionCount) {
        throw new UaException(StatusCodes.Bad_TooManySessions);
    }
    ByteString serverNonce = NonceUtil.generateNonce(32);
    NodeId authenticationToken = new NodeId(0, NonceUtil.generateNonce(32));
    long maxRequestMessageSize = serviceRequest.getServer().getConfig().getEncodingLimits().getMaxMessageSize();
    double revisedSessionTimeout = Math.max(5000, Math.min(server.getConfig().getLimits().getMaxSessionTimeout(), request.getRequestedSessionTimeout()));
    ApplicationDescription clientDescription = request.getClientDescription();
    long secureChannelId = serviceRequest.getSecureChannelId();
    EndpointDescription endpoint = serviceRequest.getEndpoint();
    SecurityPolicy securityPolicy = SecurityPolicy.fromUri(endpoint.getSecurityPolicyUri());
    EndpointDescription[] serverEndpoints = server.getEndpointDescriptions().stream().filter(ed -> !ed.getEndpointUrl().endsWith("/discovery")).filter(ed -> endpointMatchesUrl(ed, request.getEndpointUrl())).filter(ed -> Objects.equal(endpoint.getTransportProfileUri(), ed.getTransportProfileUri())).map(SessionManager::stripNonEssentialFields).toArray(EndpointDescription[]::new);
    if (serverEndpoints.length == 0) {
        // GetEndpoints in UaStackServer returns *all* endpoints regardless of a hostname
        // match in the endpoint URL if the result after filtering is 0 endpoints. Do the
        // same here.
        serverEndpoints = server.getEndpointDescriptions().stream().filter(ed -> !ed.getEndpointUrl().endsWith("/discovery")).filter(ed -> Objects.equal(endpoint.getTransportProfileUri(), ed.getTransportProfileUri())).map(SessionManager::stripNonEssentialFields).toArray(EndpointDescription[]::new);
    }
    ByteString clientNonce = request.getClientNonce();
    if (securityPolicy != SecurityPolicy.None) {
        NonceUtil.validateNonce(clientNonce);
        if (clientNonces.contains(clientNonce)) {
            throw new UaException(StatusCodes.Bad_NonceInvalid);
        }
    }
    if (securityPolicy != SecurityPolicy.None && clientNonce.isNotNull()) {
        clientNonces.add(clientNonce);
        while (clientNonces.size() > 64) {
            clientNonces.remove(0);
        }
    }
    ByteString clientCertificateBytes = request.getClientCertificate();
    if (securityPolicy != SecurityPolicy.None && serviceRequest.getClientCertificateBytes() != null) {
        if (!Objects.equal(clientCertificateBytes, serviceRequest.getClientCertificateBytes())) {
            throw new UaException(StatusCodes.Bad_SecurityChecksFailed, "certificate used to open secure channel " + "differs from certificate used to create session");
        }
    }
    SecurityConfiguration securityConfiguration = createSecurityConfiguration(endpoint, clientCertificateBytes);
    if (securityPolicy != SecurityPolicy.None) {
        X509Certificate clientCertificate = securityConfiguration.getClientCertificate();
        List<X509Certificate> clientCertificateChain = securityConfiguration.getClientCertificateChain();
        if (clientCertificate == null || clientCertificateChain == null) {
            throw new UaException(StatusCodes.Bad_SecurityChecksFailed, "client certificate must be non-null");
        }
        ServerCertificateValidator certificateValidator = server.getConfig().getCertificateValidator();
        certificateValidator.validateCertificateChain(clientCertificateChain, clientDescription.getApplicationUri());
    }
    // SignatureData must be created using only the bytes of the client
    // leaf certificate, not the bytes of the client certificate chain.
    SignatureData serverSignature = getServerSignature(securityPolicy, securityConfiguration.getKeyPair(), clientNonce, securityConfiguration.getClientCertificateBytes());
    NodeId sessionId = new NodeId(1, "Session:" + UUID.randomUUID());
    String sessionName = request.getSessionName();
    Duration sessionTimeout = Duration.ofMillis(DoubleMath.roundToLong(revisedSessionTimeout, RoundingMode.UP));
    Session session = new Session(server, sessionId, sessionName, sessionTimeout, clientDescription, request.getServerUri(), request.getMaxResponseMessageSize(), endpoint, secureChannelId, securityConfiguration);
    session.setLastNonce(serverNonce);
    session.addLifecycleListener((s, remove) -> {
        createdSessions.remove(authenticationToken);
        activeSessions.remove(authenticationToken);
        sessionListeners.forEach(l -> l.onSessionClosed(s));
    });
    createdSessions.put(authenticationToken, session);
    sessionListeners.forEach(l -> l.onSessionCreated(session));
    return new CreateSessionResponse(serviceRequest.createResponseHeader(), sessionId, authenticationToken, revisedSessionTimeout, serverNonce, endpoint.getServerCertificate(), serverEndpoints, new SignedSoftwareCertificate[0], serverSignature, uint(maxRequestMessageSize));
}
Also used : X509Certificate(java.security.cert.X509Certificate) KeyPair(java.security.KeyPair) SignedSoftwareCertificate(org.eclipse.milo.opcua.stack.core.types.structured.SignedSoftwareCertificate) MonitoredItemServiceSet(org.eclipse.milo.opcua.stack.server.services.MonitoredItemServiceSet) DigestUtil.sha1(org.eclipse.milo.opcua.stack.core.util.DigestUtil.sha1) Arrays(java.util.Arrays) ApplicationType(org.eclipse.milo.opcua.stack.core.types.enumerated.ApplicationType) ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString) LoggerFactory(org.slf4j.LoggerFactory) ExtensionObject(org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject) ByteBuffer(java.nio.ByteBuffer) UserIdentityToken(org.eclipse.milo.opcua.stack.core.types.structured.UserIdentityToken) AttributeServiceSet(org.eclipse.milo.opcua.stack.server.services.AttributeServiceSet) SecurityAlgorithm(org.eclipse.milo.opcua.stack.core.security.SecurityAlgorithm) Unsigned.uint(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint) Duration(java.time.Duration) Map(java.util.Map) NodeManagementServiceSet(org.eclipse.milo.opcua.stack.server.services.NodeManagementServiceSet) Objects(com.google.common.base.Objects) ServiceAttributes(org.eclipse.milo.opcua.sdk.server.services.ServiceAttributes) CertificateUtil(org.eclipse.milo.opcua.stack.core.util.CertificateUtil) RoundingMode(java.math.RoundingMode) CreateSessionRequest(org.eclipse.milo.opcua.stack.core.types.structured.CreateSessionRequest) ActivateSessionRequest(org.eclipse.milo.opcua.stack.core.types.structured.ActivateSessionRequest) ServerDiagnosticsSummary(org.eclipse.milo.opcua.sdk.server.diagnostics.ServerDiagnosticsSummary) NodeId(org.eclipse.milo.opcua.stack.core.types.builtin.NodeId) UUID(java.util.UUID) Bytes(com.google.common.primitives.Bytes) DiagnosticInfo(org.eclipse.milo.opcua.stack.core.types.builtin.DiagnosticInfo) ActivateSessionResponse(org.eclipse.milo.opcua.stack.core.types.structured.ActivateSessionResponse) Nullable(org.jetbrains.annotations.Nullable) List(java.util.List) StatusCode(org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode) CloseSessionResponse(org.eclipse.milo.opcua.stack.core.types.structured.CloseSessionResponse) Optional(java.util.Optional) NotNull(org.jetbrains.annotations.NotNull) EndpointUtil(org.eclipse.milo.opcua.stack.core.util.EndpointUtil) SubscriptionServiceSet(org.eclipse.milo.opcua.stack.server.services.SubscriptionServiceSet) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) CloseSessionRequest(org.eclipse.milo.opcua.stack.core.types.structured.CloseSessionRequest) ViewServiceSet(org.eclipse.milo.opcua.stack.server.services.ViewServiceSet) UserTokenPolicy(org.eclipse.milo.opcua.stack.core.types.structured.UserTokenPolicy) UaRuntimeException(org.eclipse.milo.opcua.stack.core.UaRuntimeException) Strings.nullToEmpty(com.google.common.base.Strings.nullToEmpty) IdentityValidator(org.eclipse.milo.opcua.sdk.server.identity.IdentityValidator) CreateSessionResponse(org.eclipse.milo.opcua.stack.core.types.structured.CreateSessionResponse) ArrayList(java.util.ArrayList) Lists(com.google.common.collect.Lists) ServiceRequest(org.eclipse.milo.opcua.stack.server.services.ServiceRequest) EndpointDescription(org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription) ServerCertificateValidator(org.eclipse.milo.opcua.stack.server.security.ServerCertificateValidator) MethodServiceSet(org.eclipse.milo.opcua.stack.server.services.MethodServiceSet) ConversionUtil.l(org.eclipse.milo.opcua.stack.core.util.ConversionUtil.l) MessageSecurityMode(org.eclipse.milo.opcua.stack.core.types.enumerated.MessageSecurityMode) SignatureData(org.eclipse.milo.opcua.stack.core.types.structured.SignatureData) AttributeHistoryServiceSet(org.eclipse.milo.opcua.stack.server.services.AttributeHistoryServiceSet) SecurityPolicy(org.eclipse.milo.opcua.stack.core.security.SecurityPolicy) QueryServiceSet(org.eclipse.milo.opcua.stack.server.services.QueryServiceSet) DoubleMath(com.google.common.math.DoubleMath) StatusCodes(org.eclipse.milo.opcua.stack.core.StatusCodes) SignatureUtil(org.eclipse.milo.opcua.stack.core.util.SignatureUtil) Lists.newCopyOnWriteArrayList(com.google.common.collect.Lists.newCopyOnWriteArrayList) Logger(org.slf4j.Logger) UInteger(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger) AnonymousIdentityToken(org.eclipse.milo.opcua.stack.core.types.structured.AnonymousIdentityToken) UserTokenType(org.eclipse.milo.opcua.stack.core.types.enumerated.UserTokenType) SessionServiceSet(org.eclipse.milo.opcua.stack.server.services.SessionServiceSet) Maps(com.google.common.collect.Maps) NonceUtil(org.eclipse.milo.opcua.stack.core.util.NonceUtil) ApplicationDescription(org.eclipse.milo.opcua.stack.core.types.structured.ApplicationDescription) UaException(org.eclipse.milo.opcua.stack.core.UaException) UaException(org.eclipse.milo.opcua.stack.core.UaException) ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString) Duration(java.time.Duration) EndpointDescription(org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription) ByteString(org.eclipse.milo.opcua.stack.core.types.builtin.ByteString) ApplicationDescription(org.eclipse.milo.opcua.stack.core.types.structured.ApplicationDescription) X509Certificate(java.security.cert.X509Certificate) SignatureData(org.eclipse.milo.opcua.stack.core.types.structured.SignatureData) ServerCertificateValidator(org.eclipse.milo.opcua.stack.server.security.ServerCertificateValidator) CreateSessionRequest(org.eclipse.milo.opcua.stack.core.types.structured.CreateSessionRequest) CreateSessionResponse(org.eclipse.milo.opcua.stack.core.types.structured.CreateSessionResponse) SecurityPolicy(org.eclipse.milo.opcua.stack.core.security.SecurityPolicy) NodeId(org.eclipse.milo.opcua.stack.core.types.builtin.NodeId)

Aggregations

UaException (org.eclipse.milo.opcua.stack.core.UaException)2 ByteString (org.eclipse.milo.opcua.stack.core.types.builtin.ByteString)2 ExtensionObject (org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject)2 NodeId (org.eclipse.milo.opcua.stack.core.types.builtin.NodeId)2 StatusCode (org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode)2 ActivateSessionRequest (org.eclipse.milo.opcua.stack.core.types.structured.ActivateSessionRequest)2 ActivateSessionResponse (org.eclipse.milo.opcua.stack.core.types.structured.ActivateSessionResponse)2 SignedSoftwareCertificate (org.eclipse.milo.opcua.stack.core.types.structured.SignedSoftwareCertificate)2 UserIdentityToken (org.eclipse.milo.opcua.stack.core.types.structured.UserIdentityToken)2 Objects (com.google.common.base.Objects)1 Strings.nullToEmpty (com.google.common.base.Strings.nullToEmpty)1 Lists (com.google.common.collect.Lists)1 Lists.newCopyOnWriteArrayList (com.google.common.collect.Lists.newCopyOnWriteArrayList)1 Maps (com.google.common.collect.Maps)1 DoubleMath (com.google.common.math.DoubleMath)1 Bytes (com.google.common.primitives.Bytes)1 RoundingMode (java.math.RoundingMode)1 ByteBuffer (java.nio.ByteBuffer)1 KeyPair (java.security.KeyPair)1 X509Certificate (java.security.cert.X509Certificate)1