vpn-btcpay-provisioner/app/static/js/utils/wireguard.js

134 lines
3.4 KiB
JavaScript
Raw Normal View History

2024-12-30 07:07:53 +00:00
// Base64 encoding/decoding utilities with error handling
2024-12-30 06:03:07 +00:00
const b64 = {
2024-12-30 07:07:53 +00:00
encode: (array) => {
try {
return btoa(String.fromCharCode.apply(null, array));
} catch (error) {
console.error('Base64 encoding failed:', error);
throw new Error('Failed to encode key data');
}
},
decode: (str) => {
try {
return Uint8Array.from(atob(str), c => c.charCodeAt(0));
} catch (error) {
console.error('Base64 decoding failed:', error);
throw new Error('Failed to decode key data');
}
2024-12-30 06:03:07 +00:00
}
2024-12-30 07:07:53 +00:00
};
// Key storage management
const keyStorage = {
store: (userId, keyData) => {
try {
const data = {
privateKey: keyData.privateKey,
publicKey: keyData.publicKey,
createdAt: new Date().toISOString()
};
localStorage.setItem(`vpn_keys_${userId}`, JSON.stringify(data));
} catch (error) {
console.error('Failed to store keys:', error);
throw new Error('Failed to save key data');
}
},
retrieve: (userId) => {
try {
const data = localStorage.getItem(`vpn_keys_${userId}`);
return data ? JSON.parse(data) : null;
} catch (error) {
console.error('Failed to retrieve keys:', error);
throw new Error('Failed to retrieve key data');
}
},
remove: (userId) => {
try {
localStorage.removeItem(`vpn_keys_${userId}`);
} catch (error) {
console.error('Failed to remove keys:', error);
}
2024-12-30 06:03:07 +00:00
}
2024-12-30 07:07:53 +00:00
};
// Main key generation function
async function generateKeyPair() {
try {
const keyPair = await window.crypto.subtle.generateKey(
{
name: 'X25519',
namedCurve: 'X25519',
},
true,
['deriveKey', 'deriveBits']
);
const privateKey = await window.crypto.subtle.exportKey('raw', keyPair.privateKey);
const publicKey = await window.crypto.subtle.exportKey('raw', keyPair.publicKey);
return {
privateKey: b64.encode(new Uint8Array(privateKey)),
publicKey: b64.encode(new Uint8Array(publicKey))
};
} catch (error) {
console.error('Key generation failed:', error);
throw new Error('Failed to generate WireGuard keys');
}
}
// Key validation function
function validateKey(key) {
try {
const decoded = b64.decode(key);
return decoded.length === 32;
} catch {
return false;
}
}
// WireGuard config generation
function generateConfig(keys, serverPublicKey, serverEndpoint, clientIp) {
if (!keys || !serverPublicKey || !serverEndpoint || !clientIp) {
throw new Error('Missing required configuration parameters');
}
return `[Interface]
PrivateKey = ${keys.privateKey}
Address = ${clientIp}/24
DNS = 1.1.1.1
[Peer]
PublicKey = ${serverPublicKey}
Endpoint = ${serverEndpoint}:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25`;
}
// Main interface for key management
export const WireGuard = {
generateKeys: async () => {
2024-12-30 06:03:07 +00:00
return await generateKeyPair();
2024-12-30 07:07:53 +00:00
},
saveKeys: (userId, keyPair) => {
if (!validateKey(keyPair.publicKey) || !validateKey(keyPair.privateKey)) {
throw new Error('Invalid key data');
}
keyStorage.store(userId, keyPair);
},
getKeys: (userId) => {
return keyStorage.retrieve(userId);
},
removeKeys: (userId) => {
keyStorage.remove(userId);
},
generateConfig,
validateKey
};
export default WireGuard;