Skip to content

Commit

Permalink
Merge pull request #38 from nanocom2024/change-pairing-process
Browse files Browse the repository at this point in the history
Change pairing process
  • Loading branch information
hyouhyan committed Sep 10, 2024
2 parents 7112faf + 49c919f commit 94e4ce1
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 65 deletions.
1 change: 1 addition & 0 deletions server/src/Auth/firebase.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
def sign_in_with_email_and_password(api_key, email, password):
"""
Firebaseで認証を行う(SDKの signInWithEmailAndPassword と同値)
:param api_key:
:param email:
:param password:
Expand Down
44 changes: 44 additions & 0 deletions server/src/Pairing/PairingModel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import hashlib
from DB import DB

db = DB()
device_keys = db.device_keys


def generate_major_minor(public_key):
"""
majorとminorをpublic_keyから生成する
:param public_key: str
:return major, minor: (int, int)
"""

temp = public_key
while True:
major, minor = generate(temp)
device_key = device_keys.find_one({'major': major, 'minor': minor})
if not device_key:
break
temp = hashlib.sha256(temp.encode()).hexdigest()

return major, minor


def generate(key):
forward = key[:32]
backward = key[32:]

forward_hash = hashlib.sha256(forward.encode()).hexdigest()
backward_hash = hashlib.sha256(backward.encode()).hexdigest()

# 16bitのuintに変換
major = int(forward_hash, 16) % 2**16
minor = int(backward_hash, 16) % 2**16

return major, minor


if __name__ == '__main__':
public_key = 'a' * 64
print(generate(public_key))
# (42311, 42311)
35 changes: 25 additions & 10 deletions server/src/Pairing/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from flask import Blueprint, request, jsonify
from DB import DB
from crypto.generate import generate_ed25519_keypair
from Pairing import PairingModel
from flask_jwt_extended import create_access_token

PAIRING_BP = Blueprint('pairing', __name__, url_prefix='/pairing')
Expand All @@ -13,8 +14,8 @@
pairings = db.pairings


@PAIRING_BP.route('/generate_device_key', methods=['POST'])
def generate_device_key():
@PAIRING_BP.route('/generate_major_minor', methods=['POST'])
def generate_major_minor():
uid = request.json['uid']
if not uid:
return jsonify({'error': 'Missing uid'}), 400
Expand All @@ -24,40 +25,54 @@ def generate_device_key():

private_key, public_key = generate_ed25519_keypair()

major, minor = PairingModel.generate_major_minor(public_key)

device_keys.insert_one({
'uid': uid,
'private_key': private_key,
'public_key': public_key
'public_key': public_key,
'major': major,
'minor': minor
})

return jsonify({'private_key': private_key, 'public_key': public_key}), 200
return jsonify({
'private_key': private_key,
'public_key': public_key,
'major': major,
'minor': minor
}), 200


@PAIRING_BP.route('/register_pairing', methods=['POST'])
def register_pairing():
token = request.json['token']
if not token:
return jsonify({'error': 'Missing token'}), 400
public_key = request.json['public_key']
if not public_key:
return jsonify({'error': 'Missing public_key'}), 400
major = request.json['major']
if not major:
return jsonify({'error': 'Missing major'}), 400
minor = request.json['minor']
if not minor:
return jsonify({'error': 'Missing minor'}), 400

user = users.find_one({'token': token})
if not user:
return jsonify({'error': 'Invalid token'}), 400

device_key = device_keys.find_one({'public_key': public_key})
device_key = device_keys.find_one({'major': major, 'minor': minor})
if not device_key:
return jsonify({'error': 'Invalid public_key'}), 400
return jsonify({'error': 'Invalid major,minor'}), 400

pairings.delete_many({'uid': user['uid']})
pairings.delete_many({'public_key': device_key['public_key']})
pairings.delete_many({'private_key': device_key['private_key']})

pairings.insert_one({
'uid': user['uid'],
'private_key': device_key['private_key'],
'public_key': device_key['public_key'],
'private_key': device_key['private_key']
'major': major,
'minor': minor
})

return jsonify({'done': 'pairing'}), 200
Expand Down
14 changes: 9 additions & 5 deletions server/src/StreetPass/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,20 @@

@STREETPASS_BP.route('/received_beacon', methods=['POST'])
def received_beacon():
received_public_key = request.json['received_public_key']
if not received_public_key:
return jsonify({'error': 'Missing received_public_key'}), 400
received_major = request.json['received_major']
if not received_major:
return jsonify({'error': 'Missing received_major'}), 400
received_minor = request.json['received_minor']
if not received_minor:
return jsonify({'error': 'Missing received_minor'}), 400
private_key = request.json['private_key']
if not private_key:
return jsonify({'error': 'Missing private_key'}), 400

received_user = pairings.find_one({'public_key': received_public_key})
received_user = pairings.find_one(
{'major': received_major, 'minor': received_minor})
if not received_user:
return jsonify({'error': 'Invalid received_public_key'}), 400
return jsonify({'error': 'Invalid received_major_minor'}), 400
sent_user = pairings.find_one({'private_key': private_key})
if not sent_user:
return jsonify({'error': 'Invalid private_key'}), 400
Expand Down
74 changes: 56 additions & 18 deletions server/tests/test_pairing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,44 @@

private_key = ''
public_key = ''
major = ''
minor = ''
token = ''
email = ''.join(random.choices(string.ascii_lowercase +
string.digits, k=20))+'@test.org'


def test_generate_device_key_success(baseurl):
def test_generate_major_minor_success(baseurl):
global private_key
global public_key
url = baseurl+'/pairing/generate_device_key'
global major
global minor
url = baseurl+'/pairing/generate_major_minor'
res = requests.post(url, json={
'uid': 'test_uid',
})
assert res.status_code == 200
private_key = res.json()['private_key']
public_key = res.json()['public_key']
assert private_key
public_key = res.json()['public_key']
assert public_key
major = res.json()['major']
assert major
minor = res.json()['minor']
assert minor


def test_generate_device_key_missing_uid(baseurl):
url = baseurl+'/pairing/generate_device_key'
def test_generate_major_minor_missing_uid(baseurl):
url = baseurl+'/pairing/generate_major_minor'
res = requests.post(url, json={
'uid': '',
})
assert res.status_code == 400
assert res.json()['error'] == 'Missing uid'


def test_generate_device_key_already_exists(baseurl):
url = baseurl+'/pairing/generate_device_key'
def test_generate_major_minor_already_exists(baseurl):
url = baseurl+'/pairing/generate_major_minor'
res = requests.post(url, json={
'uid': 'test_uid',
})
Expand All @@ -56,12 +64,13 @@ def get_token(baseurl):

def test_register_pairing_success(baseurl):
global token
global public_key
global major, minor
url = baseurl+'/pairing/register_pairing'
token = get_token(baseurl)
res = requests.post(url, json={
'token': token,
'public_key': public_key
'major': major,
'minor': minor
})
assert res.status_code == 200
assert res.json()['done'] == 'pairing'
Expand All @@ -73,52 +82,81 @@ def test_register_pairing_success(baseurl):

user = users.find_one({'token': token})
pairing = pairings.find_one(
{'uid': user['uid'], 'public_key': public_key, 'private_key': private_key})
{'uid': user['uid'], 'major': major, 'minor': minor})
assert pairing


def test_register_pairing_missing_token(baseurl):
global public_key
global major, minor
url = baseurl+'/pairing/register_pairing'
res = requests.post(url, json={
'token': '',
'public_key': public_key
'major': major,
'minor': minor
})
assert res.status_code == 400
assert res.json()['error'] == 'Missing token'


def test_register_pairing_missing_public_key(baseurl):
def test_register_pairing_missing_major(baseurl):
global token
global minor
url = baseurl+'/pairing/register_pairing'
res = requests.post(url, json={
'token': token,
'major': '',
'minor': minor
})
assert res.status_code == 400
assert res.json()['error'] == 'Missing major'


def test_register_pairing_missing_minor(baseurl):
global token
global major
url = baseurl+'/pairing/register_pairing'
res = requests.post(url, json={
'token': token,
'public_key': ''
'major': major,
'minor': ''
})
assert res.status_code == 400
assert res.json()['error'] == 'Missing public_key'
assert res.json()['error'] == 'Missing minor'


def test_register_pairing_invalid_token(baseurl):
global public_key
global major, minor
url = baseurl+'/pairing/register_pairing'
res = requests.post(url, json={
'token': 'invalidToken',
'public_key': public_key
'major': major,
'minor': minor
})
assert res.status_code == 400
assert res.json()['error'] == 'Invalid token'


def test_register_pairing_invalid_public_key(baseurl):
def test_register_pairing_invalid_major_minor(baseurl):
global token
global major, minor
url = baseurl+'/pairing/register_pairing'
res = requests.post(url, json={
'token': token,
'public_key': 'invalidPublicKey'
'major': 'invalidMajor',
'minor': minor
})
assert res.status_code == 400
assert res.json()['error'] == 'Invalid major,minor'

res = requests.post(url, json={
'token': token,
'major': major,
'minor': 'invalidMinor'
})
assert res.status_code == 400
assert res.json()['error'] == 'Invalid public_key'
assert res.json()['error'] == 'Invalid major,minor'


def test_auth_check_success(baseurl):
Expand Down
Loading

0 comments on commit 94e4ce1

Please sign in to comment.