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
|
from __future__ import division
from collections import OrderedDict
import click
from srptools import VERSION, SRPContext, SRPServerSession, SRPClientSession, hex_from_b64
from srptools.constants import *
PRESETS = OrderedDict([
('1024', (PRIME_1024, PRIME_1024_GEN)),
('1536', (PRIME_1536, PRIME_1536_GEN)),
('2048', (PRIME_2048, PRIME_2048_GEN)),
('3072', (PRIME_3072, PRIME_3072_GEN)),
('4096', (PRIME_4096, PRIME_4096_GEN)),
('6144', (PRIME_6144, PRIME_6144_GEN)),
])
@click.group()
@click.version_option(version='.'.join(map(str, VERSION)))
def base():
"""srptools command line utility.
Tools to implement Secure Remote Password (SRP) authentication.
Basic scenario:
> srptools get_user_data_triplet
> srptools server get_private_and_public
> srptools client get_private_and_public
> srptools client get_session_data
> srptools server get_session_data
"""
def common_options(func):
"""Commonly used command options."""
def parse_preset(ctx, param, value):
return PRESETS.get(value, (None, None))
def parse_private(ctx, param, value):
return hex_from_b64(value) if value else None
func = click.option('--private', default=None, help='Private.', callback=parse_private)(func)
func = click.option(
'--preset',
default=None, help='Preset ID defining prime and generator pair.',
type=click.Choice(PRESETS.keys()), callback=parse_preset
)(func)
return func
@base.group()
def server():
"""Server session related commands."""
@base.group()
def client():
"""Client session related commands."""
@server.command()
@click.argument('username')
@click.argument('password_verifier')
@common_options
def get_private_and_public(username, password_verifier, private, preset):
"""Print out server public and private."""
session = SRPServerSession(
SRPContext(username, prime=preset[0], generator=preset[1]),
hex_from_b64(password_verifier), private=private)
click.secho('Server private: %s' % session.private_b64)
click.secho('Server public: %s' % session.public_b64)
@server.command()
@click.argument('username')
@click.argument('password_verifier')
@click.argument('salt')
@click.argument('client_public')
@common_options
def get_session_data( username, password_verifier, salt, client_public, private, preset):
"""Print out server session data."""
session = SRPServerSession(
SRPContext(username, prime=preset[0], generator=preset[1]),
hex_from_b64(password_verifier), private=private)
session.process(client_public, salt, base64=True)
click.secho('Server session key: %s' % session.key_b64)
click.secho('Server session key proof: %s' % session.key_proof_b64)
click.secho('Server session key hash: %s' % session.key_proof_hash_b64)
@client.command()
@click.argument('username')
@click.argument('password')
@common_options
def get_private_and_public(ctx, username, password, private, preset):
"""Print out server public and private."""
session = SRPClientSession(
SRPContext(username, password, prime=preset[0], generator=preset[1]),
private=private)
click.secho('Client private: %s' % session.private_b64)
click.secho('Client public: %s' % session.public_b64)
@client.command()
@click.argument('username')
@click.argument('password')
@click.argument('salt')
@click.argument('server_public')
@common_options
def get_session_data(ctx, username, password, salt, server_public, private, preset):
"""Print out client session data."""
session = SRPClientSession(
SRPContext(username, password, prime=preset[0], generator=preset[1]),
private=private)
session.process(server_public, salt, base64=True)
click.secho('Client session key: %s' % session.key_b64)
click.secho('Client session key proof: %s' % session.key_proof_b64)
click.secho('Client session key hash: %s' % session.key_proof_hash_b64)
@base.command()
@click.argument('username')
@click.argument('password')
def get_user_data_triplet(username, password):
"""Print out user data triplet: username, password verifier, salt."""
context = SRPContext(username, password)
username, password_verifier, salt = context.get_user_data_triplet(base64=True)
click.secho('Username: %s' % username)
click.secho('Password verifier: %s' % password_verifier)
click.secho('Salt: %s' % salt)
def main():
"""
CLI entry point
"""
base(obj={})
|