Question about hidden services and addresses in arti

Hi all.

I’m toying with a proof of concept where I’m trying to embed the necessary data for starting a hidden service at compile time in a program. This seems to necessitate generating keys for it, but so far I haven’t figured out how to do so if it’s even possible just from reading the examples and available documentation.

Any pointers?

Are you asking to start a new instance of a hidden service in Arti? Or a hidden service with a specific hsid?

To start a hidden service you can look at arti_client’s TorClient launch_onion_service: TorClient in arti_client - Rust

This will spin up a new service.

To re-use an existing HsId you can do it programmatically using launch_onion_service_with_hsidor by just copying the ed25519 private key from your Arti’s hsstate/keystore/hss. Pasting this key in the same directory on another system will launch an onion service with the same hsid.

This seems to necessitate generating keys for

Just launching a hidden service doesn’t require you to manually generate keys for it. launch_onion_service will do this automatically and place the key in the keystore inside Arti’s data directory.

I also guess you mean at runtime.

There are also examples to do it using hyper or axum:

https://gitlab.torproject.org/tpo/core/arti/-/tree/main/examples/hyper-examples?ref_type=heads

https://gitlab.torproject.org/tpo/core/arti/-/tree/main/examples/axum/axum-hello-world?ref_type=heads

I also guess you mean at runtime.

Nope, compile time. Imagine generating a HsId during or before the build process and embedding that into the binary with something like `embed_*!`. Think of it like compiling a server binary whose hidden address I know in advance without ever having to run it. It doesn’t need to be a good idea, just a silly PoC I’m working on.

To re-use an existing HsId you can do it programmatically using launch_onion_service_with_hsid

Oh that’s weird, I’m not seeing that in my scope. Am I missing a feature or smt? I currently have onion-service-client and onion-service-service. *Edit:* oh, it’s gated behind `experimental-api`

just copying the ed25519 private key from your Arti’s hsstate/keystore/hss

which one(s)? if i peek into the keystore for a previously used test nickname i see a bunch of keys

.
├── ipts
│   ├── k_hss_ntor+3b430bd949931345b6debbea957d556437732019260585d13ee775398a99b0f1.x25519_private
│   ├── k_hss_ntor+63dd79d74560f0dc18f0c1984f71c1ce72720e50c49ead4625246280f63786ff.x25519_private
│   ├── k_hss_ntor+eb9fa3a150eb72df5b07ac4b96f787b05dbdd2e8cce5bad7cdc0c7db367e384f.x25519_private
│   ├── k_sid+3b430bd949931345b6debbea957d556437732019260585d13ee775398a99b0f1.ed25519_private
│   ├── k_sid+63dd79d74560f0dc18f0c1984f71c1ce72720e50c49ead4625246280f63786ff.ed25519_private
│   └── k_sid+eb9fa3a150eb72df5b07ac4b96f787b05dbdd2e8cce5bad7cdc0c7db367e384f.ed25519_private
├── ks_hs_blind_id+20490_1440_43200.ed25519_expanded_private
├── ks_hs_blind_id+20491_1440_43200.ed25519_expanded_private
├── ks_hs_desc_sign+20490_1440_43200.ed25519_private
├── ks_hs_desc_sign+20491_1440_43200.ed25519_private
└── ks_hs_id.ed25519_expanded_private

I thought about archiving the whole keystore but that seems finicky and wanted to avoid it.

Your onion hsid is derived from this file ks_hs_id.ed25519_expanded_private (Key store hidden service identifier).

You could embed the content in your binary and write it to Arti’s data directory at runtime (easy) or somehow find a way to convert it to Arti’s HsIdKeytype or something (if you want to dive deeper into Arti).

Glad you acknowledge it, embedding this key in your binary is a terrible idea for production software. But it’s nice as PoC/learning or personal project.

1 Like