diff --git a/docs/about/index.html b/docs/about/index.html index 61ba4a9..056f55b 100644 --- a/docs/about/index.html +++ b/docs/about/index.html @@ -12,7 +12,7 @@ about | oddsquat - + @@ -65,7 +65,7 @@

- I'm a front-end developer and a big fan of open-source, + I’m a front-end developer and a big fan of open-source, customization, and minimalist software.
Member of the BadBar crew, diff --git a/docs/index.html b/docs/index.html index 5f58231..4ed9a45 100644 --- a/docs/index.html +++ b/docs/index.html @@ -12,7 +12,7 @@ oddsquat - + diff --git a/docs/lost+found/index.html b/docs/lost+found/index.html index 875d5fb..ddf724a 100644 --- a/docs/lost+found/index.html +++ b/docs/lost+found/index.html @@ -238,7 +238,7 @@ and so requires manual intervention by the user.

Interactive articles about physics, math, and engineering. - It's probably the best website on the entire internet.
+ It’s probably the best website on the entire internet.
My favorite post is the one about bicycles.
@@ -283,7 +283,7 @@ and so requires manual intervention by the user.

Torrenting can leave traces.
Check torrent downloads and distributions - for your own or your neighbor's IP address. + for your own or your neighbor’s IP address.
@@ -338,7 +338,7 @@ and so requires manual intervention by the user.

- Ask HN: Programmers who don't use autocomplete/LSP, how do you do it? + Ask HN: Programmers who don’t use autocomplete/LSP, how do you do it?
@@ -352,7 +352,7 @@ and so requires manual intervention by the user.

- Your Computer Isn't Yours + Your Computer Isn’t Yours
@@ -449,7 +449,7 @@ and so requires manual intervention by the user.

- Most software tutorials suck. Here's how to make one that doesn't. + Most software tutorials suck. Here’s how to make one that doesn’t.
diff --git a/docs/posts/2026/encrypted_XMPP/index.html b/docs/posts/2026/encrypted_XMPP/index.html new file mode 100644 index 0000000..12f7e6b --- /dev/null +++ b/docs/posts/2026/encrypted_XMPP/index.html @@ -0,0 +1,427 @@ + + + + + + + + + + + encrypted XMPP | oddsquat + + + + + + + + + + + + + + + +
+
+
+
+ + +
+ +
+ +
+
+

End-to-End Encryption in XMPP with OMEMO

+

I find it funny that twenty years ago I was already trying +to get people to switch to XMPP.

+

For a long time, ICQ was extremely popular around me, +but the proprietary messenger kept breaking things for people +using alternative clients, which was quite annoying. +After yet another round of this pointless battle +I realized clearly that I prefer protocols over services.

+

I didn’t have much success back then, +but fortunately, XMPP (and I hope I have too) +has continued moving forward over the past two decades. +It has developed slowly, sometimes awkwardly, but steadily.

+

Here, I won’t talk about why XMPP is great or how it works. +You can check + + this guide +(one of many) and I’d rather not write another one. +In this post, +I want to focus specifically on end-to-end encryption +and the practical aspects of using it.

+

Short Glossary

+

End-to-end encryption is a way +to keep your chats truly private.
+Only you and the person you’re messaging can read the messages. +Not even the server owner has the keys +needed to decrypt or modify them.

+

XMPP is an extensible protocol for instant messaging. +It’s open, decentralized, and mature.

+

OMEMO is a widely supported +XMPP Extension Protocol (XEP) +for secure multi-client end-to-end encryption. +You can read more about +it on a dedicated page by Daniel Gultsch.

+

Client, in this post, +means a specific instance +of an XMPP application on a user device. +
OMEMO-related documentation uses the term Device, +but I find it potentially confusing: +in practice, a single physical device +can run multiple independent clients.

+

Basic Concepts

+

This section introduces some basics of end-to-end encryption.

+

If you’re already familiar with the concepts and terminology, +you can skip ahead to how end-to-end encryption + affects the XMPP user experience, +or jump straight to the step-by-step workflow I personally use.

+

Trade-offs Between Safety and Convenience

+

Unfortunately, things that are truly secure are rarely convenient. +They often require some initial efforts +and a bit of ongoing attention.

+

Telegram, which used to be a benchmark for messenger usability +before its long dive into enshitification, +really draws the line between convenience and security. +Regular chats are easy and flexible, +but “secret” chats come with a full set of limitations: +they’re one-on-one only, +can’t be synced to another device, +aren’t available on desktop at all, +and so on.

+

All commercial so-called “secure” messengers, like Signal or WhatsApp, +end up with pretty similar limitations, +because it’s tricky to make end-to-end encrypted chats +work the way users expect.

+

Luckily, protocols and cryptography don’t care about +convenience or user expectations. +Many XMPP clients let you do almost anything you’re trying to do. +Sometimes it’s clunky and unintuitive, +sometimes it’s the kind of freedom +that lets you shoot yourself in the foot. +At the end of the day, you’d better understand what you’re doing.

+

It might sound messy, but for that price, XMPP actually +gives you a lot of handy features: +your chats are secured with Signal-grade end-to-end encryption, +and you can use as many devices as you want, +all at the same time, +without being tied to any proprietary service.

+

In general, the XMPP experience today +could be described as a “WhatsApp with benefits and frictions”. +It’s kinda ironic, considering that WhatsApp’s protocol +is actually based on XMPP, but incompatibly altered and defederated.

+

Keys, Fingerprints and Trust

+

OMEMO is based on the + Double Ratchet Algorithm. +While the internal details are quite interesting, +for practical purposes it’s enough to know that +each client stores some cryptographic keys +and can derive a hash from them, commonly called a fingerprint.

+

Keys are usually managed automatically by the XMPP client, +and in normal use you should never need to handle them manually. +In fact, you probably don’t even need to know what they look like.

+

A fingerprint lets you identify +a specific client of your contact +and verify that it hasn’t been spoofed. +Fingerprints for an account are not secret: +clients publish their own fingerprints to the XMPP server +and automatically receive the fingerprints of others. +Only fingerprints you explicitly mark as trusted are relevant.

+

In an typical scenario, the contact should confirm in person +or through an already trusted and secure communication channel +that the fingerprint belongs to their device, +and only then you mark it as trusted.

+

The list of trusted fingerprints +is used at the moment a message is sent. +Behind the scenes, +OMEMO performs a certain amount of key management, +and only the clients that are present in the trusted list +at the time of encryption +will be able to decrypt the message later.

+

It’s important to understand +that trust cannot be applied retroactively: +it’s not possible to “extend” trust to new clients +after a message has already been encrypted and sent.

+

+ Practical Aspects of OMEMO and XMPP +

+ +

Chat History

+

In theory, XMPP supports server-side message history storage via +XEP-0313: Message Archive Management.

+

In practice, support for this XEP, +as well as retention policies and message lifetime, +depends on the specific server. +You should never assume that all conversations are stored +indefinitely by default. +From a practical standpoint, +the server-side MAM archive is better considered a cache: +it can help you handle recent messages after a short period offline +or synchronize conversations across multiple devices.

+

At the end of the day, +keeping your chat history is your responsibility, +and this is a good place to apply a local-first approach.

+

Synchronisation

+

Seamless switching between clients is handled by +XEP-0280: Message Carbons. +Before its introduction, only incoming messages were synced between devices, +while your own outgoing messages were not. +Protocol-level mirroring of your own messages +is a rather non-obvious feature :D

+

It’s important to note that with end-to-end encryption, +the concept of trusted fingerprints also applies to your own clients. +For seamless synchronisation of outgoing messages, +all your clients must trust each other’s fingerprints. +A new client, +or an old one that was not trusted +at the time messages were sent, +will receive the full history from MAM +but will not be able to decrypt it. +
Yes, even your own messages.

+

In theory, re-encrypting messages on already trusted clients +could solve this issue, but no XMPP client implements it yet. +So in practice you may need to manually resend +some data to a new device.

+

Message Correction

+

It’s worth keeping in mind that +features that seem simple and straightforward at first glance, +such as message editing and deletion, +actually rely on client-side implementation +and may not behave for your recipient the way you expect.

+

They’re fine to use and are well supported in some clients, +but you shouldn’t rely on them to hide anything.

+

Maintenance

+

OMEMO was designed as a set-it-and-forget-it solution +and mostly succeeds in that goal. +If you have a basic understanding of how the protocol works +and check in online from time to time, +there shouldn’t be any surprises.

+

All maintenance comes down to making regular backups +and notifying your contacts +when fingerprints are added or no longer valid +so they can keep their trust list up to date.

+

Step-by-Step Guide

+

Let’s say I have a XMPP account, me@some.server, +and a few devices: +a phone, a laptop, and a desktop computer. +First I’ll describe my mindset at a high level, +then I’ll add some notes about specific clients.

+

Client Roles

+

On the one hand, I have my phone. +It’s almost always with me and almost always online. +That’s where I keep the full chat history +and get real-time notifications.

+

On the other hand, I have a couple of desktop applications. +I only open them +when I need to discuss something using my keyboard +or share some text between devices. +I like to think of them as satellite clients.

+

Before the Start

+

First, enable OMEMO encryption +on every client if it isn’t enabled by default.

+

The next step is to add +all clients to the trust list on each device: +my phone should trust all my computers, +and my computers should trust each other +as well as my phone.

+

Fingerprints do not have to be secret, +so they can be published on +your website or even on social media profiles. +Here is my page with the fingerprints, for example: +
+ https://oddsquat.org/about/keys/ +

+

Start the Conversation in Person

+

Let’s say I meet Alice, +we start talking, +and then decide to continue the conversation online.

+

I open a special QR code on my phone, +and Alice scans it with her client. +This QR code already contains +the fingerprints of all my devices, +so no extra steps are needed on her phone. +After that, I do the same +and scan her QR code as well.

+

Later at home, +I manually mark her devices as trusted on my computers +using the trusted list on my phone, and she does the same.

+

Now we are both sure +that it is really us in the conversation, +and that all messages will be available +on all our devices and only on them.

+

Start the Conversation Online

+

Let’s say Bob and I start discussing something +on a forum or in the Fediverse, +and then decide to continue the discussion on XMPP.

+

Before starting the chat, +Bob can confirm it’s really me using my page with fingerprints. +I can confirm it’s really him +by asking him to send his fingerprints +in a private message on the same forum or via email.

+

Ideally, Bob also has a public page with his fingerprints. +That way, we can both independently verify +that we are who we say we are.

+

In an alternative scenario, +where there has been no prior communication or public pages +and only a single JID is known, +things play out a bit differently: +Bob starts the chat, +I trust the first device he messages me from, +and then we exchange fingerprints for our other devices, +if we have any. +This approach is called TOFU (Trust On First Use).

+

New or Lost Devices

+

If I start using a new device +or install another client application, +the first thing I do is add it to the list +of trusted clients on my existing devices.

+

If I lose one of my devices +or delete any private keys, +the first thing I do is remove the corresponding client +from the trusted list on my other devices.

+

Once I’ve updated all my personal lists, +I should inform my contacts about changes via trusted channels.

+

I can simply ask Alice to scan +my new QR code the next time we meet, +and send Bob a message introducing +my new client or letting him know +that the lost device is no longer trusted +and that no real messages will ever come from it again.

+

Client Applications

+

This section describes +how OMEMO is used in specific client applications +that I personally use.

+

Conversations and Forks

+

+ Conversations is a modern, +fully featured chat application for Android. +It supports everything a messaging app should support: +chats, voice calls, video calls, and sharing files of any kind.

+

There are several forks of it where +the UI or UX may differ, +but the core features work exactly the same. +I personally use + Monocles Chat.

+

On the Contact Details screen (including your own account), +you can see a list of published fingerprints +and manually mark them as trusted or revoke trust.

+

To simplify all these routine operations, +a QR-code-based system is used: +you can show your own QR code or scan other people’s codes +directly from the main screen. +This makes device verification during in-person meetings +simple and effortless.

+

Dino

+

+ Dino is a lightweight GTK-based GUI client.

+

It can be considered a fully functional one, +although some non-essential features are still not implemented. +For example, +it is not possible to clear local chat history +using built-in methods :D

+

Trust and untrust decisions can be easily managed +in the Encryption tab of the Conversation Details window.

+

It is important to note that, +by default, Dino is configured +to automatically trust new fingerprints. +I recommend disabling this feature.

+

Profanity

+

+ Profanity is a powerful TUI client +where everything is controlled through a built-in command system.

+

If you somehow intend to use it, +you can find a small cheat sheet for the omemo command below. +However, I strongly recommend reading the full documentation.

+ +

Late Disclaimer

+

This post was originally intended +as a collection of answers to questions +I had when I first started using XMPP with OMEMO.

+

It isn’t meant to be exhaustive or formal, +but rather to clarify the practical side of things +and reduce that initial feeling of being lost +when you keep running into +“The message was not encrypted for this device” +over and over again.

+

From now on, I hope you won’t encounter such errors +or any other issues +connected to end-to-end encryption in XMPP.

+ +
+
+ + + + + + + + diff --git a/docs/posts/2026/index.html b/docs/posts/2026/index.html new file mode 100644 index 0000000..91624c7 --- /dev/null +++ b/docs/posts/2026/index.html @@ -0,0 +1,25 @@ + + + + + + + + Redirect | oddsquat + + + +
+ Redirect to + + /posts/#2026 + +
+ + diff --git a/docs/posts/2026/ugly_keyboards_ru/index.html b/docs/posts/2026/ugly_keyboards_ru/index.html index 157b29e..c9090b5 100644 --- a/docs/posts/2026/ugly_keyboards_ru/index.html +++ b/docs/posts/2026/ugly_keyboards_ru/index.html @@ -10,7 +10,7 @@ - ugly_keyboards | oddsquat + ugly keyboards | oddsquat @@ -46,7 +46,7 @@ 2026 -
  • ugly_keyboards
  • +
  • ugly keyboards
  • diff --git a/docs/posts/index.html b/docs/posts/index.html index acafacb..af8204b 100644 --- a/docs/posts/index.html +++ b/docs/posts/index.html @@ -12,7 +12,7 @@ posts | oddsquat - + diff --git a/docs/projects/index.html b/docs/projects/index.html index 70c03fd..1d0baa9 100644 --- a/docs/projects/index.html +++ b/docs/projects/index.html @@ -163,7 +163,7 @@
  • - Cantor MX Tastatura + Cantor MX Tastatura
    @@ -181,7 +181,7 @@
    - Huge custom ergonomic mechanical Dactyl-Manuform (5×6) keyboard. + Huge custom ergonomic mechanical Dactyl-Manuform (5×6) keyboard.
    repository diff --git a/src/pages/about.html b/src/pages/about.html index 204bb91..f936f72 100644 --- a/src/pages/about.html +++ b/src/pages/about.html @@ -4,7 +4,7 @@ layout: post lang: 'en' title: 'about' -description: 'General info about this website and the author' +description: 'General info about this website and the author.' --- @@ -25,7 +25,7 @@ description: 'General info about this website and the author'

    - I'm a front-end developer and a big fan of open-source, + I’m a front-end developer and a big fan of open-source, customization, and minimalist software.
    Member of the BadBar crew, diff --git a/src/pages/about/keys.md b/src/pages/about/keys.md index e5145cc..910b8e8 100644 --- a/src/pages/about/keys.md +++ b/src/pages/about/keys.md @@ -2,12 +2,13 @@ layout: post lang: 'en' -date: '2026-04-05' -section: 'about' title: 'keys' description: 'Public keys and fingerprints.' +section: 'about' +date: '2026-04-05' + --- # Public Keys and Fingerprints diff --git a/src/pages/index.ejs b/src/pages/index.ejs index 336d045..a30b27a 100644 --- a/src/pages/index.ejs +++ b/src/pages/index.ejs @@ -1,6 +1,7 @@ --- -description: 'My own private fanzine' +description: 'My own private fanzine.' + css: - index diff --git a/src/pages/lost+found.md b/src/pages/lost+found.md index 9a3e36e..1f247f5 100644 --- a/src/pages/lost+found.md +++ b/src/pages/lost+found.md @@ -200,7 +200,7 @@ in the middle of a conversation.

    Interactive articles about physics, math, and engineering. - It's probably the best website on the entire internet.
    + It’s probably the best website on the entire internet.
    My favorite post is the one about bicycles.
    @@ -245,7 +245,7 @@ in the middle of a conversation.
    Torrenting can leave traces.
    Check torrent downloads and distributions - for your own or your neighbor's IP address. + for your own or your neighbor’s IP address.
    @@ -300,7 +300,7 @@ in the middle of a conversation.
    - Ask HN: Programmers who don't use autocomplete/LSP, how do you do it? + Ask HN: Programmers who don’t use autocomplete/LSP, how do you do it?
    @@ -314,7 +314,7 @@ in the middle of a conversation.
    - Your Computer Isn't Yours + Your Computer Isn’t Yours
    @@ -411,7 +411,7 @@ in the middle of a conversation.
    - Most software tutorials suck. Here's how to make one that doesn't. + Most software tutorials suck. Here’s how to make one that doesn’t.
    diff --git a/src/pages/posts.md b/src/pages/posts.md index e6cbe7e..498cd8c 100644 --- a/src/pages/posts.md +++ b/src/pages/posts.md @@ -4,7 +4,7 @@ layout: post lang: 'en' title: 'posts' -description: 'Сomplete list of posts' +description: 'Сomplete list of posts.' --- diff --git a/src/pages/posts/2020/initial_post.md b/src/pages/posts/2020/initial_post.md index 42075d6..e56ee0b 100644 --- a/src/pages/posts/2020/initial_post.md +++ b/src/pages/posts/2020/initial_post.md @@ -1,16 +1,15 @@ --- layout: post - lang: 'ru' -date: '2020-11-08' - -year: '2020' -section: 'posts' title: 'initial post' description: 'Первый пост в этом фэнзине, рассказывающий о его внутреннем устойстве.' +section: 'posts' +year: '2020' +date: '2020-11-08' + --- # Initial Post diff --git a/src/pages/posts/2020/typographic_linter.md b/src/pages/posts/2020/typographic_linter.md index be94f32..245e55a 100644 --- a/src/pages/posts/2020/typographic_linter.md +++ b/src/pages/posts/2020/typographic_linter.md @@ -1,16 +1,15 @@ --- layout: post - lang: 'ru' -date: '2020-11-18' - -year: '2020' -section: 'posts' title: 'typographic linter' description: 'Prettier для текста. Автоматизация рутинной типографики.' +section: 'posts' +year: '2020' +date: '2020-11-18' + --- # Типографика как code style diff --git a/src/pages/posts/2024.md b/src/pages/posts/2024.md index d1b54b3..ecca402 100644 --- a/src/pages/posts/2024.md +++ b/src/pages/posts/2024.md @@ -4,4 +4,3 @@ layout: redirect redirectTarget: '/posts/#2024' --- - diff --git a/src/pages/posts/2024/selfhosted_llm.md b/src/pages/posts/2024/selfhosted_llm.md index 1b6cdb1..3952ce4 100644 --- a/src/pages/posts/2024/selfhosted_llm.md +++ b/src/pages/posts/2024/selfhosted_llm.md @@ -1,16 +1,15 @@ --- layout: post - lang: 'ru' -date: '2024-01-15' - -year: '2024' -section: 'posts' title: 'selfhosted LLM' description: 'Персональные LLM в docker-контейнере на твоём компьютере.' +section: 'posts' +year: '2024' +date: '2024-01-15' + --- # Your Own Private Large Language Models diff --git a/src/pages/posts/2024/wrapped_bw_ru.md b/src/pages/posts/2024/wrapped_bw_ru.md index db685e9..f55b5b7 100644 --- a/src/pages/posts/2024/wrapped_bw_ru.md +++ b/src/pages/posts/2024/wrapped_bw_ru.md @@ -1,15 +1,15 @@ --- layout: post - lang: 'ru' -date: '2024-07-27' - -year: '2024' -section: 'posts' title: 'wrapped bw' description: 'Превращаем fully-featured Bitwarden command-line interface в удобный.' + +section: 'posts' +year: '2024' +date: '2024-07-27' + --- # Интеграция Bitwarden CLI с fzf и буфером обмена diff --git a/src/pages/posts/2026.md b/src/pages/posts/2026.md new file mode 100644 index 0000000..cf8324c --- /dev/null +++ b/src/pages/posts/2026.md @@ -0,0 +1,6 @@ +--- + +layout: redirect +redirectTarget: '/posts/#2026' + +--- diff --git a/src/pages/posts/2026/encrypted_XMPP.md b/src/pages/posts/2026/encrypted_XMPP.md new file mode 100644 index 0000000..74a34bf --- /dev/null +++ b/src/pages/posts/2026/encrypted_XMPP.md @@ -0,0 +1,463 @@ +--- + +layout: post +lang: 'en' + +title: 'encrypted XMPP' +description: 'Secure and private messaging with XMPP and OMEMO encryption.' + +section: 'posts' +year: '2026' +date: '2026-04-16' + +--- + +# End-to-End Encryption in XMPP with OMEMO + +I find it funny that twenty years ago I was already trying +to get people to switch to XMPP. + +For a long time, ICQ was extremely popular around me, +but the proprietary messenger kept breaking things for people +using alternative clients, which was quite annoying. +After yet another round of this pointless battle +I realized clearly that I prefer protocols over services. + +I didn’t have much success back then, +but fortunately, XMPP (and I hope I have too) +has continued moving forward over the past two decades. +It has developed slowly, sometimes awkwardly, but steadily. + +Here, I won’t talk about why XMPP is great or how it works. +You can check + + this guide +(one of many) and I’d rather not write another one. +In this post, +I want to focus specifically on end-to-end encryption +and the practical aspects of using it. + +## Short Glossary + +**End-to-end encryption** is a way +to keep your chats truly private.
    +Only you and the person you’re messaging can read the messages. +Not even the server owner has the keys +needed to decrypt or modify them. + +**XMPP** is an extensible protocol for instant messaging. +It’s open, decentralized, and mature. + +**OMEMO** is a widely supported +XMPP Extension Protocol (XEP) +for secure multi-client end-to-end encryption. +You can read more about +it on a dedicated page by Daniel Gultsch. + +**Client**, in this post, +means a specific instance +of an XMPP application on a user device. +
    OMEMO-related documentation uses the term Device, +but I find it potentially confusing: +in practice, a single physical device +can run multiple independent clients. + +## Basic Concepts + +This section introduces some basics of end-to-end encryption. + +If you’re already familiar with the concepts and terminology, +you can skip ahead to how end-to-end encryption + affects the XMPP user experience, +or jump straight to the step-by-step workflow I personally use. + +### Trade-offs Between Safety and Convenience + +Unfortunately, things that are truly secure are rarely convenient. +They often require some initial efforts +and a bit of ongoing attention. + +Telegram, which used to be a benchmark for messenger usability +before its long dive into enshitification, +really draws the line between convenience and security. +Regular chats are easy and flexible, +but “secret” chats come with a full set of limitations: +they’re one-on-one only, +can’t be synced to another device, +aren’t available on desktop at all, +and so on. + +All commercial so-called “secure” messengers, like Signal or WhatsApp, +end up with pretty similar limitations, +because it’s tricky to make end-to-end encrypted chats +work the way users expect. + +Luckily, protocols and cryptography don’t care about +convenience or user expectations. +Many XMPP clients let you do almost anything you’re trying to do. +Sometimes it’s clunky and unintuitive, +sometimes it’s the kind of freedom +that lets you shoot yourself in the foot. +At the end of the day, you’d better understand what you’re doing. + +It might sound messy, but for that price, XMPP actually +gives you a lot of handy features: +your chats are secured with Signal-grade end-to-end encryption, +and you can use as many devices as you want, +all at the same time, +without being tied to any proprietary service. + +In general, the XMPP experience today +could be described as a “WhatsApp with benefits and frictions”. +It’s kinda ironic, considering that WhatsApp’s protocol +is actually based on XMPP, but incompatibly altered and defederated. + +### Keys, Fingerprints and Trust + +OMEMO is based on the + Double Ratchet Algorithm. +While the internal details are quite interesting, +for practical purposes it’s enough to know that +each client stores some cryptographic keys +and can derive a hash from them, commonly called a fingerprint. + +Keys are usually managed automatically by the XMPP client, +and in normal use you should never need to handle them manually. +In fact, you probably don’t even need to know what they look like. + +A fingerprint lets you identify +a specific client of your contact +and verify that it hasn’t been spoofed. +Fingerprints for an account are not secret: +clients publish their own fingerprints to the XMPP server +and automatically receive the fingerprints of others. +Only fingerprints you explicitly mark as trusted are relevant. + +In an typical scenario, the contact should confirm in person +or through an already trusted and secure communication channel +that the fingerprint belongs to their device, +and only then you mark it as trusted. + +The list of trusted fingerprints +is used at the moment a message is sent. +Behind the scenes, +OMEMO performs a certain amount of key management, +and only the clients that are present in the trusted list +at the time of encryption +will be able to decrypt the message later. + +It’s important to understand +that trust cannot be applied retroactively: +it’s not possible to “extend” trust to new clients +after a message has already been encrypted and sent. + +

    + Practical Aspects of OMEMO and XMPP +

    + +### Chat History + +In theory, XMPP supports server-side message history storage via +**XEP-0313: Message Archive Management**. + +In practice, support for this XEP, +as well as retention policies and message lifetime, +depends on the specific server. +You should never assume that all conversations are stored +indefinitely by default. +From a practical standpoint, +the server-side MAM archive is better considered a cache: +it can help you handle recent messages after a short period offline +or synchronize conversations across multiple devices. + +At the end of the day, +keeping your chat history is your responsibility, +and this is a good place to apply a local-first approach. + + +### Synchronisation + +Seamless switching between clients is handled by +**XEP-0280: Message Carbons**. +Before its introduction, only incoming messages were synced between devices, +while your own outgoing messages were not. +Protocol-level mirroring of your own messages +is a rather non-obvious feature :D + +It’s important to note that with end-to-end encryption, +the concept of trusted fingerprints also applies to your own clients. +For seamless synchronisation of outgoing messages, +all your clients must trust each other’s fingerprints. +A new client, +or an old one that was not trusted +at the time messages were sent, +will receive the full history from MAM +but will not be able to decrypt it. +
    Yes, even your own messages. + +In theory, re-encrypting messages on already trusted clients +could solve this issue, but no XMPP client implements it yet. +So in practice you may need to manually resend +some data to a new device. + +### Message Correction + +It’s worth keeping in mind that +features that seem simple and straightforward at first glance, +such as message editing and deletion, +actually rely on client-side implementation +and may not behave for your recipient the way you expect. + +They’re fine to use and are well supported in some clients, +but you shouldn’t rely on them to hide anything. + +### Maintenance + +OMEMO was designed as a set-it-and-forget-it solution +and mostly succeeds in that goal. +If you have a basic understanding of how the protocol works +and check in online from time to time, +there shouldn’t be any surprises. + +All maintenance comes down to making regular backups +and notifying your contacts +when fingerprints are added or no longer valid +so they can keep their trust list up to date. + +## Step-by-Step Guide + +Let’s say I have a XMPP account, `me@some.server`, +and a few devices: +a phone, a laptop, and a desktop computer. +First I’ll describe my mindset at a high level, +then I’ll add some notes about specific clients. + +### Client Roles + +On the one hand, I have my phone. +It’s almost always with me and almost always online. +That’s where I keep the full chat history +and get real-time notifications. + +On the other hand, I have a couple of desktop applications. +I only open them +when I need to discuss something using my keyboard +or share some text between devices. +I like to think of them as satellite clients. + +### Before the Start + +First, enable OMEMO encryption +on every client if it isn’t enabled by default. + +The next step is to add +all clients to the trust list on each device: +my phone should trust all my computers, +and my computers should trust each other +as well as my phone. + +Fingerprints do not have to be secret, +so they can be published on +your website or even on social media profiles. +Here is my page with the fingerprints, for example: +
    + https://oddsquat.org/about/keys/ + + +### Start the Conversation in Person + +Let’s say I meet Alice, +we start talking, +and then decide to continue the conversation online. + +I open a special QR code on my phone, +and Alice scans it with her client. +This QR code already contains +the fingerprints of all my devices, +so no extra steps are needed on her phone. +After that, I do the same +and scan her QR code as well. + +Later at home, +I manually mark her devices as trusted on my computers +using the trusted list on my phone, and she does the same. + +Now we are both sure +that it is really us in the conversation, +and that all messages will be available +on all our devices and only on them. + +### Start the Conversation Online + +Let’s say Bob and I start discussing something +on a forum or in the Fediverse, +and then decide to continue the discussion on XMPP. + +Before starting the chat, +Bob can confirm it’s really me using my page with fingerprints. +I can confirm it’s really him +by asking him to send his fingerprints +in a private message on the same forum or via email. + +Ideally, Bob also has a public page with his fingerprints. +That way, we can both independently verify +that we are who we say we are. + +In an alternative scenario, +where there has been no prior communication or public pages +and only a single JID is known, +things play out a bit differently: +Bob starts the chat, +I trust the first device he messages me from, +and then we exchange fingerprints for our other devices, +if we have any. +This approach is called TOFU (Trust On First Use). + +### New or Lost Devices + +If I start using a new device +or install another client application, +the first thing I do is add it to the list +of trusted clients on my existing devices. + +If I lose one of my devices +or delete any private keys, +the first thing I do is remove the corresponding client +from the trusted list on my other devices. + +Once I’ve updated all my personal lists, +I should inform my contacts about changes via trusted channels. + +I can simply ask Alice to scan +my new QR code the next time we meet, +and send Bob a message introducing +my new client or letting him know +that the lost device is no longer trusted +and that no real messages will ever come from it again. + +## Client Applications + +This section describes +how OMEMO is used in specific client applications +that I personally use. + +### Conversations and Forks + + + Conversations is a modern, +fully featured chat application for Android. +It supports everything a messaging app should support: +chats, voice calls, video calls, and sharing files of any kind. + +There are several forks of it where +the UI or UX may differ, +but the core features work exactly the same. +I personally use + Monocles Chat. + +On the Contact Details screen (including your own account), +you can see a list of published fingerprints +and manually mark them as trusted or revoke trust. + +To simplify all these routine operations, +a QR-code-based system is used: +you can show your own QR code or scan other people’s codes +directly from the main screen. +This makes device verification during in-person meetings +simple and effortless. + +### Dino + + + Dino is a lightweight GTK-based GUI client. + +It can be considered a fully functional one, +although some non-essential features are still not implemented. +For example, +it is not possible to clear local chat history +using built-in methods :D + +Trust and untrust decisions can be easily managed +in the Encryption tab of the Conversation Details window. + +It is important to note that, +by default, Dino is configured +to automatically trust new fingerprints. +I recommend disabling this feature. + +### Profanity + + + Profanity is a powerful TUI client +where everything is controlled through a built-in command system. + +If you somehow intend to use it, +you can find a small cheat sheet for the `omemo` command below. +However, I strongly recommend reading the full documentation. + +- Generate a key and add your other clients: + ```text + /omemo gen + /omemo trust me@some.server some-cool-fingerprint-01 + /omemo trust me@some.server another-cool-fingerprint + /omemo qrcode + ``` + +- View the list of your own or someone else’s fingerprints: + ```text + /omemo fingerprint me@some.server + /omemo fingerprint alice@another.server + ``` + Trusted ones will be marked as `trusted`. + +- Start an encrypted conversation: + ```text + /omemo start alice@another.server + ``` + +- Add fingerprints to the trusted list: + ```text + /omemo trust alice@another.server some-cool-fingerprint-02 + /omemo trust alice@another.server some-cool-fingerprint-03 + /omemo trust bob@another.server some-cool-fingerprint-04 + ``` + +- Revoke trust for a specific client: + ```text + /omemo untrust alice@another.server some-cool-fingerprint-02 + ``` + +## Late Disclaimer + +This post was originally intended +as a collection of answers to questions +I had when I first started using XMPP with OMEMO. + +It isn’t meant to be exhaustive or formal, +but rather to clarify the practical side of things +and reduce that initial feeling of being lost +when you keep running into +“The message was not encrypted for this device” +over and over again. + +From now on, I hope you won’t encounter such errors +or any other issues +connected to end-to-end encryption in XMPP. diff --git a/src/pages/posts/2026/ugly_keyboards_ru.md b/src/pages/posts/2026/ugly_keyboards_ru.md index 3b3adb6..9a72747 100644 --- a/src/pages/posts/2026/ugly_keyboards_ru.md +++ b/src/pages/posts/2026/ugly_keyboards_ru.md @@ -2,12 +2,13 @@ layout: post lang: 'ru' + +title: 'ugly keyboards' +description: 'Почему нас окружают уродливые клавиатуры и что с этим можно сделать.' + +section: 'posts' year: '2026' date: '2026-03-18' -section: 'posts' - -title: 'ugly_keyboards' -description: 'Почему нас окружают уродливые клавиатуры и что с этим можно сделать.' --- diff --git a/src/pages/projects.md b/src/pages/projects.md index 6172c8d..a7593f6 100644 --- a/src/pages/projects.md +++ b/src/pages/projects.md @@ -123,7 +123,7 @@ Incomplete list of my projects and experiments. -
    - Cantor MX Tastatura + Cantor MX Tastatura
    @@ -141,7 +141,7 @@ Incomplete list of my projects and experiments.
    - Huge custom ergonomic mechanical Dactyl-Manuform (5×6) keyboard. + Huge custom ergonomic mechanical Dactyl-Manuform (5×6) keyboard.
    repository diff --git a/src/pages/test.md b/src/pages/test.md index 727d8fb..7066777 100644 --- a/src/pages/test.md +++ b/src/pages/test.md @@ -1,16 +1,15 @@ --- layout: post - lang: 'en' -date: '2020-10-30' - -year: '2020' -section: 'posts' title: 'markdown test page' description: 'A test document written using the Markdown language.' +section: 'posts' +year: '2020' +date: '2020-10-30' + --- # Markdown: Syntax diff --git a/tools/typograf.js b/tools/typograf.js index 2319865..2b7ed50 100644 --- a/tools/typograf.js +++ b/tools/typograf.js @@ -25,6 +25,7 @@ const tp = new Typograf({ const enabledRules = [ 'common/nbsp/*', + 'common/punctuation/apostrophe', 'common/punctuation/quote', 'en-US/dash/main', 'ru/dash/main',