Self-hosted, federated location sharing app and server that prioritizes user privacy and security
end-to-end-encryption location-sharing privacy self-hosted federated

added nonce to auth

+23 -7
+12 -4
app/src/utils/api.ts
··· 76 76 "sign", 77 77 ]); 78 78 79 - const signature = await crypto.subtle.sign("Ed25519", privKey, bodyBytes); 80 - const signature_b64 = bufToBase64(signature); 79 + const nonce = new Uint8Array(8); 80 + crypto.getRandomValues(nonce); 81 + const data_to_sign = new Uint8Array(bodyBytes.length + nonce.length); 82 + data_to_sign.set(bodyBytes); 83 + data_to_sign.set(nonce, bodyBytes.length); 84 + const signature = await crypto.subtle.sign("Ed25519", privKey, data_to_sign); 81 85 82 86 const headers = { 83 - "x-auth": JSON.stringify({ user_id, signature: signature_b64 }), 87 + "x-auth": JSON.stringify({ 88 + user_id, 89 + signature: bufToBase64(signature), 90 + nonce: nonce.toBase64(), 91 + }), 84 92 "Content-Type": "application/json", // TODO: not always json tho, but does it matter? 85 93 }; 86 94 87 95 const res = await fetch(`${server_url}/${endpoint}`, { 88 96 method: "POST", 89 97 headers, 90 - body: bodyBytes, // TODO: do we need to send bodyBytes instead to match server side auth? 98 + body: bodyBytes, 91 99 }); 92 100 93 101 if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
+10 -3
server/src/auth.rs
··· 56 56 //////////////////////////////////// unsure 57 57 //////////////////////////////////// 58 58 59 - let sig_vec = BASE64_STANDARD 59 + let sign_vec = BASE64_STANDARD 60 60 .decode(&auth_data.signature) 61 61 .map_err(|e| SrvErr!("base64 decode fail", e))?; 62 + let nonce_vec = BASE64_STANDARD 63 + .decode(&auth_data.nonce) 64 + .map_err(|e| SrvErr!("base64 decode fail", e))?; 62 65 let sig_bytes: [u8; 64] = 63 - sig_vec.try_into().map_err(|e| SrvErr!("invalid signature length", e))?; 66 + sign_vec.try_into().map_err(|e| SrvErr!("invalid signature length", e))?; 64 67 let signature = Signature::from_bytes(&sig_bytes); 65 68 66 - if let Err(err) = verifying_key.verify_strict(&body_bytes, &signature) { 69 + let mut combined_vec = Vec::with_capacity(body_bytes.len() + nonce_vec.len()); 70 + combined_vec.extend_from_slice(&body_bytes); 71 + combined_vec.extend_from_slice(&nonce_vec); 72 + 73 + if let Err(err) = verifying_key.verify_strict(&combined_vec, &signature) { 67 74 panic!("Signature verification failed: {err}"); 68 75 } 69 76
+1
server/src/types.rs
··· 26 26 pub struct AuthData { 27 27 pub user_id: String, 28 28 pub signature: String, 29 + pub nonce: String, 29 30 } 30 31 31 32 pub struct RingBuffer {