]> git.ipfire.org Git - thirdparty/wireguard-tools.git/commitdiff
noise: redesign preshared key mode
authorJason A. Donenfeld <Jason@zx2c4.com>
Thu, 27 Apr 2017 09:10:50 +0000 (11:10 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Wed, 17 May 2017 16:07:42 +0000 (18:07 +0200)
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
contrib/external-tests/go/main.go
contrib/external-tests/haskell/src/Main.hs
contrib/external-tests/rust/src/main.rs
contrib/json/wg-json
src/completion/wg.bash-completion
src/config.c
src/set.c
src/show.c
src/showconf.c
src/wg.8

index 11c2f868301cf6d6bc396baa82669472ea0a4308..4b58891620711fc8077d3ccace032c1b9037a69e 100644 (file)
@@ -37,16 +37,17 @@ func ipChecksum(buf []byte) uint16 {
 func main() {
        ourPrivate, _ := base64.StdEncoding.DecodeString("WAmgVYXkbT2bCtdcDwolI88/iVi/aV3/PHcUBTQSYmo=")
        ourPublic, _ := base64.StdEncoding.DecodeString("K5sF9yESrSBsOXPd6TcpKNgqoy1Ik3ZFKl4FolzrRyI=")
-       preshared, _ := base64.StdEncoding.DecodeString("FpCyhws9cxwWoV4xELtfJvjJN+zQVRPISllRWgeopVE=")
        theirPublic, _ := base64.StdEncoding.DecodeString("qRCwZSKInrMAq5sepfCdaCsRJaoLe5jhtzfiw7CjbwM=")
+       preshared, _ := base64.StdEncoding.DecodeString("FpCyhws9cxwWoV4xELtfJvjJN+zQVRPISllRWgeopVE=")
        cs := noise.NewCipherSuite(noise.DH25519, noise.CipherChaChaPoly, noise.HashBLAKE2s)
        hs := noise.NewHandshakeState(noise.Config{
                CipherSuite:   cs,
                Random:        rand.Reader,
                Pattern:       noise.HandshakeIK,
                Initiator:     true,
-               Prologue:      []byte("WireGuard v0 zx2c4 Jason@zx2c4.com"),
+               Prologue:      []byte("WireGuard v1 zx2c4 Jason@zx2c4.com"),
                PresharedKey:  preshared,
+               PresharedKeyPlacement: 2,
                StaticKeypair: noise.DHKey{Private: ourPrivate, Public: ourPublic},
                PeerStatic:    theirPublic,
        })
@@ -68,8 +69,10 @@ func main() {
        initiationPacket[3] = 0 // Reserved
        binary.LittleEndian.PutUint32(initiationPacket[4:], 28) // Sender index: 28 (arbitrary)
        initiationPacket, _, _ = hs.WriteMessage(initiationPacket, tai64n)
-       hasher, _ := blake2s.New(&blake2s.Config{Size: 16, Key: preshared})
+       hasher, _ := blake2s.New(&blake2s.Config{Size: 32})
+       hasher.Write([]byte("mac1----"))
        hasher.Write(theirPublic)
+       hasher, _ = blake2s.New(&blake2s.Config{Size: 16, Key: hasher.Sum(nil)})
        hasher.Write(initiationPacket)
        initiationPacket = append(initiationPacket, hasher.Sum(nil)[:16]...)
        initiationPacket = append(initiationPacket, make([]byte, 16)...)
index 820e2f18e60549a97ac055f9faafbf1cf166dfb4..8983e6c142b3c82e0f7a888f75e6300c9e6670cc 100644 (file)
@@ -34,7 +34,7 @@ w :: PublicKey Curve25519
   -> IO ()
 w theirPub (Plaintext myPSK) sock addr msg = do
   let x      = "\x01\x00\x00\x00\x00\x00" `mappend` msg
-      mac    = hash 16 myPSK (sbToBS' (curvePubToBytes theirPub) `mappend` sbToBS' x)
+      mac    = hash 16 myPSK (sbToBS' (curvePubToBytes theirPub) `mappend` sbToBS' x) -- TODO: this should actually be blake2s(key=blake2s("mac1----" || theirPub), payload=blah)
   void $ NBS.sendTo sock (x `mappend` mac `mappend` replicate 16 '\0') addr
 
 r :: MVar ByteString -> Socket -> IO ByteString
@@ -63,8 +63,8 @@ main = do
       serverkey' = curveBytesToPub   . bsToSB' . either undefined id . B64.decode . pack $ serverkey :: PublicKey Curve25519
       psk'       = Plaintext . bsToSB' . either undefined id . B64.decode . pack $ psk
       hs         = handshakeState $ HandshakeStateParams
-                   noiseIK
-                   "WireGuard v0 zx2c4 Jason@zx2c4.com"
+                   noiseIK -- TODO: specify psk2 mode
+                   "WireGuard v1 zx2c4 Jason@zx2c4.com"
                    (Just psk')
                    (Just mykey')
                    Nothing
index 232375cdd0f73754c7bcddafd8b8222967fb4a15..ceb68b8bacaeebdddea8ece341866279b558d4cb 100644 (file)
@@ -39,11 +39,12 @@ fn main() {
        owner.set_rs(&their_public);
        let mut cipherstate1 : CipherState<CipherChaChaPoly> = Default::default();
         let mut cipherstate2 : CipherState<CipherChaChaPoly> = Default::default();
-       let mut handshake = HandshakeState::new_from_owner(&mut owner, true, HandshakePattern::IK, "WireGuard v0 zx2c4 Jason@zx2c4.com".as_bytes(), Some(&my_preshared[..]), &mut cipherstate1, &mut cipherstate2);
+       //TODO: specify psk2 mode
+       let mut handshake = HandshakeState::new_from_owner(&mut owner, true, HandshakePattern::IK, "WireGuard v1 zx2c4 Jason@zx2c4.com".as_bytes(), Some(&my_preshared[..]), &mut cipherstate1, &mut cipherstate2);
 
        let now = time::get_time();
        let mut tai64n = [0; 12];
-       BigEndian::write_i64(&mut tai64n[0..], 4611686018427387914ULL + now.sec);
+       BigEndian::write_i64(&mut tai64n[0..], 4611686018427387914 + now.sec);
        BigEndian::write_i32(&mut tai64n[8..], now.nsec);
        let mut initiation_packet = [0; 148];
        initiation_packet[0] = 1; /* Type: Initiation */
@@ -52,11 +53,13 @@ fn main() {
        initiation_packet[3] = 0; /* Reserved */
        LittleEndian::write_u32(&mut initiation_packet[4..], 28); /* Sender index: 28 (arbitrary) */
        handshake.write_message(&tai64n, &mut initiation_packet[8..]);
-       let mut mac_material = [0; 148];
-       memcpy(&mut mac_material, &their_public);
-       memcpy(&mut mac_material[32..], &initiation_packet[0..116]);
+       let mut mac_key_input = [0; 40];
+       let mut mac_key = [0; 32];
+       memcpy(&mut mac_key_input, b"mac1----");
+       memcpy(&mut mac_key_input[8..], &their_public);
+       Blake2s::blake2s(&mut mac_key, &mac_key_input, &[0; 0]);
        let mut mac = [0; 16];
-       Blake2s::blake2s(&mut mac, &mac_material, &my_preshared);
+       Blake2s::blake2s(&mut mac, &initiation_packet[0..116], &mac_key);
        memcpy(&mut initiation_packet[116..], &mac);
        socket.send_to(&initiation_packet, &send_addr).unwrap();
 
index 90544e24ba61db4a5d44c62a54f5bd28f58c2906..1b9a570d1506758cbcd6e756d6628189f03e26b7 100755 (executable)
@@ -9,20 +9,20 @@ while read -r -d $'\t' device; do
        if [[ $device != "$last_device" ]]; then
                [[ -z $last_device ]] && printf '\n' || printf '%s,\n' "$end"
                last_device="$device"
-               read -r private_key public_key preshared_key listen_port fwmark
+               read -r private_key public_key listen_port fwmark
                printf '\t"%s": {' "$device"
                delim=$'\n'
                [[ $private_key == "(none)" ]] || { printf '%s\t\t"privateKey": "%s"' "$delim" "$private_key"; delim=$',\n'; }
                [[ $public_key == "(none)" ]] || { printf '%s\t\t"publicKey": "%s"' "$delim" "$public_key"; delim=$',\n'; }
-               [[ $preshared_key == "(none)" ]] || { printf '%s\t\t"presharedKey": "%s"' "$delim" "$preshared_key"; delim=$',\n'; }
                [[ $listen_port == "0" ]] || { printf '%s\t\t"listenPort": %u' "$delim" $(( $listen_port )); delim=$',\n'; }
                [[ $fwmark == "off" ]] || { printf '%s\t\t"fwmark": %u' "$delim" $(( $fwmark )); delim=$',\n'; }
                printf '%s\t\t"peers": {' "$delim"; end=$'\n\t\t}\n\t}'
                delim=$'\n'
        else
-               read -r public_key endpoint allowed_ips latest_handshake transfer_rx transfer_tx persistent_keepalive
+               read -r public_key preshared_key endpoint allowed_ips latest_handshake transfer_rx transfer_tx persistent_keepalive
                printf '%s\t\t\t"%s": {' "$delim" "$public_key"
                delim=$'\n'
+               [[ $preshared_key == "(none)" ]] || { printf '%s\t\t\t\t"presharedKey": "%s"' "$delim" "$preshared_key"; delim=$',\n'; }
                [[ $endpoint == "(none)" ]] || { printf '%s\t\t\t\t"endpoint": "%s"' "$delim" "$endpoint"; delim=$',\n'; }
                [[ $latest_handshake == "0" ]] || { printf '%s\t\t\t\t"latestHandshake": %u' "$delim" $(( $latest_handshake )); delim=$',\n'; }
                [[ $transfer_rx == "0" ]] || { printf '%s\t\t\t\t"transferRx": %u' "$delim" $(( $transfer_rx )); delim=$',\n'; }
index 355012cf222f97b1bdab96d55f77c050d155f211..5401bc33216327c15332d8cac97d941a4421c186 100644 (file)
@@ -21,7 +21,7 @@ _wg_completion() {
        fi
 
        if [[ $COMP_CWORD -eq 3 && ${COMP_WORDS[1]} == show && ${COMP_WORDS[2]} != interfaces ]]; then
-               COMPREPLY+=( $(compgen -W "public-key private-key preshared-key listen-port peers endpoints allowed-ips fwmark latest-handshakes persistent-keepalive transfer dump" -- "${COMP_WORDS[3]}") )
+               COMPREPLY+=( $(compgen -W "public-key private-key listen-port peers preshared-keys endpoints allowed-ips fwmark latest-handshakes persistent-keepalive transfer dump" -- "${COMP_WORDS[3]}") )
                return
        fi
 
@@ -39,7 +39,6 @@ _wg_completion() {
                [[ ${COMP_WORDS[i]} == listen-port ]] && has_listen_port=1
                [[ ${COMP_WORDS[i]} == fwmark ]] && has_fwmark=1
                [[ ${COMP_WORDS[i]} == private-key ]] && has_private_key=1
-               [[ ${COMP_WORDS[i]} == preshared-key ]] && has_preshared_key=1
                [[ ${COMP_WORDS[i]} == peer ]] && { has_peer=$i; break; }
        done
        if [[ $has_peer -eq 0 ]]; then
@@ -47,7 +46,6 @@ _wg_completion() {
                        [[ $has_listen_port -eq 1 ]] || words+=( listen-port )
                        [[ $has_fwmark -eq 1 ]] || words+=( fwmark )
                        [[ $has_private_key -eq 1 ]] || words+=( private-key )
-                       [[ $has_preshared_key -eq 1 ]] || words+=( preshared-key )
                        words+=( peer )
                        COMPREPLY+=( $(compgen -W "${words[*]}" -- "${COMP_WORDS[COMP_CWORD]}") )
                elif [[ ${COMP_WORDS[COMP_CWORD-1]} == *-key ]]; then
@@ -70,6 +68,7 @@ _wg_completion() {
                        has_endpoint=0
                        has_persistent_keepalive=0
                        has_allowed_ips=0
+                       has_preshared_key=0
                        [[ ${COMP_WORDS[i+2]} == = ]] && ((i+=2)) || ((i++))
                        continue
                fi
@@ -77,6 +76,7 @@ _wg_completion() {
                [[ ${COMP_WORDS[i]} == endpoint ]] && has_endpoint=1
                [[ ${COMP_WORDS[i]} == persistent-keepalive ]] && has_persistent_keepalive=1
                [[ ${COMP_WORDS[i]} == allowed-ips ]] && has_allowed_ips=1
+               [[ ${COMP_WORDS[i]} == preshared-key ]] && has_preshared_key=1
 
                [[ ${COMP_WORDS[i]} == remove ]] || ((i++))
        done
@@ -84,6 +84,7 @@ _wg_completion() {
        ((COMP_CWORD == j)) || return
 
        if [[ $has_remove -ne 1 ]]; then
+               [[ $has_preshared_key -eq 1 ]] || words+=( preshared-key )
                [[ $has_endpoint -eq 1 ]] || words+=( endpoint )
                [[ $has_allowed_ips -eq 1 ]] || words+=( allowed-ips )
                [[ $has_persistent_keepalive -eq 1 ]] || words+=( persistent-keepalive )
index c00e91cf94ce7760ee5f475f6d8f986baf8fad8a..a1290889a5b74e9f7e9b080b313ea585b4172a51 100644 (file)
@@ -323,10 +323,6 @@ static bool process_line(struct config_ctx *ctx, const char *line)
                        ret = parse_key(ctx->buf.dev->private_key, value);
                        if (!ret)
                                memset(ctx->buf.dev->private_key, 0, WG_KEY_LEN);
-               } else if (key_match("PresharedKey")) {
-                       ret = parse_key(ctx->buf.dev->preshared_key, value);
-                       if (!ret)
-                               memset(ctx->buf.dev->preshared_key, 0, WG_KEY_LEN);
                } else
                        goto error;
        } else if (ctx->is_peer_section) {
@@ -338,7 +334,11 @@ static bool process_line(struct config_ctx *ctx, const char *line)
                        ret = parse_ipmasks(&ctx->buf, ctx->peer_offset, value);
                else if (key_match("PersistentKeepalive"))
                        ret = parse_persistent_keepalive(&peer_from_offset(ctx->buf.dev, ctx->peer_offset)->persistent_keepalive_interval, value);
-               else
+               else if (key_match("PresharedKey")) {
+                       ret = parse_key(peer_from_offset(ctx->buf.dev, ctx->peer_offset)->preshared_key, value);
+                       if (!ret)
+                               memset(peer_from_offset(ctx->buf.dev, ctx->peer_offset)->preshared_key, 0, WG_KEY_LEN);
+               } else
                        goto error;
        } else
                goto error;
@@ -408,8 +408,6 @@ bool config_read_finish(struct config_ctx *ctx)
                fprintf(stderr, "No private key configured\n");
                goto err;
        }
-       if (ctx->buf.dev->flags & WGDEVICE_REPLACE_PEERS && !key_is_valid(ctx->buf.dev->preshared_key))
-               ctx->buf.dev->flags |= WGDEVICE_REMOVE_PRESHARED_KEY;
        if (ctx->buf.dev->flags & WGDEVICE_REPLACE_PEERS && !ctx->buf.dev->fwmark)
                ctx->buf.dev->flags |= WGDEVICE_REMOVE_FWMARK;
 
@@ -508,21 +506,6 @@ bool config_read_cmd(struct wgdevice **device, char *argv[], int argc)
                                goto error;
                        argv += 2;
                        argc -= 2;
-               } else if (!strcmp(argv[0], "preshared-key") && argc >= 2 && !buf.dev->num_peers) {
-                       char *line;
-                       int ret = read_line(&line, argv[1]);
-                       if (ret == 0) {
-                               if (!parse_key(buf.dev->preshared_key, line)) {
-                                       free(line);
-                                       goto error;
-                               }
-                               free(line);
-                       } else if (ret == 1)
-                               buf.dev->flags |= WGDEVICE_REMOVE_PRESHARED_KEY;
-                       else
-                               goto error;
-                       argv += 2;
-                       argc -= 2;
                } else if (!strcmp(argv[0], "peer") && argc >= 2) {
                        peer_offset = buf.pos;
                        if (use_space(&buf, sizeof(struct wgpeer)) < 0) {
@@ -560,6 +543,22 @@ bool config_read_cmd(struct wgdevice **device, char *argv[], int argc)
                                goto error;
                        argv += 2;
                        argc -= 2;
+               } else if (!strcmp(argv[0], "preshared-key") && argc >= 2 && buf.dev->num_peers) {
+                       char *line;
+                       int ret = read_line(&line, argv[1]);
+                       if (ret == 0) {
+                               if (!parse_key(peer_from_offset(buf.dev, peer_offset)->preshared_key, line)) {
+                                       free(line);
+                                       goto error;
+                               }
+                               free(line);
+                       } else if (ret == 1) {
+                               free(line);
+                               buf.dev->flags |= WGPEER_REMOVE_PRESHARED_KEY;
+                       } else
+                               goto error;
+                       argv += 2;
+                       argc -= 2;
                } else {
                        fprintf(stderr, "Invalid argument: %s\n", argv[0]);
                        goto error;
index 5e4291ffe4fd2db4d07e26fa69b36f06128ffd2e..497edcc516aa773020d5705e85630ff5af9fbe29 100644 (file)
--- a/src/set.c
+++ b/src/set.c
@@ -13,7 +13,7 @@ int set_main(int argc, char *argv[])
        int ret = 1;
 
        if (argc < 3) {
-               fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [fwmark <mark>] [private-key <file path>] [peer <base64 public key> [remove] [endpoint <ip>:<port>] [persistent-keepalive <interval seconds>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...] ]...\n", PROG_NAME, argv[0]);
+               fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [fwmark <mark>] [private-key <file path>] [peer <base64 public key> [remove] [preshared-key <file path>] [endpoint <ip>:<port>] [persistent-keepalive <interval seconds>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...] ]...\n", PROG_NAME, argv[0]);
                return 1;
        }
 
index 813488341c6af184e7bd4361bfda5768577d3a37..7f67dbaac70652987e4431e59d43bf58d656a95d 100644 (file)
@@ -201,7 +201,7 @@ static char *bytes(uint64_t b)
 static const char *COMMAND_NAME = NULL;
 static void show_usage(void)
 {
-       fprintf(stderr, "Usage: %s %s { <interface> | all | interfaces } [public-key | private-key | preshared-key | listen-port | fwmark | peers | endpoints | allowed-ips | latest-handshakes | transfer | persistent-keepalive | dump]\n", PROG_NAME, COMMAND_NAME);
+       fprintf(stderr, "Usage: %s %s { <interface> | all | interfaces } [public-key | private-key | listen-port | fwmark | peers | preshared-keys | endpoints | allowed-ips | latest-handshakes | transfer | persistent-keepalive | dump]\n", PROG_NAME, COMMAND_NAME);
 }
 
 static void pretty_print(struct wgdevice *device)
@@ -216,8 +216,6 @@ static void pretty_print(struct wgdevice *device)
                terminal_printf("  " TERMINAL_BOLD "public key" TERMINAL_RESET ": %s\n", key(device->public_key));
        if (memcmp(device->private_key, zero, WG_KEY_LEN))
                terminal_printf("  " TERMINAL_BOLD "private key" TERMINAL_RESET ": %s\n", masked_key(device->private_key));
-       if (memcmp(device->preshared_key, zero, WG_KEY_LEN))
-               terminal_printf("  " TERMINAL_BOLD "preshared key" TERMINAL_RESET ": %s\n", masked_key(device->preshared_key));
        if (device->port)
                terminal_printf("  " TERMINAL_BOLD "listening port" TERMINAL_RESET ": %u\n", device->port);
        if (device->fwmark)
@@ -228,6 +226,8 @@ static void pretty_print(struct wgdevice *device)
        }
        for_each_wgpeer(device, peer, i) {
                terminal_printf(TERMINAL_FG_YELLOW TERMINAL_BOLD "peer" TERMINAL_RESET ": " TERMINAL_FG_YELLOW "%s" TERMINAL_RESET "\n", key(peer->public_key));
+               if (memcmp(peer->preshared_key, zero, WG_KEY_LEN))
+                       terminal_printf("  " TERMINAL_BOLD "preshared key" TERMINAL_RESET ": %s\n", masked_key(peer->preshared_key));
                if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)
                        terminal_printf("  " TERMINAL_BOLD "endpoint" TERMINAL_RESET ": %s\n", endpoint(&peer->endpoint.addr));
                terminal_printf("  " TERMINAL_BOLD "allowed ips" TERMINAL_RESET ": ");
@@ -260,7 +260,6 @@ static void dump_print(struct wgdevice *device, bool with_interface)
                printf("%s\t", device->interface);
        printf("%s\t", key(device->private_key));
        printf("%s\t", key(device->public_key));
-       printf("%s\t", key(device->preshared_key));
        printf("%u\t", device->port);
        if (device->fwmark)
                printf("0x%x\n", device->fwmark);
@@ -270,6 +269,7 @@ static void dump_print(struct wgdevice *device, bool with_interface)
                if (with_interface)
                        printf("%s\t", device->interface);
                printf("%s\t", key(peer->public_key));
+               printf("%s\t", key(peer->preshared_key));
                if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)
                        printf("%s\t", endpoint(&peer->endpoint.addr));
                else
@@ -301,10 +301,6 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int
                if (with_interface)
                        printf("%s\t", device->interface);
                printf("%s\n", key(device->private_key));
-       } else if (!strcmp(param, "preshared-key")) {
-               if (with_interface)
-                       printf("%s\t", device->interface);
-               printf("%s\n", key(device->preshared_key));
        } else if (!strcmp(param, "listen-port")) {
                if (with_interface)
                        printf("%s\t", device->interface);
@@ -358,6 +354,13 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int
                        else
                                printf("%s\toff\n", key(peer->public_key));
                }
+       } else if (!strcmp(param, "preshared-keys")) {
+               for_each_wgpeer(device, peer, i) {
+                       if (with_interface)
+                               printf("%s\t", device->interface);
+                       printf("%s\t", key(peer->public_key));
+                       printf("%s\n", key(peer->preshared_key));
+               }
        } else if (!strcmp(param, "peers")) {
                for_each_wgpeer(device, peer, i) {
                        if (with_interface)
index da4848648ea571419b924ec403f755d058b0bd4d..039abeedf1b4f46c7f179c25c0420a26b88adf82 100644 (file)
@@ -50,14 +50,14 @@ int showconf_main(int argc, char *argv[])
                key_to_base64(base64, device->private_key);
                printf("PrivateKey = %s\n", base64);
        }
-       if (memcmp(device->preshared_key, zero, WG_KEY_LEN)) {
-               key_to_base64(base64, device->preshared_key);
-               printf("PresharedKey = %s\n", base64);
-       }
        printf("\n");
        for_each_wgpeer(device, peer, i) {
                key_to_base64(base64, peer->public_key);
                printf("[Peer]\nPublicKey = %s\n", base64);
+               if (memcmp(peer->preshared_key, zero, WG_KEY_LEN)) {
+                       key_to_base64(base64, peer->preshared_key);
+                       printf("PresharedKey = %s\n", base64);
+               }
                if (peer->num_ipmasks)
                        printf("AllowedIPs = ");
                for_each_wgipmask(peer, ipmask, j) {
index 2aa800ec8329baf9b6feb70817b51a226822d3da..1517432701b046885bb3e55979cddb51ca3ca413 100644 (file)
--- a/src/wg.8
+++ b/src/wg.8
@@ -36,7 +36,7 @@ Sub-commands that take an INTERFACE must be passed a WireGuard interface.
 .SH COMMANDS
 
 .TP
-\fBshow\fP { \fI<interface>\fP | \fIall\fP | \fIinterfaces\fP } [\fIpublic-key\fP | \fIprivate-key\fP | \fIpreshared-key\fP | \fIlisten-port\fP | \fIfwmark\fP | \fIpeers\fP | \fIendpoints\fP | \fIallowed-ips\fP | \fIlatest-handshakes\fP | \fIpersistent-keepalive\fP | \fItransfer\fP | \fIdump\fP]
+\fBshow\fP { \fI<interface>\fP | \fIall\fP | \fIinterfaces\fP } [\fIpublic-key\fP | \fIprivate-key\fP | \fIlisten-port\fP | \fIfwmark\fP | \fIpeers\fP | \fIpreshared-keys\fP | \fIendpoints\fP | \fIallowed-ips\fP | \fIlatest-handshakes\fP | \fIpersistent-keepalive\fP | \fItransfer\fP | \fIdump\fP]
 Shows current WireGuard configuration of specified \fI<interface>\fP.
 If no \fI<interface>\fP is specified, \fI<interface>\fP defaults to \fIall\fP.
 If \fIinterfaces\fP is specified, prints a list of all WireGuard interfaces,
@@ -46,16 +46,16 @@ meant for the terminal. Otherwise, prints specified information grouped by
 newlines and tabs, meant to be used in scripts. For this script-friendly display,
 if \fIall\fP is specified, then the first field for all categories of information
 is the interface name. If \fPdump\fP is specified, then several lines are printed;
-the first contains in order separated by tab: private-key, public-key, preshared-key,
-listen-port, fwmark. Subsequent lines are printed for each peer and contain in order
-separated by tab: public-key, endpoint, allowed-ips, latest-handshake, transfer-rx,
-transfer-tx, persistent-keepalive.
+the first contains in order separated by tab: private-key, public-key, listen-port,
+fwmark. Subsequent lines are printed for each peer and contain in order separated
+by tab: public-key, preshared-key, endpoint, allowed-ips, latest-handshake,
+transfer-rx, transfer-tx, persistent-keepalive.
 .TP
 \fBshowconf\fP \fI<interface>\fP
 Shows the current configuration of \fI<interface>\fP in the format described
 by \fICONFIGURATION FILE FORMAT\fP below.
 .TP
-\fBset\fP \fI<interface>\fP [\fIlisten-port\fP \fI<port>\fP] [\fIfwmark\fP \fI<fwmark>\fP] [\fIprivate-key\fP \fI<file-path>\fP] [\fIpreshared-key\fP \fI<file-path>\fP] [\fIpeer\fP \fI<base64-public-key>\fP [\fIremove\fP] [\fIendpoint\fP \fI<ip>:<port>\fP] [\fIpersistent-keepalive\fP \fI<interval seconds>\fP] [\fIallowed-ips\fP \fI<ip1>/<cidr1>\fP[,\fI<ip2>/<cidr2>\fP]...] ]...
+\fBset\fP \fI<interface>\fP [\fIlisten-port\fP \fI<port>\fP] [\fIfwmark\fP \fI<fwmark>\fP] [\fIprivate-key\fP \fI<file-path>\fP] [\fIpeer\fP \fI<base64-public-key>\fP [\fIremove\fP] [\fIpreshared-key\fP \fI<file-path>\fP] [\fIendpoint\fP \fI<ip>:<port>\fP] [\fIpersistent-keepalive\fP \fI<interval seconds>\fP] [\fIallowed-ips\fP \fI<ip1>/<cidr1>\fP[,\fI<ip2>/<cidr2>\fP]...] ]...
 Sets configuration values for the specified \fI<interface>\fP. Multiple
 \fIpeer\fPs may be specified, and if the \fIremove\fP argument is given
 for a peer, that peer is removed, not configured. If \fIlisten-port\fP
@@ -126,11 +126,6 @@ The \fIInterface\fP section may contain the following fields:
 .IP \(bu
 PrivateKey \(em a base64 private key generated by \fIwg genkey\fP. Required.
 .IP \(bu
-PresharedKey \(em a base64 preshared key generated by \fIwg genpsk\fP. Optional,
-and may be omitted. This option adds an additional layer of symmetric-key
-cryptography to be mixed into the already existing public-key cryptography,
-for post-quantum resistance.
-.IP \(bu
 ListenPort \(em a 16-bit port for listening. Optional; if not specified, chosen
 randomly.
 .IP \(bu
@@ -143,6 +138,11 @@ PublicKey \(em a base64 public key calculated by \fIwg pubkey\fP from a
 private key, and usually transmitted out of band to the author of the
 configuration file. Required.
 .IP \(bu
+PresharedKey \(em a base64 preshared key generated by \fIwg genpsk\fP. Optional,
+and may be omitted. This option adds an additional layer of symmetric-key
+cryptography to be mixed into the already existing public-key cryptography,
+for post-quantum resistance.
+.IP \(bu
 AllowedIPs \(em a comma-separated list of ip (v4 or v6) addresses with
 CIDR masks from which this peer is allowed to send incoming traffic and
 to which outgoing traffic for this peer is directed. The catch-all