Conexão segura com a comunicação remota holográfica e a API do OpenXR

Ao usar a API OpenXR, toda a API relacionada à conexão segura está disponível como parte da XR_MSFT_holographic_remoting extensão OpenXR.

Importante

Para saber mais sobre a API de extensão OpenXR de Comunicação Remota Holográfica, marcar a especificação que pode ser encontrada no repositório github de exemplos de Comunicação Remota Holográfica.

Lembre-se de que você precisa implementar aplicativos remotos e de player personalizados se quiser habilitar a segurança da conexão. Ambos os aplicativos personalizados precisam:

  • Um provedor de certificados e um validador de autenticação se o aplicativo for executado como o servidor.
  • Um provedor de autenticação e um validador de certificado se o aplicativo for executado como o cliente.

A API do OpenXR é semelhante à API de Windows Mixed Reality descrita aqui. No entanto, em vez de implementar interfaces, os principais elementos para conexão segura usando a XR_MSFT_holographic_remoting extensão OpenXR são os seguintes retornos de chamada:

  • xrRemotingRequestAuthenticationTokenCallbackMSFT, gera ou recupera o token de autenticação a ser enviado.
  • xrRemotingValidateServerCertificateCallbackMSFT, valida a cadeia de certificados.
  • xrRemotingValidateAuthenticationTokenCallbackMSFT, valida o token de autenticação do cliente.
  • xrRemotingRequestServerCertificateCallbackMSFT, forneça ao aplicativo de servidor o certificado a ser usado.

Observação

Com a Comunicação Remota Holográfica, é possível que o Player ou o Remoto seja o servidor dependendo de suas necessidades (para obter mais informações, consulte Terminologia de Comunicação Remota Holográfica). Se o aplicativo personalizado do player remoto ou personalizado puder ser executado como cliente e servidor, o aplicativo precisará fornecer todos os quatro retornos de chamada.

Os retornos de chamada podem ser fornecidos para o runtime do OpenXR de comunicação remota por meio de xrRemotingSetSecureConnectionClientCallbacksMSFT e xrRemotingSetSecureConnectionServerCallbacksMSFT. Para fazer isso, você pode criar funções estáticas para os retornos de chamada:

class SecureConnectionCallbacks {
public:
    ...

    // Static callbacks
    static XrResult XRAPI_CALL
    RequestAuthenticationTokenStaticCallback(XrRemotingAuthenticationTokenRequestMSFT* authenticationTokenRequest) {
        if (!authenticationTokenRequest->context) {
            return XR_ERROR_RUNTIME_FAILURE;
        }
        return reinterpret_cast<SecureConnectionCallbacks*>(authenticationTokenRequest->context)
            ->RequestAuthenticationToken(authenticationTokenRequest);
    }

    static XrResult XRAPI_CALL
    ValidateServerCertificateStaticCallback(XrRemotingServerCertificateValidationMSFT* serverCertificateValidation) {
        if (!serverCertificateValidation->context) {
            return XR_ERROR_RUNTIME_FAILURE;
        }
        return reinterpret_cast<SecureConnectionCallbacks*>(serverCertificateValidation->context)
            ->ValidateServerCertificate(serverCertificateValidation);
    }

    static XrResult XRAPI_CALL
    ValidateAuthenticationTokenStaticCallback(XrRemotingAuthenticationTokenValidationMSFT* authenticationTokenValidation) {
        if (!authenticationTokenValidation->context) {
            return XR_ERROR_RUNTIME_FAILURE;
        }
        return reinterpret_cast<SecureConnectionCallbacks*>(authenticationTokenValidation->context)
            ->ValidateAuthenticationToken(authenticationTokenValidation);
    }

    static XrResult XRAPI_CALL
    RequestServerCertificateStaticCallback(XrRemotingServerCertificateRequestMSFT* serverCertificateRequest) {
        if (!serverCertificateRequest->context) {
            return XR_ERROR_RUNTIME_FAILURE;
        }
        return reinterpret_cast<SecureConnectionCallbacks*>(serverCertificateRequest->context)
            ->RequestServerCertificate(serverCertificateRequest);
    }
}

Todas as funções de retorno de chamada estáticas são semelhantes e, no exemplo acima, elas apenas chamam uma função no objeto de contexto, que é definido em xrRemotingSetSecureConnectionClientCallbacksMSFT ou xrRemotingSetSecureConnectionServerCallbacksMSFT. A implementação real dos retornos de chamada é feita dentro das funções membro do objeto de contexto:

class SecureConnectionCallbacks {   
    ...

private:
    // The client has to provide a token and has to validate the certificate.
    XrResult RequestAuthenticationToken(XrRemotingAuthenticationTokenRequestMSFT* authenticationTokenRequest) {
        // To provide a token fill out the authenticationTokenRequest with your token.
    }
    XrResult ValidateServerCertificate(XrRemotingServerCertificateValidationMSFT* serverCertificateValidation) {
        // Validate the certificate.
    }

    // The server has to provide a certificate and hast to validate the token.
    XrResult ValidateAuthenticationToken(XrRemotingAuthenticationTokenValidationMSFT* authenticationTokenValidation) {
        // Validate the token.
    }
    XrResult RequestServerCertificate(XrRemotingServerCertificateRequestMSFT* serverCertificateRequest) {
        // To provide a certificate fill out the serverCertificateRequest with your certificate.
    }
}

Agora você pode fornecer os retornos de chamada para xrRemotingSetSecureConnectionClientCallbacksMSFT e xrRemotingSetSecureConnectionServerCallbacksMSFT. Além disso, a conexão segura precisa ser habilitada por meio do parâmetro secureConnection na XrRemotingConnectInfoMSFT estrutura ou na XrRemotingListenInfoMSFT estrutura, dependendo se você estiver usando xrRemotingConnectMSFT ou xrRemotingListenMSFT:

...

SecureConnectionCallbacks callbackObject;

...

if (client) 
{
    XrRemotingSecureConnectionClientCallbacksMSFT clientCallbacks{static_cast<XrStructureType>(XR_TYPE_REMOTING_SECURE_CONNECTION_CLIENT_CALLBACKS_MSFT);
    clientCallbacks.context = &callbackObject;
    clientCallbacks.requestAuthenticationTokenCallback = SecureConnectionCallbacks::RequestAuthenticationTokenStaticCallback;
    clientCallbacks.validateServerCertificateCallback = SecureConnectionCallbacks::ValidateServerCertificateStaticCallback;
    clientCallbacks.performSystemValidation = true;
    CHECK_XRCMD(m_extensions.xrRemotingSetSecureConnectionClientCallbacksMSFT(m_instance.Get(), m_systemId, &clientCallbacks));
    
    ...

    connectInfo.secureConnection = true; // Enable secure connection!
    CHECK_XRCMD(m_extensions.xrRemotingConnectMSFT(m_instance.Get(), m_systemId, &connectInfo));
}

if (server) 
{
    XrRemotingSecureConnectionServerCallbacksMSFT serverCallbacks{static_cast<XrStructureType>(XR_TYPE_REMOTING_SECURE_CONNECTION_SERVER_CALLBACKS_MSFT);
    serverCallbacks.context = &callbackObject;
    serverCallbacks.requestServerCertificateCallback = SecureConnectionCallbacks::RequestServerCertificateStaticCallback;
    serverCallbacks.validateAuthenticationTokenCallback = SecureConnectionCallbacks::ValidateAuthenticationTokenStaticCallback;
    serverCallbacks.authenticationRealm = /*YourAuthenticationRealm*/;
    CHECK_XRCMD(m_extensions.xrRemotingSetSecureConnectionServerCallbacksMSFT(m_instance.Get(), m_systemId, &serverCallbacks));

    ...

    listenInfo.secureConnection = true; // Enable secure connection!
    CHECK_XRCMD(m_extensions.xrRemotingListenMSFT(m_instance.Get(), m_systemId, &listenInfo));
}

Observação

Você pode encontrar um exemplo detalhado no aplicativo de exemplo OpenXR.

Consulte Também