def get_assertion(email, audience="*", issuer='browserid.org', bad_issuer_cert=False, bad_email_cert=False, exp=None): """Creates a browserid assertion for the given email, audience and hostname. This function can also be used to create invalid assertions. This will be the case if you set the bad_issuer_cert or the bad_email cert arguments to True. """ kwargs = {'exp': exp} if bad_issuer_cert: kwargs['issuer_keypair'] =\ get_keypair(hostname="not-the-right-host.com") if bad_email_cert: kwargs['email_keypair'] =\ get_keypair(hostname="not-the-right-host.com") return make_assertion(email, audience, issuer=issuer, **kwargs)
def test_malformed_assertions(self): errors = (ValueError, TrustError) # This one doesn't actually contain an assertion assertion = encode_json_bytes({}) self.assertRaises(errors, self.verifier.verify, assertion) # This one has no certificates pub, priv = get_keypair("TEST") assertion = encode_json_bytes({ "assertion": jwt.generate({"aud": "TEST"}, priv), "certificates": [] }) self.assertRaises(errors, self.verifier.verify, assertion)
def test_malformed_assertions(self): errors = (ValueError, TrustError) # This one doesn't actually contain an assertion assertion = encode_json_bytes({}) self.assertRaises(errors, self.verifier.verify, assertion) # This one has no certificates pub, priv = get_keypair("TEST") assertion = bundle_certs_and_assertion([], jwt.generate({"aud": "TEST"}, priv)) self.assertRaises(errors, self.verifier.verify, assertion) # This one has too many certificates in the chain. assertion = bundle_certs_and_assertion( [jwt.generate({}, priv), jwt.generate({}, priv)], jwt.generate({"aud": "TEST"}, priv) ) self.assertRaises(errors, self.verifier.verify, assertion)
def get_assertion(email, audience="*", issuer='browserid.org', bad_issuer_cert=False, bad_email_cert=False, exp=None): """Creates a browserid assertion for the given email, audience and hostname. This function can also be used to create invalid assertions. This will be the case if you set the bad_issuer_cert or the bad_email cert arguments to True. """ kwargs = {'exp': exp} if bad_issuer_cert: kwargs['issuer_keypair'] =\ get_keypair(hostname="not-the-right-host.com") if bad_email_cert: kwargs['email_keypair'] =\ get_keypair(hostname="not-the-right-host.com") assertion = make_assertion(email, audience, issuer=issuer, **kwargs) return assertion.encode('ascii')
def test_malformed_assertions(self): errors = (ValueError, TrustError) # This one doesn't actually contain an assertion assertion = encode_json_bytes({}) self.assertRaises(errors, self.verifier.verify, assertion) # This one has no certificates pub, priv = get_keypair("TEST") assertion = bundle_certs_and_assertion( [], jwt.generate({"aud": "TEST"}, priv), ) self.assertRaises(errors, self.verifier.verify, assertion) # This one has too many certificates in the chain. assertion = bundle_certs_and_assertion( [jwt.generate({}, priv), jwt.generate({}, priv)], jwt.generate({"aud": "TEST"}, priv), ) self.assertRaises(errors, self.verifier.verify, assertion)
def load_key(hostname): return get_keypair(hostname)[1]
def test_error_jwt_with_mismatched_algorithm(self): pub, priv = get_keypair("TEST") token = jwt.generate({}, priv) token = jwt.parse(token) pub["algorithm"] = "RS" self.assertFalse(token.check_signature(pub))
def main(): arguments = docopt(HELP) host = arguments["--host"].rstrip('/') headers = {'content-type': 'application/json'} if arguments["--version"]: print("msisdn-cli %s" % __version__) sys.exit(0) verify = True if arguments["--insecure"]: verify = False # 1. Start the discover url = "%s/discover" % host discover_args = {"mcc": arguments["--mcc"], "roaming": False} if arguments["--mnc"] is not None: discover_args["mnc"] = arguments["--mnc"] if arguments["--msisdn"] is not None: discover_args["msisdn"] = arguments["--msisdn"] r = requests.post(url, json.dumps(discover_args), headers=headers, verify=verify) try: r.raise_for_status() except: print(url, r.content) raise discover = r.json() # 1.1 Register url = "%s/register" % host r = requests.post(url, headers=headers, verify=verify) try: r.raise_for_status() except: print(url, r.content) raise register = r.json() hawk_auth = HawkAuth(hawk_session=register["msisdnSessionToken"], server_url=host) hawkId = hawk_auth.credentials["id"] method = discover['verificationMethods'][0] try: mtSender = discover['verificationDetails'][method]["mtSender"] except KeyError: mtSender = '' # 2. If MT Flow if method == "sms/mt": # 2.1 If no MSISDN, ask the MSISDN if arguments["--msisdn"] is None: msisdn = input("Please enter your MSISDN number (ie +123456789): ") else: msisdn = arguments["--msisdn"] # 2.2 Start the registration print("MT Flow for %s" % msisdn) url = "%s/sms/mt/verify" % host verify_args = { "msisdn": msisdn, "mcc": discover_args["mcc"], "shortVerificationCode": True } r = requests.post(url, json.dumps(verify_args), auth=hawk_auth, headers=headers, verify=verify) try: r.raise_for_status() except: print(url, r.content) raise # 3. If MOMT Flow else: print("MOMT Flow") # 3.1 Give the Number and HawkId moVerifier = discover['verificationDetails']["sms/momt"]["moVerifier"] print("Please send the following message to %s:" % moVerifier) print("\n\tSMS %s\n" % hawkId.decode("ascii")) # 4. Ask for the code code = input("Please enter the code that you will get by SMS from %s: " % mtSender) # 5. Verify the code url = "%s/sms/verify_code" % host r = requests.post(url, json.dumps({"code": code.strip()}), auth=hawk_auth, headers=headers, verify=verify) try: r.raise_for_status() except: print(url, r.content) raise # 6. Print out the certificate publicKey, privateKey = get_keypair("msisdn") url = "%s/certificate/sign" % host sign_args = { "publicKey": json.dumps(publicKey), "duration": 86400 # One day } r = requests.post(url, json.dumps(sign_args), auth=hawk_auth, headers=headers, verify=verify) try: r.raise_for_status() except: print(url, r.content) raise sign = r.json() cert = sign["cert"] info = json.loads(decode_bytes(cert.split('.')[1]).decode("utf-8")) info["publicKey"] = "<stripped>" info["public-key"] = "<stripped>" info["pubkey"] = "<stripped>" print("Verified: %s" % json.dumps(info, indent=2, sort_keys=True)) # Build assertion if arguments["--audience"]: audience = arguments["--audience"] assertion = {"exp": int((time.time() + 60) * 1000), "aud": audience} assertion = bundle_certs_and_assertion([cert], jwt.generate( assertion, privateKey)) if arguments["--verbose"]: print("BID Assertion for %s:\n\n%s\n\n" % (audience, assertion)) if arguments["--dry-run"]: curl = """\ncurl -X POST -D - \\ -H 'Authorization: BROWSERID %s' \\""" % assertion if arguments["--data"]: curl += """ -d '%s' \\""" % arguments["--data"] if arguments["--json"]: curl += """ -H 'Content-Type: application/json' -H 'Accept: application/json' \\ -d '%s' \\""" % arguments["--json"] login_endpoint = arguments["--login-endpoint"] or "<login_URL>" curl += "\n %s\n" "" % login_endpoint print("\nTo validate the configuration of the service provider, " "you can run the curl command below.\n\n" "You should get a 200 OK status code with a " "Hawk-Session-Token header:\n\n") print(curl) print(ERROR_EXPLAINATION) else: headers = {"Authorization": "BROWSERID %s" % assertion} data = arguments["--data"] if arguments["--json"]: data = arguments["--json"] headers["Content-Type"] = "application/json" headers["Accept"] = "application/json" r = requests.post(arguments["--login-endpoint"], data=data, headers=headers, verify=verify) # Try to extract an Hawk sessionToken from the response. sessionToken = None if "Access-Control-Expose-Headers" in r.headers: tokenHeader = r.headers["Access-Control-Expose-Headers"] sessionHeaders = tokenHeader.split(",") sessionHeader = None for header in sessionHeaders: if "token" in header.lower(): sessionHeader = header.strip() break if sessionHeader: sessionToken = r.headers[sessionHeader] else: try: json_resp = r.json() for key in json_resp.keys(): if "token" in key.lower(): sessionToken = json_resp["key"] except ValueError: pass print("Status: %s" % r.status_code) if sessionToken: print("Hawk sessionToken: %s" % sessionToken) else: print("Headers: %s" % r.headers) print("Content: %s" % r.content)
def main(): arguments = docopt(HELP) host = arguments["--host"].rstrip('/') headers = {'content-type': 'application/json'} if arguments["--version"]: print("msisdn-cli %s" % __version__) sys.exit(0) verify = True if arguments["--insecure"]: verify = False # 1. Start the discover url = "%s/discover" % host discover_args = {"mcc": arguments["--mcc"], "roaming": False} if arguments["--mnc"] is not None: discover_args["mnc"] = arguments["--mnc"] if arguments["--msisdn"] is not None: discover_args["msisdn"] = arguments["--msisdn"] r = requests.post(url, json.dumps(discover_args), headers=headers, verify=verify) try: r.raise_for_status() except: print(url, r.content) raise discover = r.json() # 1.1 Register url = "%s/register" % host r = requests.post(url, headers=headers, verify=verify) try: r.raise_for_status() except: print(url, r.content) raise register = r.json() hawk_auth = HawkAuth(hawk_session=register["msisdnSessionToken"], server_url=host) hawkId = hawk_auth.credentials["id"] method = discover['verificationMethods'][0] try: mtSender = discover['verificationDetails'][method]["mtSender"] except KeyError: mtSender = '' # 2. If MT Flow if method == "sms/mt": # 2.1 If no MSISDN, ask the MSISDN if arguments["--msisdn"] is None: msisdn = input("Please enter your MSISDN number (ie +123456789): ") else: msisdn = arguments["--msisdn"] # 2.2 Start the registration print("MT Flow for %s" % msisdn) url = "%s/sms/mt/verify" % host verify_args = { "msisdn": msisdn, "mcc": discover_args["mcc"], "shortVerificationCode": True } r = requests.post(url, json.dumps(verify_args), auth=hawk_auth, headers=headers, verify=verify) try: r.raise_for_status() except: print(url, r.content) raise # 3. If MOMT Flow else: print("MOMT Flow") # 3.1 Give the Number and HawkId moVerifier = discover['verificationDetails']["sms/momt"]["moVerifier"] print("Please send the following message to %s:" % moVerifier) print("\n\tSMS %s\n" % hawkId.decode("ascii")) # 4. Ask for the code code = input( "Please enter the code that you will get by SMS from %s: " % mtSender ) # 5. Verify the code url = "%s/sms/verify_code" % host r = requests.post(url, json.dumps({"code": code.strip()}), auth=hawk_auth, headers=headers, verify=verify) try: r.raise_for_status() except: print(url, r.content) raise # 6. Print out the certificate publicKey, privateKey = get_keypair("msisdn") url = "%s/certificate/sign" % host sign_args = { "publicKey": json.dumps(publicKey), "duration": 86400 # One day } r = requests.post(url, json.dumps(sign_args), auth=hawk_auth, headers=headers, verify=verify) try: r.raise_for_status() except: print(url, r.content) raise sign = r.json() cert = sign["cert"] info = json.loads(decode_bytes(cert.split('.')[1]).decode("utf-8")) info["publicKey"] = "<stripped>" info["public-key"] = "<stripped>" info["pubkey"] = "<stripped>" print("Verified: %s" % json.dumps(info, indent=2, sort_keys=True)) # Build assertion if arguments["--audience"]: audience = arguments["--audience"] assertion = { "exp": int((time.time() + 60) * 1000), "aud": audience } assertion = bundle_certs_and_assertion( [cert], jwt.generate(assertion, privateKey) ) if arguments["--verbose"]: print("BID Assertion for %s:\n\n%s\n\n" % (audience, assertion)) if arguments["--dry-run"]: curl = """\ncurl -X POST -D - \\ -H 'Authorization: BROWSERID %s' \\""" % assertion if arguments["--data"]: curl += """ -d '%s' \\""" % arguments["--data"] if arguments["--json"]: curl += """ -H 'Content-Type: application/json' -H 'Accept: application/json' \\ -d '%s' \\""" % arguments["--json"] login_endpoint = arguments["--login-endpoint"] or "<login_URL>" curl += "\n %s\n""" % login_endpoint print("\nTo validate the configuration of the service provider, " "you can run the curl command below.\n\n" "You should get a 200 OK status code with a " "Hawk-Session-Token header:\n\n") print(curl) print(ERROR_EXPLAINATION) else: headers = {"Authorization": "BROWSERID %s" % assertion} data = arguments["--data"] if arguments["--json"]: data = arguments["--json"] headers["Content-Type"] = "application/json" headers["Accept"] = "application/json" r = requests.post(arguments["--login-endpoint"], data=data, headers=headers, verify=verify) # Try to extract an Hawk sessionToken from the response. sessionToken = None if "Access-Control-Expose-Headers" in r.headers: tokenHeader = r.headers["Access-Control-Expose-Headers"] sessionHeaders = tokenHeader.split(",") sessionHeader = None for header in sessionHeaders: if "token" in header.lower(): sessionHeader = header.strip() break if sessionHeader: sessionToken = r.headers[sessionHeader] else: try: json_resp = r.json() for key in json_resp.keys(): if "token" in key.lower(): sessionToken = json_resp["key"] except ValueError: pass print("Status: %s" % r.status_code) if sessionToken: print("Hawk sessionToken: %s" % sessionToken) else: print("Headers: %s" % r.headers) print("Content: %s" % r.content)