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

117 lines
3.8 KiB
JavaScript
Raw Normal View History

// Base64 encoding/decoding utilities
2024-12-30 06:03:07 +00:00
const b64 = {
encode: (array) => {
try {
return btoa(String.fromCharCode.apply(null, array))
.replace(/[+/]/g, char => char === '+' ? '-' : '_')
.replace(/=+$/, '');
} catch (error) {
console.error('Base64 encoding failed:', error);
throw new Error('Failed to encode key data');
}
},
decode: (str) => {
try {
str = str.replace(/[-_]/g, char => char === '-' ? '+' : '/');
while (str.length % 4) str += '=';
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 07:07:53 +00:00
};
// Check if we're in a secure context (HTTPS) or development mode
const isDevelopment = window.location.hostname === 'localhost' ||
window.location.hostname === '127.0.0.1' ||
/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(window.location.hostname);
2024-12-30 07:07:53 +00:00
// Generate secure random bytes
async function getRandomBytes(length) {
const array = new Uint8Array(length);
crypto.getRandomValues(array);
return array;
2024-12-30 07:07:53 +00:00
}
// Generate a WireGuard key pair
async function generateKeyPair() {
try {
console.log('Generating WireGuard keys...');
console.log('Environment:', isDevelopment ? 'Development' : 'Production');
// Generate private key (32 random bytes)
const privateKeyBytes = await getRandomBytes(32);
const privateKey = b64.encode(privateKeyBytes);
console.log('Private key generated');
let publicKey;
let publicKeyBytes;
// Use Web Crypto API in production/HTTPS, fallback for development/HTTP
if (!isDevelopment && window.crypto.subtle) {
const keyPair = await window.crypto.subtle.generateKey(
{
name: 'ECDH',
namedCurve: 'P-256',
},
true,
['deriveKey', 'deriveBits']
);
publicKeyBytes = await window.crypto.subtle.exportKey(
'raw',
keyPair.publicKey
);
publicKey = b64.encode(new Uint8Array(publicKeyBytes));
} else {
// Development fallback
console.log('Using development key generation mode');
publicKeyBytes = await getRandomBytes(32);
publicKey = b64.encode(publicKeyBytes);
}
console.log('Public key generated');
// Generate preshared key
const presharedKeyBytes = await getRandomBytes(32);
const presharedKey = b64.encode(presharedKeyBytes);
console.log('Preshared key generated');
return { privateKey, publicKey, presharedKey };
} catch (error) {
console.error('Key generation failed:', error);
throw new Error('Failed to generate WireGuard keys');
}
2024-12-30 07:07:53 +00:00
}
// Export WireGuard interface
2024-12-30 07:07:53 +00:00
export const WireGuard = {
generateKeys: async () => {
try {
console.log('Starting key generation process...');
const keys = await generateKeyPair();
console.log('Keys generated successfully:', {
privateKeyLength: keys.privateKey.length,
publicKeyLength: keys.publicKey.length,
presharedKeyLength: keys.presharedKey.length
});
return keys;
} catch (error) {
console.error('Error in generateKeys:', error);
throw error;
}
},
validateKey: (key) => {
try {
const decoded = b64.decode(key);
return decoded.length === 32;
} catch {
return false;
}
},
// Expose environment information
isDevelopment
2024-12-30 07:07:53 +00:00
};
export default WireGuard;