Skip to content

Instantly share code, notes, and snippets.

@mig5
Created June 17, 2020 06:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mig5/2e95a3fbe157e1f78764f7a718bf93b9 to your computer and use it in GitHub Desktop.
Save mig5/2e95a3fbe157e1f78764f7a718bf93b9 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import base64
import threading
from http.server import BaseHTTPRequestHandler, HTTPServer
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives import serialization
from stem.control import Controller
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
# Send response status code
self.send_response(200)
# Send headers
self.send_header('Content-type','text/html')
self.end_headers()
self.wfile.write(bytes("<html><head><title>Hello, world.</title></head><body><p>Hello, world.</p></html>","utf-8"))
return
def start_http():
print("http service: http://127.0.0.1:8080/")
print("")
httpd = HTTPServer(('127.0.0.1', 8080), RequestHandler)
httpd.serve_forever()
def main():
# Start the http server
t = threading.Thread(target=start_http)
t.start()
# Connect to tor controller provided by Tor Browser
c = Controller.from_port(port=9051)
c.authenticate()
key_type = "NEW"
key_content = "ED25519-V3"
print("starting onion service with: key_type='{}', key_content='{}'".format(key_type, key_content))
res = c.create_ephemeral_hidden_service(
{ 80: 8080 },
await_publication=True,
key_type=key_type,
key_content=key_content
)
print("http://{}.onion/".format(res.service_id))
print("")
priv_key = Ed25519PrivateKey.generate()
pub_key = priv_key.public_key().public_bytes(
encoding=serialization.Encoding.Raw,
format=serialization.PublicFormat.Raw
)
keyblob = priv_key.private_bytes(
encoding=serialization.Encoding.Raw,
format=serialization.PrivateFormat.Raw,
encryption_algorithm=serialization.NoEncryption()
)
base64_keyblob = base64.b64encode(keyblob).decode('utf-8')
base32_keyblob = base64.b32encode(keyblob).decode('utf-8')
base32_pubkeyblob = base64.b32encode(pub_key).decode('utf-8')
print('private base64: %s' % base64_keyblob)
# These would be stored client side (i.e in TB)
print('public base32: %s' % base32_pubkeyblob)
print('private base32: %s' % base32_keyblob)
# Commented out as Stem support for ONION_CLIENT_AUTH_ADD is in my own private Stem feature branch for now.
# But the behaviour is the same (my feature to Stem is returning a 250 OK)
#
# Instead, connect to a control port with telnet and run ONION_CLIENT_AUTH_ADD $service_id $base64_keyblob
# and you'll get a 250 OK, but the onion is still directly accessible in Tor Browser without the client auth
# added
#c.add_onion_client_auth(service_id=res.service_id, private_key_blob=base64_keyblob, key_type='x25519')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment