Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
 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 = encode_json_bytes({
         "assertion":
         jwt.generate({"aud": "TEST"}, priv),
         "certificates": []
     })
     self.assertRaises(errors, self.verifier.verify, assertion)
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
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')
Ejemplo n.º 6
0
 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)
Ejemplo n.º 7
0
def load_key(hostname):
    return get_keypair(hostname)[1]
Ejemplo n.º 8
0
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))
Ejemplo n.º 10
0
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)
Ejemplo n.º 11
0
 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))
Ejemplo n.º 12
0
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)