wg: side channel resistant base64
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
d42dd68add
commit
755217bd85
|
@ -36,7 +36,6 @@ CFLAGS += -std=gnu11
|
|||
CFLAGS += -Wall -Wextra
|
||||
CFLAGS += -MMD -MP
|
||||
CFLAGS += -DRUNSTATEDIR="\"$(RUNSTATEDIR)\""
|
||||
LDLIBS += -lresolv
|
||||
ifeq ($(shell uname -s),Linux)
|
||||
LIBMNL_CFLAGS := $(shell $(PKG_CONFIG) --cflags libmnl 2>/dev/null)
|
||||
LIBMNL_LDLIBS := $(shell $(PKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl)
|
||||
|
|
252
src/base64.c
252
src/base64.c
|
@ -1,220 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 1998 by Internet Software Consortium.
|
||||
/* Copyright (C) 2015-2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Portions Copyright (c) 1995 by International Business Machines, Inc.
|
||||
*
|
||||
* International Business Machines, Inc. (hereinafter called IBM) grants
|
||||
* permission under its copyrights to use, copy, modify, and distribute this
|
||||
* Software with or without fee, provided that the above copyright notice and
|
||||
* all paragraphs of this notice appear in all copies, and that the name of IBM
|
||||
* not be used in connection with the marketing of any product incorporating
|
||||
* the Software or modifications thereof, without specific, written prior
|
||||
* permission.
|
||||
*
|
||||
* To the extent it has a right to do so, IBM grants an immunity from suit
|
||||
* under its patents, if any, for the use, sale or manufacture of products to
|
||||
* the extent that such products are used for performing Domain Name System
|
||||
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
|
||||
* granted for any product per se or for any other function of any product.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
|
||||
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
|
||||
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
* This is a specialized constant-time base64 implementation that resists side-channel attacks.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "base64.h"
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined(NEED_B64_NTOP) || defined(NEED_B64_PTON)
|
||||
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
static const char pad64 = '=';
|
||||
#endif
|
||||
|
||||
#ifdef NEED_B64_NTOP
|
||||
int b64_ntop(unsigned char const *src, size_t srclength, char *target, size_t targsize)
|
||||
static inline void encode(char dest[4], const uint8_t src[3])
|
||||
{
|
||||
size_t datalength = 0;
|
||||
uint8_t input[3];
|
||||
uint8_t output[4];
|
||||
size_t i;
|
||||
const uint8_t input[] = { (src[0] >> 2) & 63, ((src[0] << 4) | (src[1] >> 4)) & 63, ((src[1] << 2) | (src[2] >> 6)) & 63, src[2] & 63 };
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
dest[i] = input[i] + 'A'
|
||||
+ (((25 - input[i]) >> 8) & 6)
|
||||
- (((51 - input[i]) >> 8) & 75)
|
||||
- (((61 - input[i]) >> 8) & 15)
|
||||
+ (((62 - input[i]) >> 8) & 3);
|
||||
|
||||
while (2 < srclength) {
|
||||
input[0] = *src++;
|
||||
input[1] = *src++;
|
||||
input[2] = *src++;
|
||||
srclength -= 3;
|
||||
|
||||
output[0] = input[0] >> 2;
|
||||
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
||||
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
||||
output[3] = input[2] & 0x3f;
|
||||
assert(output[0] < 64);
|
||||
assert(output[1] < 64);
|
||||
assert(output[2] < 64);
|
||||
assert(output[3] < 64);
|
||||
|
||||
if (datalength + 4 > targsize)
|
||||
return -1;
|
||||
target[datalength++] = base64[output[0]];
|
||||
target[datalength++] = base64[output[1]];
|
||||
target[datalength++] = base64[output[2]];
|
||||
target[datalength++] = base64[output[3]];
|
||||
}
|
||||
if (0 != srclength) {
|
||||
input[0] = input[1] = input[2] = '\0';
|
||||
for (i = 0; i < srclength; i++)
|
||||
input[i] = *src++;
|
||||
output[0] = input[0] >> 2;
|
||||
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
||||
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
||||
assert(output[0] < 64);
|
||||
assert(output[1] < 64);
|
||||
assert(output[2] < 64);
|
||||
|
||||
if (datalength + 4 > targsize)
|
||||
return -1;
|
||||
target[datalength++] = base64[output[0]];
|
||||
target[datalength++] = base64[output[1]];
|
||||
if (srclength == 1)
|
||||
target[datalength++] = pad64;
|
||||
else
|
||||
target[datalength++] = base64[output[2]];
|
||||
target[datalength++] = pad64;
|
||||
}
|
||||
if (datalength >= targsize)
|
||||
return (-1);
|
||||
target[datalength] = '\0';
|
||||
return datalength;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NEED_B64_PTON
|
||||
int b64_pton(char const *src, uint8_t *target, size_t targsize)
|
||||
void key_to_base64(char base64[static WG_KEY_LEN_BASE64], const uint8_t key[static WG_KEY_LEN])
|
||||
{
|
||||
static int b64rmap_initialized = 0;
|
||||
static uint8_t b64rmap[256];
|
||||
static const uint8_t b64rmap_special = 0xf0;
|
||||
static const uint8_t b64rmap_end = 0xfd;
|
||||
static const uint8_t b64rmap_space = 0xfe;
|
||||
static const uint8_t b64rmap_invalid = 0xff;
|
||||
int tarindex, state, ch;
|
||||
uint8_t ofs;
|
||||
|
||||
if (!b64rmap_initialized) {
|
||||
int i;
|
||||
char ch;
|
||||
b64rmap[0] = b64rmap_end;
|
||||
for (i = 1; i < 256; ++i) {
|
||||
ch = (char)i;
|
||||
if (isspace(ch))
|
||||
b64rmap[i] = b64rmap_space;
|
||||
else if (ch == pad64)
|
||||
b64rmap[i] = b64rmap_end;
|
||||
else
|
||||
b64rmap[i] = b64rmap_invalid;
|
||||
}
|
||||
for (i = 0; base64[i] != '\0'; ++i)
|
||||
b64rmap[(uint8_t)base64[i]] = i;
|
||||
b64rmap_initialized = 1;
|
||||
unsigned int i;
|
||||
for (i = 0; i < WG_KEY_LEN / 3; ++i)
|
||||
encode(&base64[i * 4], &key[i * 3]);
|
||||
encode(&base64[i * 4], (const uint8_t[]){ key[i * 3 + 0], key[i * 3 + 1], 0 });
|
||||
base64[WG_KEY_LEN_BASE64 - 2] = '=';
|
||||
base64[WG_KEY_LEN_BASE64 - 1] = '\0';
|
||||
}
|
||||
|
||||
state = 0;
|
||||
tarindex = 0;
|
||||
|
||||
for (;;) {
|
||||
ch = *src++;
|
||||
ofs = b64rmap[ch];
|
||||
|
||||
if (ofs >= b64rmap_special) {
|
||||
if (ofs == b64rmap_space)
|
||||
continue;
|
||||
if (ofs == b64rmap_end)
|
||||
break;
|
||||
return -1;
|
||||
static inline int decode(const char src[4])
|
||||
{
|
||||
int val = 0;
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
val |= (-1
|
||||
+ ((((('A' - 1) - src[i]) & (src[i] - ('Z' + 1))) >> 8) & (src[i] - 64))
|
||||
+ ((((('a' - 1) - src[i]) & (src[i] - ('z' + 1))) >> 8) & (src[i] - 70))
|
||||
+ ((((('0' - 1) - src[i]) & (src[i] - ('9' + 1))) >> 8) & (src[i] + 5))
|
||||
+ ((((('+' - 1) - src[i]) & (src[i] - ('+' + 1))) >> 8) & 63)
|
||||
+ ((((('/' - 1) - src[i]) & (src[i] - ('/' + 1))) >> 8) & 64)
|
||||
) << (18 - 6 * i);
|
||||
return val;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if ((size_t)tarindex >= targsize)
|
||||
return -1;
|
||||
target[tarindex] = ofs << 2;
|
||||
state = 1;
|
||||
break;
|
||||
case 1:
|
||||
if ((size_t)tarindex + 1 >= targsize)
|
||||
return -1;
|
||||
target[tarindex] |= ofs >> 4;
|
||||
target[tarindex+1] = (ofs & 0x0f) << 4 ;
|
||||
tarindex++;
|
||||
state = 2;
|
||||
break;
|
||||
case 2:
|
||||
if ((size_t)tarindex + 1 >= targsize)
|
||||
return -1;
|
||||
target[tarindex] |= ofs >> 2;
|
||||
target[tarindex+1] = (ofs & 0x03) << 6;
|
||||
tarindex++;
|
||||
state = 3;
|
||||
break;
|
||||
case 3:
|
||||
if ((size_t)tarindex >= targsize)
|
||||
return -1;
|
||||
target[tarindex] |= ofs;
|
||||
tarindex++;
|
||||
state = 0;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
bool key_from_base64(uint8_t key[static WG_KEY_LEN], const char *base64)
|
||||
{
|
||||
unsigned int i;
|
||||
int val;
|
||||
if (strlen(base64) != WG_KEY_LEN_BASE64 - 1 || base64[WG_KEY_LEN_BASE64 - 2] != '=')
|
||||
return false;
|
||||
|
||||
if (ch == pad64) {
|
||||
ch = *src++;
|
||||
switch (state) {
|
||||
case 0:
|
||||
case 1:
|
||||
return -1;
|
||||
|
||||
case 2:
|
||||
for (; ch; ch = *src++) {
|
||||
if (b64rmap[ch] != b64rmap_space)
|
||||
break;
|
||||
for (i = 0; i < WG_KEY_LEN / 3; ++i) {
|
||||
val = decode(&base64[i * 4]);
|
||||
if (val < 0)
|
||||
return false;
|
||||
key[i * 3 + 0] = (val >> 16) & 0xff;
|
||||
key[i * 3 + 1] = (val >> 8) & 0xff;
|
||||
key[i * 3 + 2] = val & 0xff;
|
||||
}
|
||||
if (ch != pad64)
|
||||
return -1;
|
||||
ch = *src++;
|
||||
case 3:
|
||||
for (; ch; ch = *src++) {
|
||||
if (b64rmap[ch] != b64rmap_space)
|
||||
return -1;
|
||||
val = decode((const char[]){ base64[i * 4 + 0], base64[i * 4 + 1], base64[i * 4 + 2], 'A' });
|
||||
if (val < 0 || val & 0xff)
|
||||
return false;
|
||||
key[i * 3 + 0] = (val >> 16) & 0xff;
|
||||
key[i * 3 + 1] = (val >> 8) & 0xff;
|
||||
return true;
|
||||
}
|
||||
if (target[tarindex] != 0)
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (state != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return tarindex;
|
||||
}
|
||||
#endif
|
||||
|
|
17
src/base64.h
17
src/base64.h
|
@ -3,18 +3,13 @@
|
|||
#ifndef BASE64_H
|
||||
#define BASE64_H
|
||||
|
||||
#include <resolv.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "../uapi.h"
|
||||
|
||||
#define b64_len(len) ((((len) + 2) / 3) * 4 + 1)
|
||||
#define WG_KEY_LEN_BASE64 ((((WG_KEY_LEN) + 2) / 3) * 4 + 1)
|
||||
|
||||
#ifndef b64_ntop
|
||||
int b64_ntop(unsigned char const *, size_t, char *, size_t);
|
||||
#define NEED_B64_NTOP
|
||||
#endif
|
||||
|
||||
#ifndef b64_pton
|
||||
int b64_pton(char const *, unsigned char *, size_t);
|
||||
#define NEED_B64_PTON
|
||||
#endif
|
||||
void key_to_base64(char base64[static WG_KEY_LEN_BASE64], const uint8_t key[static WG_KEY_LEN]);
|
||||
bool key_from_base64(uint8_t key[static WG_KEY_LEN], const char *base64);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -118,12 +118,10 @@ static inline bool parse_fwmark(uint32_t *fwmark, unsigned int *flags, const cha
|
|||
|
||||
static inline bool parse_key(uint8_t key[static WG_KEY_LEN], const char *value)
|
||||
{
|
||||
uint8_t tmp[WG_KEY_LEN + 1];
|
||||
if (strlen(value) != b64_len(WG_KEY_LEN) - 1 || b64_pton(value, tmp, WG_KEY_LEN + 1) != WG_KEY_LEN) {
|
||||
if (!key_from_base64(key, value)) {
|
||||
fprintf(stderr, "Key is not the correct length or format: `%s`\n", value);
|
||||
return false;
|
||||
}
|
||||
memcpy(key, tmp, WG_KEY_LEN);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
17
src/genkey.c
17
src/genkey.c
|
@ -34,8 +34,8 @@ static inline ssize_t get_random_bytes(uint8_t *out, size_t len)
|
|||
|
||||
int genkey_main(int argc, char *argv[])
|
||||
{
|
||||
unsigned char private_key[CURVE25519_POINT_SIZE];
|
||||
char private_key_base64[b64_len(CURVE25519_POINT_SIZE)];
|
||||
uint8_t key[WG_KEY_LEN];
|
||||
char base64[WG_KEY_LEN_BASE64];
|
||||
struct stat stat;
|
||||
|
||||
if (argc != 1) {
|
||||
|
@ -46,19 +46,14 @@ int genkey_main(int argc, char *argv[])
|
|||
if (!fstat(STDOUT_FILENO, &stat) && S_ISREG(stat.st_mode) && stat.st_mode & S_IRWXO)
|
||||
fputs("Warning: writing to world accessible file.\nConsider setting the umask to 077 and trying again.\n", stderr);
|
||||
|
||||
if (get_random_bytes(private_key, CURVE25519_POINT_SIZE) != CURVE25519_POINT_SIZE) {
|
||||
if (get_random_bytes(key, WG_KEY_LEN) != WG_KEY_LEN) {
|
||||
perror("getrandom");
|
||||
return 1;
|
||||
}
|
||||
if (argc && !strcmp(argv[0], "genkey"))
|
||||
curve25519_normalize_secret(private_key);
|
||||
curve25519_normalize_secret(key);
|
||||
|
||||
if (b64_ntop(private_key, sizeof(private_key), private_key_base64, sizeof(private_key_base64)) != sizeof(private_key_base64) - 1) {
|
||||
fprintf(stderr, "%s: Could not convert key to base64\n", PROG_NAME);
|
||||
return 1;
|
||||
}
|
||||
|
||||
puts(private_key_base64);
|
||||
key_to_base64(base64, key);
|
||||
puts(base64);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
|
|
@ -177,7 +177,7 @@ static int userspace_set_device(struct wgdevice *dev)
|
|||
if (fd < 0)
|
||||
return fd;
|
||||
for_each_wgpeer(dev, peer, len);
|
||||
len = (unsigned char *)peer - (unsigned char *)dev;
|
||||
len = (uint8_t *)peer - (uint8_t *)dev;
|
||||
ret = -EBADMSG;
|
||||
if (!len)
|
||||
goto out;
|
||||
|
|
19
src/pubkey.c
19
src/pubkey.c
|
@ -1,7 +1,6 @@
|
|||
/* Copyright (C) 2015-2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
@ -11,8 +10,8 @@
|
|||
|
||||
int pubkey_main(int argc, char *argv[])
|
||||
{
|
||||
unsigned char private_key[CURVE25519_POINT_SIZE + 1] = { 0 }, public_key[CURVE25519_POINT_SIZE] = { 0 };
|
||||
char private_key_base64[b64_len(CURVE25519_POINT_SIZE)] = { 0 }, public_key_base64[b64_len(CURVE25519_POINT_SIZE)] = { 0 };
|
||||
uint8_t key[WG_KEY_LEN];
|
||||
char base64[WG_KEY_LEN_BASE64];
|
||||
int trailing_char;
|
||||
|
||||
if (argc != 1) {
|
||||
|
@ -20,11 +19,12 @@ int pubkey_main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (fread(private_key_base64, 1, sizeof(private_key_base64) - 1, stdin) != sizeof(private_key_base64) - 1) {
|
||||
if (fread(base64, 1, sizeof(base64) - 1, stdin) != sizeof(base64) - 1) {
|
||||
errno = EINVAL;
|
||||
fprintf(stderr, "%s: Key is not the correct length or format\n", PROG_NAME);
|
||||
return 1;
|
||||
}
|
||||
base64[WG_KEY_LEN_BASE64 - 1] = '\0';
|
||||
|
||||
for (;;) {
|
||||
trailing_char = getc(stdin);
|
||||
|
@ -36,15 +36,12 @@ int pubkey_main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (b64_pton(private_key_base64, private_key, sizeof(private_key)) != sizeof(private_key) - 1) {
|
||||
if (!key_from_base64(key, base64)) {
|
||||
fprintf(stderr, "%s: Key is not the correct length or format\n", PROG_NAME);
|
||||
return 1;
|
||||
}
|
||||
curve25519_generate_public(public_key, private_key);
|
||||
if (b64_ntop(public_key, sizeof(public_key), public_key_base64, sizeof(public_key_base64)) != sizeof(public_key_base64) - 1) {
|
||||
fprintf(stderr, "%s: Could not convert key to base64\n", PROG_NAME);
|
||||
return 1;
|
||||
}
|
||||
puts(public_key_base64);
|
||||
curve25519_generate_public(key, key);
|
||||
key_to_base64(base64, key);
|
||||
puts(base64);
|
||||
return 0;
|
||||
}
|
||||
|
|
12
src/show.c
12
src/show.c
|
@ -4,7 +4,6 @@
|
|||
#include <inttypes.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <resolv.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
@ -78,17 +77,16 @@ static void sort_peers(struct wgdevice *device)
|
|||
|
||||
static const uint8_t zero[WG_KEY_LEN] = { 0 };
|
||||
|
||||
static char *key(const unsigned char key[static WG_KEY_LEN])
|
||||
static char *key(const uint8_t key[static WG_KEY_LEN])
|
||||
{
|
||||
static char b64[b64_len(WG_KEY_LEN)];
|
||||
static char base64[WG_KEY_LEN_BASE64];
|
||||
if (!memcmp(key, zero, WG_KEY_LEN))
|
||||
return "(none)";
|
||||
memset(b64, 0, b64_len(WG_KEY_LEN));
|
||||
b64_ntop(key, WG_KEY_LEN, b64, b64_len(WG_KEY_LEN));
|
||||
return b64;
|
||||
key_to_base64(base64, key);
|
||||
return base64;
|
||||
}
|
||||
|
||||
static char *masked_key(const unsigned char masked_key[static WG_KEY_LEN])
|
||||
static char *masked_key(const uint8_t masked_key[static WG_KEY_LEN])
|
||||
{
|
||||
const char *var = getenv("WG_HIDE_KEYS");
|
||||
if (var && !strcmp(var, "never"))
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <resolv.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -18,7 +17,7 @@
|
|||
int showconf_main(int argc, char *argv[])
|
||||
{
|
||||
static const uint8_t zero[WG_KEY_LEN] = { 0 };
|
||||
char b64[b64_len(WG_KEY_LEN)] = { 0 };
|
||||
char base64[WG_KEY_LEN_BASE64];
|
||||
char ip[INET6_ADDRSTRLEN];
|
||||
struct wgdevice *device = NULL;
|
||||
struct wgpeer *peer;
|
||||
|
@ -48,17 +47,17 @@ int showconf_main(int argc, char *argv[])
|
|||
if (device->fwmark)
|
||||
printf("FwMark = 0x%x\n", device->fwmark);
|
||||
if (memcmp(device->private_key, zero, WG_KEY_LEN)) {
|
||||
b64_ntop(device->private_key, WG_KEY_LEN, b64, b64_len(WG_KEY_LEN));
|
||||
printf("PrivateKey = %s\n", b64);
|
||||
key_to_base64(base64, device->private_key);
|
||||
printf("PrivateKey = %s\n", base64);
|
||||
}
|
||||
if (memcmp(device->preshared_key, zero, WG_KEY_LEN)) {
|
||||
b64_ntop(device->preshared_key, WG_KEY_LEN, b64, b64_len(WG_KEY_LEN));
|
||||
printf("PresharedKey = %s\n", b64);
|
||||
key_to_base64(base64, device->preshared_key);
|
||||
printf("PresharedKey = %s\n", base64);
|
||||
}
|
||||
printf("\n");
|
||||
for_each_wgpeer(device, peer, i) {
|
||||
b64_ntop(peer->public_key, WG_KEY_LEN, b64, b64_len(WG_KEY_LEN));
|
||||
printf("[Peer]\nPublicKey = %s\n", b64);
|
||||
key_to_base64(base64, peer->public_key);
|
||||
printf("[Peer]\nPublicKey = %s\n", base64);
|
||||
if (peer->num_ipmasks)
|
||||
printf("AllowedIPs = ");
|
||||
for_each_wgipmask(peer, ipmask, j) {
|
||||
|
|
Loading…
Reference in New Issue