Exemple #1
0
 def import_card(self, card_to_import):
     # type: (Union[str, dict, RawSignedModel]) -> Card
     """
     Imports and verifies Card.
     Args:
         card_to_import: Exported data of signed model.
     Returns:
         Imported and verified card.
     """
     if isinstance(card_to_import,
                   str) or Utils.check_unicode(card_to_import):
         card_to_import = str(card_to_import)
         try:
             if isinstance(Utils.json_loads(card_to_import), dict):
                 card = Card.from_signed_model(
                     self._card_crypto,
                     RawSignedModel.from_json(card_to_import))
             else:
                 raise JSONDecodeError
         except (JSONDecodeError, ValueError) as e:
             card = Card.from_signed_model(
                 self._card_crypto,
                 RawSignedModel.from_string(card_to_import))
     elif isinstance(card_to_import, dict) or isinstance(
             card_to_import, bytes):
         card = Card.from_signed_model(
             self._card_crypto, RawSignedModel.from_json(card_to_import))
     elif isinstance(card_to_import, RawSignedModel):
         card = Card.from_signed_model(self._card_crypto, card_to_import)
     elif card_to_import is None:
         raise ValueError("Missing card to import")
     else:
         raise TypeError("Unexpected type for card import")
     self.__validate(card)
     return card
Exemple #2
0
    def _create_raw_card(self, key_pair: KeyGeneratorInterface,
                         key_info: dict) -> str:
        # Prepare public key in virgil format
        public_key = key_pair.public_key
        public_key = tiny_key_to_virgil(public_key)
        public_key = self._crypto.import_public_key(public_key)

        # Calculate identity.
        identity = key_pair.key_type
        # For keys which amount is 2 there should be identities like auth_1, auth_2
        if key_pair.key_type in (VSKeyTypeS.RECOVERY.value,
                                 VSKeyTypeS.AUTH.value,
                                 VSKeyTypeS.TRUSTLIST.value,
                                 VSKeyTypeS.FIRMWARE.value):
            if key_pair.key_type not in self._keys_counter or self._keys_counter[
                    key_pair.key_type] == 2:
                key_number = 1
            else:
                key_number = 2
            identity = "%s_%s" % (identity, key_number)
            self._keys_counter[key_pair.key_type] = key_number

        # Prepare card content snapshot
        created_at = int(datetime.utcnow().timestamp())
        card_content = RawCardContent(identity=identity,
                                      public_key=public_key,
                                      created_at=created_at)
        card_content_snapshot = card_content.content_snapshot

        # Create raw card
        raw_card = RawSignedModel(card_content_snapshot)

        # Sign combined snapshot (with key_info)
        key_info_b = json.dumps(key_info).encode("utf-8")
        key_info_b64 = to_b64(key_info_b)
        combined_snapshot = to_b64(
            b64_to_bytes(card_content_snapshot) + b64_to_bytes(key_info_b64))

        signature = key_pair.sign(combined_snapshot, long_sign=True)
        if not signature:
            err_msg = "[ERROR]: Virgil Card creation request: signing failed"
            self._ui.print_error(err_msg)
            self._logger.error(err_msg)
            sys.exit(1)

        raw_signature = RawSignature(
            signer="self",
            signature=b64_to_bytes(signature),
            signature_snapshot=b64_to_bytes(key_info_b64))

        # Append signature to card
        raw_card.signatures.append(raw_signature)

        # Return card request as json string
        return raw_card.to_json()
Exemple #3
0
 def test_create_from_raw_card_content(self):
     # STC-1
     raw_signed_model = RawSignedModel.from_json(
         self._compatibility_data["STC-1.as_json"])
     raw_card_content = RawCardContent.from_signed_model(
         self._crypto, raw_signed_model)
     raw_signed_model_from_raw_card_content = RawSignedModel(
         raw_card_content.content_snapshot)
     self.assertEqual(
         raw_signed_model.content_snapshot,
         raw_signed_model_from_raw_card_content.content_snapshot)
     self.assertDictEqual(vars(raw_signed_model),
                          vars(raw_signed_model_from_raw_card_content))
Exemple #4
0
 def export_card_to_raw_card(self, card):
     # type: (Card) -> RawSignedModel
     """
     Exports the specified card as a RawSignedModel.
     Args:
         card: Card instance to be exported.
     Returns:
         Returns instance of RawSignedModel representing Card.
     """
     raw_signed_model = RawSignedModel(card.content_snapshot)
     for signature in card.signatures:
         raw_signed_model.add_signature(signature)
     return raw_signed_model
Exemple #5
0
    def generate_raw_signed_model(
            self,
            key_pair,
            add_self_sign=False,
            virgil_key_pair=None,
            extra_key_pair=None,
            previous_card_id=None
    ):
        create_time = 1515686245
        raw_card_content = RawCardContent(
            created_at=create_time,
            identity="test",
            public_key=key_pair.public_key,
            version="5.0",
            previous_card_id=previous_card_id
        )
        model = RawSignedModel(raw_card_content.content_snapshot)
        signer = ModelSigner(CardCrypto())

        if add_self_sign:
            signer.self_sign(model, key_pair.private_key)

        if virgil_key_pair:
            signer.sign(model, ModelSigner.VIRGIL_SIGNER, virgil_key_pair.private_key)

        if extra_key_pair:
            signer.sign(model, "extra", extra_key_pair.private_key)

        return model
Exemple #6
0
    def get_card(self, card_id, token):
        # type: (str, str) -> Tuple[RawSignedModel, bool]
        """
        Gets a card from Virgil Services by specified card ID.
        Args:
            card_id: The Card ID.
            token: The string representation of Jwt token.
        Returns:
            An instance of RawSignedModel class and flag,
            which determines whether or not this raw card is superseded.
        Raises:
            ValueError: Missed argument.
        """
        if not card_id:
            raise ValueError("Missing card id")

        if not token:
            raise ValueError("Missing access token")

        request = Request("/card/v5/{}".format(card_id), )

        request.authorization(token)

        response, headers = self.__connection.send(request)

        card_raw = RawSignedModel(**response)

        superseded = False
        if headers and "X-VIRGIL-IS-SUPERSEEDED" in headers.keys():
            if headers["X-VIRGIL-IS-SUPERSEEDED"]:
                superseded = True

        return card_raw, superseded
Exemple #7
0
    def generate_raw_card(self,
                          private_key,
                          public_key,
                          identity,
                          previous_card_id="",
                          extra_fields=None):
        # type: (PrivateKey, PublicKey, str, Optional[str], Optional[dict]) -> RawSignedModel
        """

        Args:
            private_key: PrivateKey for generate self signature.
            public_key: Card Public key.
            identity: Unique identity value.
            previous_card_id: Previous card id that current card is used to override to.
            extra_fields: The additional data associated with the card.
        Returns:
            The instance of newly published Card.
        """
        current_time = Utils.to_timestamp(datetime.datetime.utcnow())
        raw_card = RawSignedModel.generate(public_key, identity, current_time,
                                           previous_card_id)
        self.model_signer.self_sign(raw_card,
                                    private_key,
                                    extra_fields=extra_fields)
        return raw_card
Exemple #8
0
 def __parse_cards_from_response(self, response):
     if response:
         result = list()
         for card in response:
             result.append(RawSignedModel(**card))
         return result
     else:
         return response
Exemple #9
0
 def test_generate_pure_model_from_string(self):
     # STC-1
     rsm = RawSignedModel.from_string(
         self._compatibility_data["STC-1.as_string"])
     rsm_string = rsm.to_string()
     self.assertEqual(self._compatibility_data["STC-1.as_string"],
                      rsm_string)
     self.assertEqual(
         Utils.json_loads(
             Utils.b64decode(self._compatibility_data["STC-1.as_string"]))
         ["signatures"], rsm.signatures)
Exemple #10
0
 def test_generate_pure_model_from_json(self):
     # STC-1
     rsm = RawSignedModel.from_json(
         self._compatibility_data["STC-1.as_json"])
     rsm_json = rsm.to_json()
     self.assertDictEqual(
         json.loads(self._compatibility_data["STC-1.as_json"]),
         json.loads(rsm_json))
     self.assertEqual(
         json.loads(
             self._compatibility_data["STC-1.as_json"])["signatures"],
         rsm.signatures)
Exemple #11
0
 def test_generate_full_model_from_json(self):
     # STC-2
     rsm = RawSignedModel.from_json(
         self._compatibility_data["STC-2.as_json"])
     rsm_json = rsm.to_json()
     self.assertDictEqual(
         json.loads(self._compatibility_data["STC-2.as_json"]),
         json.loads(rsm_json))
     self.assertEqual(
         json.dumps(json.loads(
             self._compatibility_data["STC-2.as_json"])["signatures"],
                    sort_keys=True),
         json.dumps(list(map(lambda x: x.to_json(), rsm.signatures)),
                    sort_keys=True))
Exemple #12
0
 def test_generate_full_model_from_string(self):
     # STC-2
     rsm = RawSignedModel.from_string(
         self._compatibility_data["STC-2.as_string"])
     rsm_string = rsm.to_string()
     self.assertEqual(self._compatibility_data["STC-2.as_string"],
                      rsm_string)
     self.assertEqual(
         json.dumps(json.loads(
             Utils.b64decode(
                 self._compatibility_data["STC-2.as_string"]).decode())
                    ["signatures"],
                    sort_keys=True),
         json.dumps(list(map(lambda x: x.to_json(), rsm.signatures)),
                    sort_keys=True))
Exemple #13
0
    def test_gets_card_with_different_id(self):
        class PositiveVerifier(object):
            def verify_card(self):
                return True

        class FakeCardClient(object):
            def __init__(self, raw_signed_model):
                self._raw_signed_model = raw_signed_model

            def get_card(self, card_id, access_token):
                return self._raw_signed_model, False

        validator = PositiveVerifier()
        key_pair = self._crypto.generate_keys()
        raw_card_content = RawCardContent(identity="test",
                                          public_key=key_pair.public_key,
                                          created_at=Utils.to_timestamp(
                                              datetime.datetime.now()),
                                          version="5.0")
        model = RawSignedModel(raw_card_content.content_snapshot)
        signer = ModelSigner(CardCrypto())
        signer.self_sign(model,
                         key_pair.private_key,
                         extra_fields={"info": "some_additional_info"})
        jwt_generator = JwtGenerator(config.VIRGIL_APP_ID,
                                     self._app_private_key,
                                     config.VIRGIL_API_KEY_ID,
                                     datetime.timedelta(minutes=10).seconds,
                                     AccessTokenSigner())
        identity = Utils.b64encode(os.urandom(20))
        token = jwt_generator.generate_token(identity)
        access_token_provider = self.EchoTokenProvider(token)
        card_id = self._data_generator.generate_app_id()
        manager = CardManager(
            card_crypto=CardCrypto(),
            access_token_provider=access_token_provider,
            card_verifier=validator,
        )
        manager.card_client = FakeCardClient(model)
        self.assertRaises(CardVerificationException, manager.get_card, card_id)
Exemple #14
0
    def publish_card(self, raw_card, token):
        # type: (RawSignedModel, str) -> RawSignedModel
        """
        Publishes card in Virgil Cards service.
        Args:
            raw_card: An instance of RawSignedModel class.
            token: The string representation of Jwt token.
        Returns:
            Published raw card.
        """
        if not raw_card:
            raise ValueError("Missing raw card")

        if not token:
            raise ValueError("Missing JWT token")

        request = Request("/card/v5",
                          Utils.json_loads(raw_card.to_json()),
                          method=Request.POST)

        request.authorization(token)
        response, headers = self.__connection.send(request)
        return RawSignedModel(**response)
Exemple #15
0
 def test_create_from_signed_model_string(self):
     # STC-1
     raw_signed_model = RawSignedModel.from_string(self._compatibility_data["STC-1.as_string"])
     raw_card_content = RawCardContent.from_signed_model(self._crypto, raw_signed_model)
     self.assertEqual(raw_signed_model.content_snapshot, raw_card_content.content_snapshot)
Exemple #16
0
 def __emulate_server_app_sign_response(self, model_sting):
     raw_signed_model = RawSignedModel.from_string(model_sting)
     return raw_signed_model.to_string()
Exemple #17
0
 def sign_callback(self, model):
     response = self.__emulate_server_app_sign_response(model.to_string())
     return RawSignedModel.from_string(response)