예제 #1
0
    def test_verify_function(self):
        url = 'https://example.org/beths-robotics-badge.json'
        responses.add(responses.GET,
                      url,
                      body=test_components['2_0_basic_assertion'],
                      status=200,
                      content_type='application/ld+json')
        set_up_image_mock('https://example.org/beths-robot-badge.png')
        responses.add(responses.GET,
                      'https://w3id.org/openbadges/v2',
                      body=test_components['openbadges_context'],
                      status=200,
                      content_type='application/ld+json')
        responses.add(responses.GET,
                      'https://example.org/robotics-badge.json',
                      body=test_components['2_0_basic_badgeclass'],
                      status=200,
                      content_type='application/ld+json')
        set_up_image_mock(u'https://example.org/robotics-badge.png')
        responses.add(responses.GET,
                      'https://example.org/organization.json',
                      body=test_components['2_0_basic_issuer'],
                      status=200,
                      content_type='application/ld+json')

        results = verify(url)
        self.assertEqual(results.get('input').get('value'), url)
        self.assertEqual(results.get('input').get('input_type'), 'url')

        self.assertEqual(len(results['report']['messages']), 0,
                         "There should be no failing tasks.")
예제 #2
0
    def test_can_full_verify_with_revocation_check(self):
        input_assertion = json.loads(test_components['2_0_basic_assertion'])
        input_assertion['verification'] = {'type': 'signed', 'creator': 'http://example.org/key1'}
        set_up_image_mock(u'https://example.org/beths-robot-badge.png')

        input_badgeclass = json.loads(test_components['2_0_basic_badgeclass'])
        set_up_image_mock(input_badgeclass['image'])

        revocation_list = {
            '@context': OPENBADGES_CONTEXT_V2_URI,
            'id': 'http://example.org/revocationList',
            'type': 'RevocationList',
            'revokedAssertions': []}
        input_issuer = json.loads(test_components['2_0_basic_issuer'])
        input_issuer['revocationList'] = revocation_list['id']
        input_issuer['publicKey'] = input_assertion['verification']['creator']

        private_key = RSA.generate(2048)
        print("PKEY")
        print(private_key.publickey().exportKey('PEM').decode())
        cryptographic_key_doc = {
            '@context': OPENBADGES_CONTEXT_V2_URI,
            'id': input_assertion['verification']['creator'],
            'type': 'CryptographicKey',
            'owner': input_issuer['id'],
            'publicKeyPem': private_key.publickey().exportKey('PEM').decode()
        }

        set_up_context_mock()
        for doc in [input_assertion, input_badgeclass, input_issuer, cryptographic_key_doc, revocation_list]:
            responses.add(responses.GET, doc['id'], json=doc, status=200)

        header = json.dumps({'alg': 'RS256'})
        payload = json.dumps(input_assertion)

        encoded_separator = '.'
        if not sys.version[:3] < '3':
            encoded_separator = '.'.encode()
            encoded_header = b64encode(header.encode())
            encoded_payload = b64encode(payload.encode())
        else:
            encoded_header = b64encode(header)
            encoded_payload = b64encode(payload)

        signature = encoded_separator.join([
            encoded_header,
            encoded_payload,
            jws.sign(header, payload, private_key, is_json=True)
        ])

        response = verify(signature, use_cache=False)

        self.assertTrue(response['report']['valid'])
예제 #3
0
    def test_verify_of_baked_image(self):
        url = 'https://example.org/beths-robotics-badge.json'
        png_badge = os.path.join(os.path.dirname(__file__), 'testfiles',
                                 'public_domain_heart.png')
        responses.add(responses.GET,
                      url,
                      body=test_components['2_0_basic_assertion'],
                      status=200,
                      content_type='application/ld+json')
        set_up_image_mock(u'https://example.org/beths-robot-badge.png')
        responses.add(responses.GET,
                      'https://w3id.org/openbadges/v2',
                      body=test_components['openbadges_context'],
                      status=200,
                      content_type='application/ld+json')
        responses.add(responses.GET,
                      'https://example.org/robotics-badge.json',
                      body=test_components['2_0_basic_badgeclass'],
                      status=200,
                      content_type='application/ld+json')
        set_up_image_mock(u'https://example.org/robotics-badge.png')
        responses.add(responses.GET,
                      'https://example.org/organization.json',
                      body=test_components['2_0_basic_issuer'],
                      status=200,
                      content_type='application/ld+json')

        with open(png_badge, 'rb') as image:
            baked_image = bake(image, test_components['2_0_basic_assertion'])
            responses.add(responses.GET,
                          'https://example.org/baked',
                          body=baked_image.read(),
                          content_type='image/png')
            results = verify(baked_image)

        # verify gets the JSON out of the baked image, and then detect_input_type
        # will reach out to the assertion URL to fetch the canonical assertion (thus,
        # we expect this to become an URL input type for the verifier).
        self.assertNotEqual(results, None)
        self.assertEqual(results.get('input').get('value'), url)
        self.assertEqual(results.get('input').get('input_type'), 'url')
        self.assertEqual(len(results['report']['messages']), 0,
                         "There should be no failing tasks.")

        # Verify that the same result occurs when passing in the baked image url.
        another_result = verify('https://example.org/baked')
        self.assertTrue(another_result['report']['valid'])
        self.assertEqual(another_result['report']['validationSubject'],
                         results['report']['validationSubject'])
예제 #4
0
    def test_verify_badge_against_expected_profile(self):
        recipient_profile = {'email': '*****@*****.**'}
        url = 'https://example.org/beths-robotics-badge.json'
        assertion = json.loads(test_components['2_0_basic_assertion'])
        assertion['recipient']['identity'] = 'sha256$' + hashlib.sha256(
            recipient_profile['email'].encode('utf8') + assertion['recipient']['salt'].encode('utf8')).hexdigest()

        responses.add(
            responses.GET, url, body=json.dumps(assertion), status=200,
            content_type='application/ld+json'
        )
        set_up_image_mock('https://example.org/beths-robot-badge.png')
        responses.add(
            responses.GET, 'https://w3id.org/openbadges/v2',
            body=test_components['openbadges_context'], status=200,
            content_type='application/ld+json'
        )
        responses.add(
            responses.GET, 'https://example.org/robotics-badge.json',
            body=test_components['2_0_basic_badgeclass'], status=200,
            content_type='application/ld+json'
        )
        set_up_image_mock('https://example.org/robotics-badge.png')
        responses.add(
            responses.GET, 'https://example.org/organization.json',
            body=test_components['2_0_basic_issuer'], status=200,
            content_type='application/ld+json'
        )

        result = verification_store(url, recipient_profile)
        state = result.get_state()
        profile_verification_tasks = filter_tasks(state, name=VERIFY_RECIPIENT_IDENTIFIER)

        self.assertEqual(len(filter_failed_tasks(state)), 0)
        self.assertEqual(len(profile_verification_tasks), 1)
        self.assertTrue(profile_verification_tasks[0]['success'])

        recipient_profile = {'email': ['*****@*****.**', '*****@*****.**']}
        result = verification_store(url, recipient_profile)
        state = result.get_state()
        profile_verification_tasks = filter_tasks(state, name=VERIFY_RECIPIENT_IDENTIFIER)
        self.assertEqual(len(filter_failed_tasks(state)), 0)
        self.assertEqual(len(profile_verification_tasks), 1)
        self.assertTrue(profile_verification_tasks[0]['success'])
예제 #5
0
    def test_can_full_verify_jws_signed_assertion(self):
        """
        I can input a JWS string
        I can extract the Assertion from the input signature string and store it as the canonical version of the Assertion.
        I can discover and retrieve key information from the Assertion.
        I can Access the signing key
        I can verify the key is associated with the listed issuer Profile
        I can verify the JWS signature has been created by a key trusted to correspond to the issuer Profile
        Next: I can verify an assertion with an ephemeral embedded badgeclass as well
        """
        input_assertion = json.loads(test_components['2_0_basic_assertion'])
        input_assertion['verification'] = {'type': 'signed', 'creator': 'http://example.org/key1'}
        set_up_image_mock(u'https://example.org/beths-robot-badge.png')

        input_badgeclass = json.loads(test_components['2_0_basic_badgeclass'])
        set_up_image_mock(input_badgeclass['image'])

        input_issuer = json.loads(test_components['2_0_basic_issuer'])
        input_issuer['publicKey'] = input_assertion['verification']['creator']

        key = RSA.generate(2048)
        public_key_pem = key.publickey().export_key()

        cryptographic_key_doc = {
            '@context': OPENBADGES_CONTEXT_V2_URI,
            'id': input_assertion['verification']['creator'],
            'type': 'CryptographicKey',
            'owner': input_issuer['id'],
            'publicKeyPem': public_key_pem.decode()
        }

        set_up_context_mock()
        for doc in [input_badgeclass, input_issuer, cryptographic_key_doc]:
            responses.add(responses.GET, doc['id'], json=doc, status=200)

        signature = jws.sign(input_assertion, key, algorithm='RS256')

        response = verify(signature, use_cache=False)

        self.assertTrue(response['report']['valid'])
예제 #6
0
    def test_can_full_verify_with_revocation_check(self):
        input_assertion = json.loads(test_components['2_0_basic_assertion'])
        input_assertion['verification'] = {'type': 'signed', 'creator': 'http://example.org/key1'}
        set_up_image_mock(u'https://example.org/beths-robot-badge.png')

        input_badgeclass = json.loads(test_components['2_0_basic_badgeclass'])
        set_up_image_mock(input_badgeclass['image'])

        revocation_list = {
            '@context': OPENBADGES_CONTEXT_V2_URI,
            'id': 'http://example.org/revocationList',
            'type': 'RevocationList',
            'revokedAssertions': []}
        input_issuer = json.loads(test_components['2_0_basic_issuer'])
        input_issuer['revocationList'] = revocation_list['id']
        input_issuer['publicKey'] = input_assertion['verification']['creator']

        key = RSA.generate(2048)
        public_key_pem = key.publickey().export_key()

        cryptographic_key_doc = {
            '@context': OPENBADGES_CONTEXT_V2_URI,
            'id': input_assertion['verification']['creator'],
            'type': 'CryptographicKey',
            'owner': input_issuer['id'],
            'publicKeyPem': public_key_pem.decode()
        }

        set_up_context_mock()
        for doc in [input_assertion, input_badgeclass, input_issuer, cryptographic_key_doc, revocation_list]:
            responses.add(responses.GET, doc['id'], json=doc, status=200)

        header = {'alg': 'RS256'}
        payload = json.dumps(input_assertion).encode()
        signature = jws.sign(input_assertion, key, algorithm='RS256')

        response = verify(signature, use_cache=False)

        self.assertTrue(response['report']['valid'])
예제 #7
0
    def test_can_full_verify_jws_signed_assertion(self):
        """
        I can input a JWS string
        I can extract the Assertion from the input signature string and store it as the canonical version of the Assertion.
        I can discover and retrieve key information from the Assertion.
        I can Access the signing key
        I can verify the key is associated with the listed issuer Profile
        I can verify the JWS signature has been created by a key trusted to correspond to the issuer Profile
        Next: I can verify an assertion with an ephemeral embedded badgeclass as well
        """
        input_assertion = json.loads(test_components['2_0_basic_assertion'])
        input_assertion['verification'] = {'type': 'signed', 'creator': 'http://example.org/key1'}
        set_up_image_mock(u'https://example.org/beths-robot-badge.png')

        input_badgeclass = json.loads(test_components['2_0_basic_badgeclass'])
        set_up_image_mock(input_badgeclass['image'])

        input_issuer = json.loads(test_components['2_0_basic_issuer'])
        input_issuer['publicKey'] = input_assertion['verification']['creator']

        private_key = RSA.generate(2048)

        cryptographic_key_doc = {
            '@context': OPENBADGES_CONTEXT_V2_URI,
            'id': input_assertion['verification']['creator'],
            'type': 'CryptographicKey',
            'owner': input_issuer['id'],
            'publicKeyPem': private_key.publickey().exportKey('PEM').decode()
        }

        set_up_context_mock()
        for doc in [input_assertion, input_badgeclass, input_issuer, cryptographic_key_doc]:
            responses.add(responses.GET, doc['id'], json=doc, status=200)

        header = json.dumps({'alg': 'RS256'})
        payload = json.dumps(input_assertion)



        encoded_separator = '.'
        if not sys.version[:3] < '3':
            encoded_separator = '.'.encode()
            encoded_header = b64encode(header.encode())
            encoded_payload = b64encode(payload.encode())
        else:
            encoded_header = b64encode(header)
            encoded_payload = b64encode(payload)

        signature = encoded_separator.join([
            encoded_header,
            encoded_payload,
            jws.sign(header,payload,private_key, is_json=True)
        ])


        response = verify(signature, use_cache=False)

        print("TEST CAN FULLY VERIFY JWS SIGNED ASSERTION : response:")
        print(response['report'])

        self.assertTrue(response['report']['valid'])