예제 #1
0
    def test_initialize_many(self):
        """ Check that multiple keys generated, wrapped with users' public keys,
            and stored in a keystore can be retrieved and unwrapped with the 
            users' secret keys.
        """

        keygen = KeyGen('Sixteen byte key')
        keystore = DummyKeyStore()

        key_infos = [('attr' + str(i), i, 'meta' + str(i), 16)
                     for i in xrange(self.num_keys)]

        users = {}
        RSA_sks = {}
        for i in xrange(self.num_users):
            userid = 'user' + str(i)
            RSA_key = RSA.generate(3072)
            RSA_sks[userid] = RSA_key
            RSA_pk = RSA_key.publickey()

            info = random.sample(key_infos, random.randint(1, len(key_infos)))
            users[userid] = (RSA_pk, info)

        keygen.initialize_users(users, keystore)

        for userid in users:
            RSA_pk, info = users[userid]
            for attr, vers, meta, keylen in info:
                keywrap = keystore.retrieve(userid, attr, vers, meta)
                self.assertEqual(
                    utils.unwrap_key(keywrap, RSA_sks[userid]),
                    keygen._generate_key(attr, vers, meta, keylen))
예제 #2
0
    def test_init_many_from_file(self):
        """ Check that multiple keys generated, wrapped with users' public keys,
            and stored in a keystore can be retrieved and unwrapped with the 
            users' secret keys when input comes from a configuration file.
        """
        keygen = KeyGen('Sixteen byte key')
        keystore = DummyKeyStore()

        user_info = {
            'user1': [('attr1', 1, 'AES_GCM', 16), ('attr2', 1, 'AES_GCM', 16),
                      ('attr3', 2, 'AES_GCM', 16)],
            'user2': [('attr2', 1, 'AES_GCM', 16),
                      ('attr4', 2, 'AES_GCM', 16)],
            'user3': [('attr1', 1, 'AES_GCM', 16), ('attr4', 2, 'AES_GCM', 16)]
        }

        self.create_configs_from_dict(user_info,
                                      TMP_PATH + '/user_info_test.cfg')

        keygen.init_from_file(TMP_PATH + '/user_info_test.cfg', keystore)

        for userid in user_info:
            key_infos = user_info[userid]
            f = open(TMP_PATH + '/' + userid + '_privkey.pem', 'r')
            RSA_sk = RSA.importKey(f.read())
            f.close()
            for attr, vers, meta, keylen in key_infos:
                keywrap = keystore.retrieve(userid, attr, vers, meta)
                self.assertEqual(
                    utils.unwrap_key(keywrap, RSA_sk),
                    keygen._generate_key(attr, vers, meta, keylen))
예제 #3
0
 def get_attribute_key(self, algorithm, attribute, version=1):
     """
     Arguments:
     algorithm - (string) Name of algorithm for which the user
                 wishes to retrieve the current key for, triggers
                 PKILookupError if the algorithm is not part
                 of VIS_ALGORITHMS 
     attribute - (string) Attribute for which to retrieve the key for
     version - (int)version of key to grab, defaults to 1
     
     Returns:
         Key for (userid, algorithm, attribute, version) tuple
         
     Raises:
         PKILookupError if the key cannot be found for the 
         (userid, algorithm, attribute, version) tuple.
         
     """
     #get the keys
     try:
         key_wrap = self._acc_keystore.retrieve(self._user_id, attribute,
                                                version, algorithm)
     except PKILookupError as ple:
         raise PKILookupError(
             "User %s with algorithm %s and attribute %s is not present in keystore."
             % (self._user_id, algorithm, attribute))
     #unwrap the key
     return key_utils.unwrap_key(key_wrap, self._rsa_key)
예제 #4
0
 def get_key(self, algorithm, version=1):
     """
     Arguments:
     algorithm - (string) Name of algorithm for which the user
                 wishes to retrieve the key for, triggers
                 PKILookupError if the algorithm is not part
                 of AES_ALGORITHMS
     version - (int) version of key to grab, defaults to 1
     
     Returns:
         Key for (userid, algorithm, version) tuple
     
     Raises:
         PKILookupError if the key cannot be found for the
         (userid, algorithm, version) tuple. 
         
     """
     #get the keys
     try:
         key_wrap = self._acc_keystore.retrieve(self._user_id, '', version,
                                                algorithm)
     except PKILookupError:
         raise PKILookupError("User " + self._user_id + " with algorithm " +\
                               algorithm + " is not present in keystore.")
     #unwrap the key
     return key_utils.unwrap_key(key_wrap, self._rsa_key)
예제 #5
0
    def get_current_attribute_key(self, algorithm, attribute):
        """
        Arguments:
        algorithm - (string) Name of algorithm for which the user
                    wishes to retrieve the key for, triggers
                    PKILookupError if the algorithm is not part
                    of AES_ALGORITHMS 
        attribute - (string) Attribute for which to retrieve the key for
        
        Returns:
            (Most current key for (userid, algorithm, attribute) tuple, version)
        
        Raises:
            PKILookupError if the key cannot be found for the
            (userid, algorithm, attribute) tuple. 
            
        """
        #get the keys
        try:
            key_wrap = self._acc_keystore.retrieve_latest_version(
                self._user_id, algorithm, attribute)
        except PKILookupError as ple:
            raise PKILookupError(
                "User %s with algorithm %s and attribute %s is not present in keystore."
                % (self._user_id, algorithm, attribute))

        #unwrap the key
        return (key_utils.unwrap_key(key_wrap.keywrap,
                                     self._rsa_key), key_wrap.vers)
예제 #6
0
    def get_current_key(self, algorithm):
        """
        Arguments:
        algorithm - (string) Name of algorithm for which the user
                    wishes to retrieve the key for, triggers
                    PKILookupError if the algorithm is not part
                    of AES_ALGORITHMS
        
        Returns:
            (Most current key for (userid, algorithm) tuple, version)
        
        Raises:
            PKILookupError if the key cannot be found for the
            (userid, algorithm) tuple. 
            
        """
        #get the keys
        try:
            key_wrap = self._acc_keystore.retrieve_latest_version(
                self._user_id, algorithm, '')
        except PKILookupError:
            raise PKILookupError("User " + self._user_id + " with algorithm " +\
                                  algorithm + " is not present in keystore.")

        #unwrap the key
        return (key_utils.unwrap_key(key_wrap.keywrap,
                                     self._rsa_key), key_wrap.vers)
예제 #7
0
    def test_initialize_diff_users_same_info(self):
        """ Check that two different users can recover the same key for the 
            same attribute, version, metadata, key length combination.
        """

        RSA_key1 = RSA.generate(3072)
        RSA_pk1 = RSA_key1.publickey()
        RSA_key2 = RSA.generate(3072)
        RSA_pk2 = RSA_key2.publickey()
        keygen = KeyGen('Sixteen byte key')
        keystore = DummyKeyStore()
        keygen.initialize_users(
            {
                'user1': (RSA_pk1, [('attr', 1, 'meta', 16)]),
                'user2': (RSA_pk2, [('attr', 1, 'meta', 16)])
            }, keystore)
        keywrap1 = keystore.retrieve('user1', 'attr', 1, 'meta')
        keywrap2 = keystore.retrieve('user2', 'attr', 1, 'meta')
        self.assertEqual(utils.unwrap_key(keywrap1, RSA_key1),
                         utils.unwrap_key(keywrap2, RSA_key2))
예제 #8
0
    def test_initialize_single(self):
        """ Check that a key generated, wrapped with a user's public key, and 
            stored in a keystore can be retrieved and unwrapped with the user's
            secret key.
        """

        RSA_key = RSA.generate(3072)
        RSA_pk = RSA_key.publickey()
        keygen = KeyGen('Sixteen byte key')
        keystore = DummyKeyStore()
        orig_key = keygen._generate_key('attr', 1, 'meta', 16)
        keygen.initialize_users(
            {'userid': (RSA_pk, [('attr', 1, 'meta', 16)])}, keystore)
        keywrap = keystore.retrieve('userid', 'attr', 1, 'meta')
        self.assertEqual(utils.unwrap_key(keywrap, RSA_key), orig_key)
 def test_valid_enc_dec(self):
     """ Check that we can unwrap a key using the private key 
         corresponding to the public key used to wrap the key.
     """
     RSA_key = RSA.generate(3072)
     RSA_pk = RSA_key.publickey()
     for i in range(self.num_iters):
         sk = format(random.getrandbits(128), 'b')
         keywrap = wrap_key(sk, RSA_pk)
         try:
             decrypted_key = unwrap_key(keywrap, RSA_key)
         except ValueError as e:
             self.assertTrue(False, 'Error: %s' % e.msg)
         else:
             self.assertEqual(decrypted_key, sk,
                              'Failed to unwrap original key')
 def test_invalid_enc_dec(self):
     """ Check that we cannot unwrap a key using a private key that does
         not correspond to the public key used to wrap the key.
     """
     RSA_key = RSA.generate(3072)
     RSA_pk = RSA_key.publickey()
     for i in range(self.num_iters):
         sk = format(random.getrandbits(128), 'b')
         keywrap = wrap_key(sk, RSA_pk)
         other_key = RSA.generate(3072)
         try:
             decrypted_key = unwrap_key(keywrap, other_key)
         except ValueError:
             self.assertTrue(True, 'error')
         else:
             self.assertNotEqual(decrypted_key, sk,
                                 'Decryption succeeded with invalid key')
예제 #11
0
    def test_initialize_empty(self):
        """ Check that a key generated from empty string inputs, wrapped with a
            user's public key, and stored in a keystore can be retrieved and 
            unwrapped with the user's secret key.
        """

        RSA_key = RSA.generate(3072)
        RSA_pk = RSA_key.publickey()
        keygen = KeyGen('Sixteen byte key')
        keystore = DummyKeyStore()

        params = [('', 'attr', 1, 'meta'), ('userid', '', 1, 'meta'),
                  ('userid', 'attr', 0, 'meta'), ('userid', 'attr', 1, ''),
                  ('', '', 0, '')]

        for userid, attr, vers, meta in params:
            orig_key = keygen._generate_key(attr, vers, meta, 16)
            keygen.initialize_users(
                {userid: (RSA_pk, [(attr, vers, meta, 16)])}, keystore)
            keywrap = keystore.retrieve(userid, attr, vers, meta)
            self.assertEqual(utils.unwrap_key(keywrap, RSA_key), orig_key)
예제 #12
0
    def test_revocation_all_attrs(self):
        """ Tests that revoking all of a user's attributes removes the 
            appropriate entries from the keystore and the user/attr maps and 
            generates wraps of new keys for the correct set of users.
        """
        keygen = KeyGen('Sixteen byte key')
        ks = DummyKeyStore()
        attr_user_dict = {
            'A': ['user1', 'user2', 'user3'],
            'B': ['user1', 'user2'],
            'C': ['user1', 'user3']
        }
        attr_user_map = LocalAttrUserMap(attr_user_dict)
        user_attr_dict = {
            'user1': ['A', 'B', 'C'],
            'user2': ['A', 'B'],
            'user3': ['A', 'C']
        }
        user_attr_map = LocalUserAttrMap(user_attr_dict)

        user_sks = {}
        user_pks = {}
        for i in range(1, 4):
            userid = 'user' + str(i)
            RSA_key = RSA.generate(3072)
            user_sks[userid] = RSA_key
            RSA_pk = RSA_key.publickey()
            user_pks[userid] = RSA_pk

        key_infos = {
            'user1': [
                KeyInfo('A', 1, 'meta1', 'keywrap1', 16),
                KeyInfo('A', 1, 'meta2', 'keywrap2', 16),
                KeyInfo('B', 1, 'meta1', 'keywrap4', 16),
                KeyInfo('B', 1, 'meta2', 'keywrap5', 16),
                KeyInfo('C', 1, 'meta1', 'keywrap6', 16),
                KeyInfo('C', 1, 'meta2', 'keywrap7', 16)
            ],
            'user2': [
                KeyInfo('A', 1, 'meta2', 'keywrap8', 16),
                KeyInfo('A', 1, 'meta3', 'keywrap9', 16),
                KeyInfo('B', 1, 'meta1', 'keywrap10', 16),
                KeyInfo('B', 1, 'meta2', 'keywrap11', 16)
            ],
            'user3': [
                KeyInfo('A', 1, 'meta1', 'keywrap12', 16),
                KeyInfo('A', 1, 'meta2', 'keywrap13', 16),
                KeyInfo('A', 1, 'meta3', 'keywrap14', 16),
                KeyInfo('C', 1, 'meta1', 'keywrap15', 16),
                KeyInfo('C', 1, 'meta2', 'keywrap16', 16)
            ]
        }

        for user in key_infos:
            ks.batch_insert(user, key_infos[user])

        #revoke all attributes from a user
        keygen.revoke_all_attrs('user1', ks, attr_user_map, user_attr_map,
                                user_pks)

        #check that keywraps for revoked user were removed from keystore
        for i in range(1, 3):
            self.assertRaises(PKILookupError, ks.retrieve, 'user1', 'A', 1,
                              'meta' + str(i))
            self.assertRaises(PKILookupError, ks.retrieve, 'user1', 'B', 1,
                              'meta' + str(i))
            self.assertRaises(PKILookupError, ks.retrieve, 'user1', 'C', 1,
                              'meta' + str(i))

        #check that updated user/attr maps are correct
        self.assertEqual(set(attr_user_map.users_by_attribute('A')),
                         set(['user2', 'user3']))
        self.assertEqual(attr_user_map.users_by_attribute('B'), ['user2'])
        self.assertEqual(attr_user_map.users_by_attribute('C'), ['user3'])
        self.assertEqual(user_attr_map.attributes_by_user('user1'), [])
        self.assertEqual(set(user_attr_map.attributes_by_user('user2')),
                         set(['A', 'B']))
        self.assertEqual(set(user_attr_map.attributes_by_user('user3')),
                         set(['A', 'C']))

        #check that metadatas for revoked attrs have correct version numbers
        self.assertEqual(ks.retrieve_latest_version_number('meta1', 'A'), 2)
        self.assertEqual(ks.retrieve_latest_version_number('meta2', 'A'), 2)
        self.assertEqual(ks.retrieve_latest_version_number('meta3', 'A'), 1)
        self.assertEqual(ks.retrieve_latest_version_number('meta1', 'B'), 2)
        self.assertEqual(ks.retrieve_latest_version_number('meta2', 'B'), 2)

        #check that other users with revoked attrs got new keywraps that decrypt
        #to keys of the correct length
        kw_2_2_A = ks.retrieve_latest_version('user2', 'meta2', 'A').keywrap
        kw_3_1_A = ks.retrieve_latest_version('user3', 'meta1', 'A').keywrap
        kw_3_2_A = ks.retrieve_latest_version('user3', 'meta2', 'A').keywrap
        kw_2_1_B = ks.retrieve_latest_version('user2', 'meta1', 'B').keywrap
        kw_2_2_B = ks.retrieve_latest_version('user2', 'meta2', 'B').keywrap
        kw_3_1_C = ks.retrieve_latest_version('user3', 'meta1', 'C').keywrap
        kw_3_2_C = ks.retrieve_latest_version('user3', 'meta2', 'C').keywrap

        self.assertEqual(len(utils.unwrap_key(kw_2_2_A, user_sks['user2'])),
                         16)
        self.assertEqual(len(utils.unwrap_key(kw_3_1_A, user_sks['user3'])),
                         16)
        self.assertEqual(len(utils.unwrap_key(kw_3_2_A, user_sks['user3'])),
                         16)
        self.assertEqual(len(utils.unwrap_key(kw_2_1_B, user_sks['user2'])),
                         16)
        self.assertEqual(len(utils.unwrap_key(kw_2_2_B, user_sks['user2'])),
                         16)
        self.assertEqual(len(utils.unwrap_key(kw_3_1_C, user_sks['user3'])),
                         16)
        self.assertEqual(len(utils.unwrap_key(kw_3_2_C, user_sks['user3'])),
                         16)

        #revoke all attributes from a user and update some key lengths
        keylens = {'meta2': 24}
        keygen.revoke_all_attrs('user2', ks, attr_user_map, user_attr_map,
                                user_pks, keylens)

        #check that new keys for other users have correct key lengths
        kw_3_2_A = ks.retrieve_latest_version('user3', 'meta2', 'A').keywrap
        kw_3_3_A = ks.retrieve_latest_version('user3', 'meta3', 'A').keywrap
        self.assertEqual(len(utils.unwrap_key(kw_3_2_A, user_sks['user3'])),
                         24)
        self.assertEqual(len(utils.unwrap_key(kw_3_3_A, user_sks['user3'])),
                         16)