Search in sources :

Example 1 with ServerCertificateValidator

use of org.eclipse.milo.opcua.stack.server.security.ServerCertificateValidator 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

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 Duration (java.time.Duration)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 List (java.util.List)1 Map (java.util.Map)1 Optional (java.util.Optional)1 UUID (java.util.UUID)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 ServerDiagnosticsSummary (org.eclipse.milo.opcua.sdk.server.diagnostics.ServerDiagnosticsSummary)1