@ohos/xmpp_starttls

Introduction

Based on the open source software @xmpp/starttls, this project uses TypeScript to implement similar capabilities. It provides OpenHarmony with a library for establishing encrypted TLS connections with the Extensible Messaging and Presence Protocol (XMPP) server.

Supported Features

  • Transport Layer Security (TLS) handshake: enables TLS encryption in XMPP connections to ensure secure communication.
  • Automatic STARTTLS: automatically checks whether the server supports STARTTLS for conditionally secure connection.
  • Error handling: captures and handles errors and exceptions that may occur during STARTTLS.

How to Install

  1. Install an OpenHarmony HAR.

  2. Run the installation command:

     ohpm install @ohos/xmpp_starttls
    

Available APIs

APIs

Name Parameter Description
negotiate(entity) entity: an object that contains various information and methods required for communicating with the XMPP server, such as the capabilities of sending and receiving XML nodes. Negotiates with the XMPP server about whether a STARTTLS HANDSHAKE can be performed.
starttls({ streamFeatures }) { streamFeatures }: an object that contains the stream features of the current XMPP connection, such as the authentication method and encryption options. Processes the STARTTLS feature in XMPP streams.
canUpgrade(socket) socket: the current network socket object. Checks whether the current network socket supports an upgrade to TLS.
upgrade(service) service: a service object that may contain the information and methods required for upgrading to TLS. Upgrades a network socket to a TLS connection.

Example

import { xml, jid, Client as ClientCore } from "@ohos/xmpp_client_core";
import { getDomain } from "./src/main/client/lib/getDomain";
import _reconnect from "@ohos/xmpp_reconnect";
import _websocket from "@ohos/xmpp_websocket";
import _tcp from "@ohos/xmpp_tcp";
import _tls from "@ohos/xmpp_tls";
import _middleware from "@ohos/xmpp_middleware";
import _streamFeatures from "@ohos/xmpp_stream_features";
import _iqCaller from "@ohos/xmpp_iq/src/main/lib/caller";
import _iqCallee from "@ohos/xmpp_iq/src/main/lib/callee";
import _resolve from "@ohos/xmpp_resolve";
// Stream features - order matters and define priority
import _starttls from "@ohos/xmpp_starttls";
import _sasl from "@ohos/xmpp_sasl";
import _resourceBinding from "@ohos/xmpp_resource_binding";
import _sessionEstablishment from "@ohos/xmpp_session_establishment";
import _streamManagement from "@ohos/xmpp_stream_management";
// SASL mechanisms - order matters and define priority
import plain from "@ohos/xmpp_sasl_plain";
import scramsha1 from "@ohos/xmpp_sasl_scram_sha_1";
import anonymous from "@ohos/xmpp_sasl_anonymous";
function client(options = {}) {
    const { resource, credentials, username, password, ...params } = options;
    const { domain, service, caPath } = params;
    if (!domain && service) {
        params.domain = getDomain(service);
    }
    const entity = new ClientCore(params);
    const reconnect = _reconnect({ entity });
    const websocket = _websocket({ entity });
    const tcp = _tcp({ entity });
    const tls = _tls({ entity });
    const middleware = _middleware({ entity });
    const streamFeatures = _streamFeatures({ middleware });
    const iqCaller = _iqCaller({ middleware, entity });
    const iqCallee = _iqCallee({ middleware, entity });
    const resolve = _resolve({ entity });
    // Stream features - order matters and define priority
    const starttls = _starttls({ streamFeatures });
    const sasl = _sasl({ streamFeatures }, credentials || { username, password });
    const streamManagement = _streamManagement({
        streamFeatures,
        entity,
        middleware,
    });
    const resourceBinding = _resourceBinding(
        { iqCaller, streamFeatures },
        resource,
    );
    const sessionEstablishment = _sessionEstablishment({
        iqCaller,
        streamFeatures,
    });
    // SASL mechanisms - order matters and define priority
    const mechanisms = Object.entries({
        scramsha1,
        plain,
        anonymous,
    }).map(([k, v]) => ({ [k]: v(sasl) }));
    return Object.assign(entity, {
        entity,
        reconnect,
        tcp,
        websocket,
        tls,
        middleware,
        streamFeatures,
        iqCaller,
        iqCallee,
        resolve,
        starttls,
        sasl,
        resourceBinding,
        sessionEstablishment,
        streamManagement,
        mechanisms,
    });
}
export { xml, jid, client };
// STARTTLS is used to upgrade a TCP connection to a TLS connection.

How to Use

Registering a Middleware Processing Function on the Stream of the XMPP Connection

// Check whether the socket connection is TCP, and if so, trigger an upgrade to TLS.
function canUpgrade(socket) {
    return socket instanceof TcpSocket && !(socket instanceof TlsSocket)
}
// Create a TLS socket for TCP upgrade.
async function upgrade(service) {
  const tlsSocket = new TlsSocket();
        tlsSocket.connect(service);
  await promise(tlsSocket, "connect");
  return tlsSocket ;
}
async function negotiate(entity) {
  const element = await entity.sendReceive(xml("starttls", { xmlns: NS }));
  if (element.is("proceed", NS)) {
    return element;
  }
  throw new Error("STARTTLS_FAILURE");
}
export default function starttls({ streamFeatures }) {
  return streamFeatures.use("starttls", NS, async ({ entity }, next) => {
    const { socket, options } = entity;
    if (!canUpgrade(socket)) {
      return next();
    }
    await negotiate(entity);
    const tlsSocket = await upgrade(entity.service);
    entity._attachSocket(tlsSocket);
	// Restart the service after the upgrade is complete.
    await entity.restart();
  });
};

About obfuscation

  • Code obfuscation, please seeCode Obfuscation
  • If you want the xmpp_starttls library not to be obfuscated during code obfuscation, you need to add corresponding exclusion rules in the obfuscation rule configuration file obfuscation-rules.txt:
-keep
./oh_modules/@ohos/xmpp_starttls

Constraints

This project has been verified in the following version:

DevEco Studio: 5.0.3.200, OpenHarmony SDK: API 12 (5.0.0.21-Canary2)

Directory Structure

|---- @ohos/xmpp_starttls
|     |---- entry  # Sample code
|           |---- src  
|                   |---- main  # Sample code
|                   |---- ohosTest  # xts code
|     |---- library  # @ohos/xmpp_starttls library folder
|           |---- ets
|                 |---- lib  # Main dependencies
|                 |---- types  # External APIs
|           |---- index.js  # Main entry file
|           |---- index.d.ts  # Main declaration file of the external APIs
|     |---- README.md  # Readme
|     |---- README_zh.md  # Readme                   

How to Contribute

If you find any problem during the use, submit an issue or PR.

License

This project is licensed under the terms of the ISC license.