Opc.Ua.Server.StandardServer.CreateSession C# (CSharp) Method

CreateSession() public method

Invokes the CreateSession service.
public CreateSession ( RequestHeader requestHeader, ApplicationDescription clientDescription, string serverUri, string endpointUrl, string sessionName, byte clientNonce, byte clientCertificate, double requestedSessionTimeout, uint maxResponseMessageSize, NodeId &sessionId, NodeId &authenticationToken, double &revisedSessionTimeout, byte &serverNonce, byte &serverCertificate, EndpointDescriptionCollection &serverEndpoints, SignedSoftwareCertificateCollection &serverSoftwareCertificates, SignatureData &serverSignature, uint &maxRequestMessageSize ) : ResponseHeader
requestHeader RequestHeader The request header.
clientDescription ApplicationDescription Application description for the client application.
serverUri string The server URI.
endpointUrl string The endpoint URL.
sessionName string Name for the Session assigned by the client.
clientNonce byte The client nonce.
clientCertificate byte The client certificate.
requestedSessionTimeout double The requested session timeout.
maxResponseMessageSize uint Size of the max response message.
sessionId NodeId The unique public identifier assigned by the Server to the Session.
authenticationToken NodeId The unique private identifier assigned by the Server to the Session.
revisedSessionTimeout double The revised session timeout.
serverNonce byte The server nonce.
serverCertificate byte The server certificate.
serverEndpoints EndpointDescriptionCollection The server endpoints.
serverSoftwareCertificates SignedSoftwareCertificateCollection The server software certificates.
serverSignature SignatureData The server signature.
maxRequestMessageSize uint Size of the max request message.
return ResponseHeader
        public override ResponseHeader CreateSession(
            RequestHeader                           requestHeader,
            ApplicationDescription                  clientDescription,
            string                                  serverUri,
            string                                  endpointUrl,
            string                                  sessionName,
            byte[]                                  clientNonce,
            byte[]                                  clientCertificate,
            double                                  requestedSessionTimeout,
            uint                                    maxResponseMessageSize,
            out NodeId                              sessionId,
            out NodeId                              authenticationToken,
            out double                              revisedSessionTimeout,
            out byte[]                              serverNonce,
            out byte[]                              serverCertificate,
            out EndpointDescriptionCollection       serverEndpoints,
            out SignedSoftwareCertificateCollection serverSoftwareCertificates,
            out SignatureData                       serverSignature,
            out uint                                maxRequestMessageSize)
        {       
            sessionId = 0;
            revisedSessionTimeout = 0;
            serverNonce = null;
            serverCertificate = null;
            serverSoftwareCertificates = null;
            serverSignature = null;
            maxRequestMessageSize = (uint)MessageContext.MaxMessageSize;

            OperationContext context = ValidateRequest(requestHeader, RequestType.CreateSession);
        
            try
            {
                // check the server uri.
                if (!String.IsNullOrEmpty(serverUri))
                {
                    if (serverUri != this.Configuration.ApplicationUri)
                    {
                        throw new ServiceResultException(StatusCodes.BadServerUriInvalid);
                    }
                }

                bool requireEncryption = ServerBase.RequireEncryption(context.ChannelContext.EndpointDescription);

                if (!requireEncryption && clientCertificate != null)
                {
                    requireEncryption = true;
                }

                // validate client application instance certificate.
                X509Certificate2 parsedClientCertificate = null;

                if (requireEncryption && clientCertificate != null && clientCertificate.Length > 0)
                {
                    try
                    {
                        parsedClientCertificate = CertificateFactory.Create(clientCertificate, true);

                        if (context.SecurityPolicyUri != SecurityPolicies.None)
                        {
                            string certificateApplicationUri = Utils.GetApplicationUriFromCertficate(parsedClientCertificate);

                            // verify if applicationUri from ApplicationDescription matches the applicationUri in the client certificate.
                            if (!String.IsNullOrEmpty(certificateApplicationUri) &&
                                !String.IsNullOrEmpty(clientDescription.ApplicationUri) &&
                                certificateApplicationUri != clientDescription.ApplicationUri)
                            {
                                throw ServiceResultException.Create(
                                    StatusCodes.BadCertificateUriInvalid,
                                    "The URI specified in the ApplicationDescription does not match the URI in the Certificate.");
                            }

                            CertificateValidator.Validate(parsedClientCertificate);

							/*X509Certificate2Collection clientCertificateChain = Utils.ParseCertificateChainBlob(clientCertificate);
                            CertificateValidator.Validate(clientCertificateChain);
                            parsedClientCertificate = clientCertificateChain[0];*/
                        }
                    }
                    catch (Exception e)
                    {
                        OnApplicationCertificateError(clientCertificate, new ServiceResult(e));
                    }
                }

                // verify the nonce provided by the client.
                if (clientNonce != null)
                {
                    if (clientNonce.Length < m_minNonceLength)
                    {
                        throw new ServiceResultException(StatusCodes.BadNonceInvalid);
                    }
                }

                // create the session.
                Session session = ServerInternal.SessionManager.CreateSession(
                    context,
                    requireEncryption ? InstanceCertificate : null,
                    sessionName,
                    clientNonce,
                    clientDescription,
                    endpointUrl,
                    parsedClientCertificate,
                    requestedSessionTimeout,
                    maxResponseMessageSize,
                    out sessionId,
                    out authenticationToken,
                    out serverNonce,
                    out revisedSessionTimeout);           
                                
                lock (m_lock)
                {                
                    // return the application instance certificate for the server.
                    if (requireEncryption)
                    {
                        serverCertificate = InstanceCertificate.RawData;

                        /*List<byte> certificateChainList = new List<byte>();
                        for (int i = 0; i < InstanceCertificateChain.Count; i++)
                        {
                            certificateChainList.AddRange(InstanceCertificateChain[i].RawData);
                        }
                        serverCertificate = certificateChainList.ToArray();*/
                    }
					//session.ServerCertificateChain = serverCertificate;
                                 
                    // return the endpoints supported by the server.
                    serverEndpoints = GetEndpointDescriptions(endpointUrl, BaseAddresses, null);

                    // return the software certificates assigned to the server.
                    serverSoftwareCertificates = new SignedSoftwareCertificateCollection(ServerProperties.SoftwareCertificates);
                    
                    // sign the nonce provided by the client.
                    serverSignature = null;
                    
                    //  sign the client nonce (if provided).
                    if (parsedClientCertificate != null && clientNonce != null)
                    {
                        byte[] dataToSign = Utils.Append(clientCertificate, clientNonce);
                        serverSignature = SecurityPolicies.Sign(InstanceCertificate, context.SecurityPolicyUri, dataToSign);
                    }
                }

                lock (ServerInternal.DiagnosticsLock)
                {
                    ServerInternal.ServerDiagnostics.CurrentSessionCount++;
                    ServerInternal.ServerDiagnostics.CumulatedSessionCount++;
                }

                Utils.Trace("Server - SESSION CREATED. SessionId={0}", sessionId);

                return CreateResponse(requestHeader, StatusCodes.Good);
            }
            catch (ServiceResultException e)
            {
                Utils.Trace("Server - SESSION CREATE failed. {0}", e.Message);

                lock (ServerInternal.DiagnosticsLock)
                {
                    ServerInternal.ServerDiagnostics.RejectedSessionCount++;
                    ServerInternal.ServerDiagnostics.RejectedRequestsCount++;

                    if (IsSecurityError(e.StatusCode))
                    {
                        ServerInternal.ServerDiagnostics.SecurityRejectedSessionCount++;
                        ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++;
                    }
                }

                throw TranslateException((DiagnosticsMasks)requestHeader.ReturnDiagnostics, new StringCollection(), e);
            }  
            finally
            {
                OnRequestComplete(context);
            }
        }