aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/contrib/examples/keygen-html/keygen.html
blob: d9365e08332d4a270acf2fbf27529f1e152acde5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
<script src="curve25519_generate.js" onError='document.write("<h3>Did you forget to run \"make\" to compile curve25519_generate.js?</h3><!--");'></script>
<script>
/* SPDX-License-Identifier: GPL-2.0
 *
 * Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 */

function sendPubkeyToServer(pubkey, username, password)
{
	var node = document.createElement("li");
	node.innerText = "Sending " + username + ":" + password + " to server for new pubkey " + pubkey + "...";
	document.body.appendChild(node);

	// send info to server

	var serverResponse = {
		publicKey: "6spHEFoJrp9pijbxjJoS6fHjZaAWQqtdFFO/OtpVe3w=",
		allowedIPs: [ "0.0.0.0/0", "::/0" ],
		endpoint: "demo.wireguard.com:63321",
		address: [ "192.168.18.42/32", "fd08:1234:1111::77/128" ],
		dns: [ "8.8.8.8", "8.8.4.4" ]
	}

	return serverResponse;
}

function downloadNewConfiguration()
{
	var keypair = WireGuard.generateKeypair();
	var serverResponse = sendPubkeyToServer(keypair.publicKey, "zx2c4", "supersecretpassword");

	var config = [];
	config.push("[Interface]");
	config.push("PrivateKey = " + keypair.privateKey);
	config.push("Address = " + serverResponse.address.join(", "));
	config.push("DNS = " + serverResponse.dns.join(", "));
	config.push("");
	config.push("[Peer]");
	config.push("PublicKey = " + serverResponse.publicKey);
	config.push("AllowedIPs = " + serverResponse.allowedIPs.join(", "));
	config.push("Endpoint = " + serverResponse.endpoint);
	config.push("");
	return config.join("\n");
}

function giveOneConfigurationToUser()
{
	var config = downloadNewConfiguration();
	var blob = new Blob([config], { type: "text/plain" });
	var a = document.createElement("a");
	a.download = "demo0.conf";
	a.href = URL.createObjectURL(blob);
	a.style.display = "none";
	document.body.appendChild(a);
	a.click();
	document.body.removeChild(a);
}

function putU32(b, n)
{
	b.push(n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, (n >>> 24) & 0xff);
}

function putU16(b, n)
{
	b.push(n & 0xff, (n >>> 8) & 0xff);
}

function putBytes(b, a)
{
	for (var i = 0; i < a.length; ++i)
		b.push(a[i] & 0xff);
}

function encodeString(s)
{
	var utf8 = unescape(encodeURIComponent(s));
	var b = new Uint8Array(utf8.length);
	for (var i = 0; i < utf8.length; ++i)
		b[i] = utf8.charCodeAt(i);
	return b;
}

function crc32(b)
{
	if (!crc32.table) {
		crc32.table = [];
		for (var c = 0, n = 0; n < 256; c = ++n) {
			for (var k = 0; k < 8; ++k)
				c = ((c & 1) ? (0xedb88320 ^ (c >>> 1)) : (c >>> 1));
			crc32.table[n] = c;
		}
	}
	var crc = -1;
	for (var i = 0; i < b.length; ++i)
		crc = (crc >>> 8) ^ crc32.table[(crc ^ b[i]) & 0xff];
	return (crc ^ (-1)) >>> 0;
}

function createZipFile(files)
{
	var b = [];
	var cd = [];
	var offset = 0;

	for (var i = 0; i < files.length; ++i) {
		var name = encodeString(files[i].name);
		var contents = encodeString(files[i].contents);
		var crc = crc32(contents);

		putU32(b, 0x04034b50); /* signature */
		putU16(b, 20); /* version needed */
		putU16(b, 0); /* flags */
		putU16(b, 0); /* compression method */
		putU16(b, 0); /* mtime */
		putU16(b, 0); /* mdate */
		putU32(b, crc); /* crc32 */
		putU32(b, contents.length); /* compressed size */
		putU32(b, contents.length); /* uncompressed size */
		putU16(b, name.length); /* file name length */
		putU16(b, 0); /* extra field length */
		putBytes(b, name);
		putBytes(b, contents);

		putU32(cd, 0x02014b50); /* signature */
		putU16(cd, 0); /* version made */
		putU16(cd, 20); /* version needed */
		putU16(cd, 0); /* flags */
		putU16(cd, 0); /* compression method */
		putU16(cd, 0); /* mtime */
		putU16(cd, 0); /* mdate */
		putU32(cd, crc); /* crc32 */
		putU32(cd, contents.length); /* compressed size */
		putU32(cd, contents.length); /* uncompressed size */
		putU16(cd, name.length); /* file name length */
		putU16(cd, 0); /* extra field length */
		putU16(cd, 0); /* file comment length */
		putU16(cd, 0); /* disk number start */
		putU16(cd, 0); /* internal file attributes */
		putU32(cd, 32); /* external file attributes - 'archive' bit set (32) */
		putU32(cd, offset); /* relative offset of local header */
		putBytes(cd, name); /* file name */

		offset += 30 + contents.length + name.length
	}
	putBytes(b, cd); /* central directory */
	putU32(b, 0x06054b50); /* end of central directory signature */
	putU16(b, 0); /* number of this disk */
	putU16(b, 0); /* number of disk with central directory start */
	putU16(b, files.length); /* number of entries on disk */
	putU16(b, files.length); /* number of entries */
	putU32(b, cd.length); /* length of central directory */
	putU32(b, offset); /* offset to start of central directory */
	putU16(b, 0); /* zip comment size */
	return Uint8Array.from(b);
}

function giveMultipleConfigurationsToUser()
{
	var zipFile = createZipFile([
		{ name: "demo0.conf", contents: downloadNewConfiguration() },
		{ name: "demo1.conf", contents: downloadNewConfiguration() },
		{ name: "demo2.conf", contents: downloadNewConfiguration() }
	]);
	var blob = new Blob([zipFile], { type: "application/zip" });
	var a = document.createElement("a");
	a.download = "demo-configs.zip";
	a.href = URL.createObjectURL(blob);
	a.style.display = "none";
	document.body.appendChild(a);
	a.click();
	document.body.removeChild(a);
}

</script>

<p><a href="javascript:giveOneConfigurationToUser()">Download a WireGuard configuration file</a></p>
<p><a href="javascript:giveMultipleConfigurationsToUser()">Download several WireGuard configuration files</a></p>