~arx10/openpgpcard-wireguard-go

patched WireGuard Go client to interact with an OpenPGP card
build: sourcehut build script
README: how to use with private key stored on card
script: make-owg-quick.sh to run custom binary

refs

wg20240217
browse  log 
wg20230223-owg1
release notes 

clone

read-only
https://git.sr.ht/~arx10/openpgpcard-wireguard-go
read/write
git@git.sr.ht:~arx10/openpgpcard-wireguard-go

You can also use your local clone with git send-email.

#OpenPGP Card WireGuard Go

This is a small, experimental set of patches to the standard WireGuard Go client. It adds the ability to use a private key stored on an OpenPGP card, by way of a UNIX domain socket connection with an SSH agent.

Because it relies on custom SSH agent extensions, this client will work only with a custom SSH agent: currently, only the OpenPGP Card X25519 Agent.

See the OpenPGP Card WireGuard Guide for a complete walkthrough of installation and usage of both agent and client.

#Building

This requires an installation of go ≥ 1.20.

To clone this repo and build it, run the following commands:

$ git clone https://git.sr.ht/~arx10/openpgpcard-wireguard-go
$ cd openpgpcard-wireguard-go
$ make

This will build a binary called wireguard-go in the root of the source directory.

#Usage

To use the above binary, you must also have the wg command from the wireguard-tools project installed, version v1.0.20210223 or newer:

$ wg version
wireguard-tools v1.0.20210223 - https://git.zx2c4.com/wireguard-tools/

To run the wireguard-go binary with debug logging, run the following command in one terminal:

$ sudo LOG_LEVEL=debug ./wireguard-go --foreground wg0

In a second terminal, set the private key for the WireGuard interface to a special fake private key:

$ echo AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= | sudo wg set wg11 private-key /dev/stdin

This fake private key signals the client to attempt to read a real public key from an SSH agent using the /var/wireguard/run/agent0 socket.

If successful, you can continue to initialize the WireGuard interface:

$ sudo wg set wg0 peer fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds= endpoint 203.0.113.2:51822 allowed-ips 10.0.0.2/32
$ sudo ip -4 address add 10.0.0.1/32 dev wg0
$ sudo ip link set mtu 1420 up dev wg0
$ sudo ip -4 route add 10.0.0.2/32 dev wg0

For each peer you add to the interface, the client will ask the SSH agent to perform a X25519 shared-secret pre-computation for the peer.

If successful, you can use the interface as normal:

$ ping -nc1 10.0.0.2

As you use the interface, whenever the client needs to perform another WireGuard handshake, it will ask the SSH agent to derive another shared secret.

#Beware

  • The wg command will show the fake public key for this interface -- do not use this key when configuring other clients! Instead use the real public key shown for your OpenPGP card by the SSH agent.
  • Do not use the fake private key required for the configuration of this client with any other client. Using this fake key pair with a regular WireGuard client could allow an adversary to easily decrypt your WireGuard traffic, or impersonate your WireGuard identity.
  • If an adversary controls the SSH agent's socket, she could potentially decrypt your WireGuard traffic; and at least can prevent you from sending or receiving any WireGuard traffic.
  • The patches for this client haven't received the same deep level of scrutiny or testing that the standard WireGuard clients have received.

#SSH Agent Extensions

The client requires an SSH agent that can handle the following extensions to the SSH agent protocol:

#x25519/pub

To request an X25519 public key, the client will send the agent the following message:

byte        SSH_AGENTC_EXTENSION (0x1b)
string      "x25519/pub"
string      reader id

For example, to request the public key for the card reader ID "0", the client would write these bytes to the agent socket:

00000014 1b 0000000a 7832353531392f707562 00000001 30

The agent should respond with the following message if it's able to retrieve the public key:

byte        SSH_AGENT_SUCCESS (0x06)
uint32      public key length (0x00000020)
byte[]      public key contents

For example, to respond with public key of /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=, the agent would write these bytes to its socket:

00000025 06 00000020 fd3384e132ad02a56c78f45547ee40038dc79002b90d29ed90e08eee762ae715

(If the agent is not able to retrieve the public key, it should respond with a generic failure message.)

#x25519/dh

To request the agent derive an X25519 shared secret, the client will send the agent the following message:

byte        SSH_AGENTC_EXTENSION (0x1b)
string      "x25519/dh"
string      reader id
uint32      other party's public key length (0x00000020)
byte[]      other party's public key contents

For example, to request a shared secret derived from the private key in the card reader ID "0" and a public key of fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=, the client would write these bytes to the agent socket:

00000037 1b 00000009 7832353531392f6468 00000001 30 00000020 \
    7c4ff0771ce5d24955a7f211f1471aa0650c8ea6968b78c077b2b31ca152e83b

The agent should respond with the following message if it's able to derive the shared secret:

byte        SSH_AGENT_SUCCESS (0x06)
uint32      shared secret length (0x00000020)
byte[]      shared secret contents

For example, to respond with a shared secret of WdUQ9vUNzKCVMDcoU8jSe9h91U1Dyfly54dfPC2bOVc=, the agent would write these bytes to its socket:

00000025 06 00000020 59d510f6f50dcca09530372853c8d27bd87dd54d43c9f972e7875f3c2d9b3957

(If the agent is not able to derive the shared secret, it should respond with a generic failure message.)

#Contributing

#License

Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.