def test_bad_signature(): wif = 'L2Ai1TBwKfyPshmqosKRBvJ47qUCDKesfZXh2zLoYoB7NHgdPS6d' key = bitjws.PrivateKey(bitjws.wif_to_privkey(wif)) assert bitjws.privkey_to_wif(key.private_key) == wif ser = bitjws.sign_serialize(key) # Drop the last byte from the signature. ser = ser[:-1] with pytest.raises(bitjws.jws.InvalidMessage): # It will fail to decode as base64 due to padding. bitjws.validate_deserialize(ser) # Drop another byte. ser = ser[:-1] with pytest.raises(bitjws.jws.InvalidMessage): # Although it can be decoded now, the length is incorrect. bitjws.validate_deserialize(ser) # Replace the signature by something that has the correct # length before decoding but becomes invalid after it. dummy = bitjws.base64url_encode(b'a' * 88) ser = ser[:ser.rfind('.')] + '.' + dummy.decode('utf8') with pytest.raises(bitjws.jws.InvalidMessage): # Now it fails because the dummy signature above produces # 66 bytes (instead of 65) after being decoded. bitjws.validate_deserialize(ser)
def _load_config(self, config): if ENVCFG in os.environ: logging.info("Loading config from {}".format(ENVCFG)) #self.config.from_envvar(ENVCFG) data = json.load(open(os.getenv(ENVCFG))) self.config.update(**data) else: logging.warn("{} not defined".format(ENVCFG)) if isinstance(config, dict): self.config.update(**config) if not self.config.get('api_signing_key'): raise Exception("Invalid config: missing api_signing_key") # Server key used to sign responses. The client can optionally # check that the response was signed by a key it knows to belong # to this server. self._privkey = bitjws.PrivateKey( bitjws.wif_to_privkey(self.config['api_signing_key'])) logging.info("Server key address: {}".format( bitjws.pubkey_to_addr(self._privkey.pubkey.serialize()))) self._cosigner_server = self.config.get('cosigner_server') if not self._cosigner_server: logging.warning("cosigner_server not present in config, " "cosigning will not be available.") self._dbcfg = self.config.get('api_database') if not self._dbcfg: raise Exception("Invalid config: missing api_database") if 'engine' not in self._dbcfg: raise Exception("Invalid config for api_databae: missing 'engine'")
def from_spec(cls, spec_dict, origin_url=None, http_client=None, privkey=None, **kwargs): """ Build a :class:`SwaggerClient` from swagger api docs :param spec_dict: a dict with a Swagger spec in json-like form :param origin_url: the url used to retrieve the spec_dict :type origin_url: str :param http_client: an HTTP client used to perform requests :type http_client: :class:`bravado.http_client.HttpClient` :param str privkey: The WIF private key to use for bitjws signing """ if privkey is None: privkey = bitjws.PrivateKey() elif isinstance(privkey, str): privkey = bitjws.PrivateKey(bitjws.wif_to_privkey(privkey)) if http_client is None: host = urlparse.urlsplit(origin_url).hostname http_client = BitJWSRequestsClient() private_key = bitjws.privkey_to_wif(privkey.private_key) http_client.set_bitjws_key(host, private_key) return SwaggerClient.from_spec(spec_dict, http_client=http_client, **kwargs)
def test_init_basepath(): privkey = bitjws.PrivateKey(bitjws.wif_to_privkey(wif)) fbj = FlaskBitjws(server.app, privkey=privkey, basepath="/v3") app = server.app.test_client() import time user = app.post('/echo', data={'username': str(time.time)}) assert user.status_code == 401
def test_init_PrivateKey(): privkey = bitjws.PrivateKey(bitjws.wif_to_privkey(wif)) client = BitJWSSwaggerClient.from_spec(load_file(specurl), 'https://0.0.0.0:8002', privkey=privkey) assert 'coin' in client.swagger_spec.definitions assert 'user' in client.swagger_spec.definitions ckey = client.coin.addCoin.swagger_spec.http_client.authenticator.privkey assert isinstance(ckey, bitjws.PrivateKey) assert bitjws.privkey_to_wif(privkey.private_key) == \ bitjws.privkey_to_wif(ckey.private_key)
def test_init_url_PrivateKey(): privkey = bitjws.PrivateKey(bitjws.wif_to_privkey(wif)) url = "http://spec.com/swagger.json" spec = load_file(specurl) httpretty.enable() httpretty.register_uri(httpretty.GET, url, body=json.dumps(spec)) client = BitJWSSwaggerClient.from_url(url, privkey=privkey) assert 'coin' in client.swagger_spec.definitions assert 'user' in client.swagger_spec.definitions ckey = client.coin.addCoin.swagger_spec.http_client.authenticator.privkey assert isinstance(ckey, bitjws.PrivateKey) assert bitjws.privkey_to_wif(privkey.private_key) == bitjws.privkey_to_wif(ckey.private_key) httpretty.disable() httpretty.reset()
def __init__(self, app, privkey=None, loginmanager=None, get_last_nonce=get_last_nonce, get_user_by_key=get_user_by_key, basepath=""): """ Initialize a flask-bitjws Application with optional LoginManager. If you do not provide your own LoginManager one will be created. Create or set the private key to use with this application. :param str app: The flask application :param str privkey: the bitjws private key to use for signing responses :param flask.ext.login.LoginManager loginmanager: An optional LoginManager :param function get_last_nonce: A function to overwrite this class's stub. :param function get_user_by_key: A function to overwrite this class's stub. :param str basepath: The public basepath this app is deployed on. (only preceding slash required i.e. '/path') """ if privkey is not None and isinstance(privkey, str): self._privkey = bitjws.PrivateKey(bitjws.wif_to_privkey(privkey)) elif privkey is not None and isinstance(privkey, bitjws.PrivateKey): self._privkey = privkey else: self._privkey = bitjws.PrivateKey() self.pubkey = bitjws.pubkey_to_addr(self._privkey.pubkey.serialize()) if loginmanager is None: loginmanager = login.LoginManager() loginmanager.anonymous_user = login.AnonymousUserMixin loginmanager.init_app(app) loginmanager.request_loader(load_user_from_request) self.get_last_nonce = get_last_nonce self.get_user_by_key = get_user_by_key self.basepath = basepath app.bitjws = self
def from_url(cls, spec_url, http_client=None, privkey=None, **kwargs): """ Build a :class:`SwaggerClient` from a url to the Swagger specification for a RESTful API. :param spec_url: url pointing at the swagger API specification :type spec_url: str :param http_client: an HTTP client used to perform requests :type http_client: :class:`bravado.http_client.HttpClient` """ if privkey is None: privkey = bitjws.PrivateKey() elif isinstance(privkey, str): privkey = bitjws.PrivateKey(bitjws.wif_to_privkey(privkey)) if http_client is None: host = urlparse.urlsplit(spec_url).hostname http_client = BitJWSRequestsClient() private_key = bitjws.privkey_to_wif(privkey.private_key) http_client.set_bitjws_key(host, private_key) return SwaggerClient.from_url(spec_url, http_client=http_client, **kwargs)
# Install requirements: pip install requests import requests import bitjws # Load existing private key. In this example the server always # create a new private key while the client loads an existing one. wif = "KxZUqanyzZEGptbauar66cQo8bfGHwDauHogkxCaqTeMGY1stH6E" priv = bitjws.wif_to_privkey(wif) privkey = bitjws.PrivateKey(priv) assert wif == bitjws.privkey_to_wif(privkey.private_key) # The resulting bitcoin address can be derived for debugging # purposes. my_pubkey = privkey.pubkey.serialize() my_address = bitjws.pubkey_to_addr(my_pubkey) assert my_address == "1G9sChbyDSmuAXNVpjuRwakTmcHdxKGqpp" print("My WIF key: {}".format(wif)) print("My key address: {}".format(my_address)) # Prepare a request to be sent. This one uses a single custom # parameter named 'echo'. echo_msg = "hello" data = bitjws.sign_serialize(privkey, echo=echo_msg) # Send and receive signed requests. resp = requests.post("http://localhost:8001/", data=data) headers, payload = bitjws.validate_deserialize(resp.content.decode("utf8")) print(headers) # headers['kid'] contains the key used by the server. print(payload) # In this example the server returns a response containing the # echo parameter specified earlier and also a param named 'address'. assert payload["echo"] == echo_msg
# Install requirements: pip install requests import requests import bitjws # Load existing private key. In this example the server always # create a new private key while the client loads an existing one. wif = "KxZUqanyzZEGptbauar66cQo8bfGHwDauHogkxCaqTeMGY1stH6E" priv = bitjws.wif_to_privkey(wif) privkey = bitjws.PrivateKey(priv) assert wif == bitjws.privkey_to_wif(privkey.private_key) # The resulting bitcoin address can be derived for debugging # purposes. my_pubkey = privkey.pubkey.serialize() my_address = bitjws.pubkey_to_addr(my_pubkey) assert my_address == "1G9sChbyDSmuAXNVpjuRwakTmcHdxKGqpp" print("My WIF key: {}".format(wif)) print("My key address: {}".format(my_address)) # Prepare a request to be sent. This one uses a single custom # parameter named 'echo'. echo_msg = 'hello' data = bitjws.sign_serialize(privkey, echo=echo_msg) # Send and receive signed requests. resp = requests.post('http://localhost:8001/', data=data) headers, payload = bitjws.validate_deserialize(resp.content.decode('utf8')) print(headers) # headers['kid'] contains the key used by the server. print(payload) # In this example the server returns a response containing the # echo parameter specified earlier and also a param named 'address'. assert payload['echo'] == echo_msg
def __init__(self, host, privkey): super(BitJWSAuthenticator, self).__init__(host) self.privkey = bitjws.PrivateKey(bitjws.wif_to_privkey(privkey))
def test_init_PrivateKey(): privkey = bitjws.PrivateKey(bitjws.wif_to_privkey(wif)) app = Flask(__name__) fbj = FlaskBitjws(app, privkey=privkey) assert wif == bitjws.privkey_to_wif(app.bitjws._privkey.private_key)