def encrypt(self, data): data = b64_to_bytes(data) public_key = b64_to_bytes( self.public_key_full) # encrypt with full public key encrypted = self._crypto.encrypt( data, self._crypto.import_public_key(public_key)) return to_b64(encrypted)
def __save_key(self, key_data: dict, file_path: str, signer_key_data: Optional[dict] = None): byte_buffer = io.BytesIO() # Write public key pub_key_type_str = consts.VSKeyTypeS(key_data["type"]) pub_key = PubKeyStructure( start_date=int(key_data["start_date"]), expiration_date=int(key_data["expiration_date"]), key_type=consts.key_type_str_to_num_map[pub_key_type_str], ec_type=int(key_data["ec_type"]), meta_data=bytearray(key_data["meta_data"], "utf-8"), pub_key=b64_to_bytes(key_data["key"])) byte_buffer.write(bytes(pub_key)) # Write signature data if signer_key_data: signer_key_type_str = consts.VSKeyTypeS(signer_key_data["type"]) signature = Signature(signer_type=int( consts.key_type_str_to_num_map[signer_key_type_str]), ec_type=int(signer_key_data["ec_type"]), hash_type=int(key_data["signer_hash_type"]), sign=b64_to_bytes(key_data["signature"]), signer_pub_key=b64_to_bytes( signer_key_data["key"])) byte_buffer.write(bytes(signature)) with open(file_path, "wb") as f: f.write(byte_buffer.getvalue())
def footer(self) -> Footer: if self._footer is None: # Get signatures signatures = [] # Data to sign: header + body + tl_type from footer tl_type_bytes = self._tl_type.to_bytes(1, byteorder=TL_BYTE_ORDER, signed=False) data_to_sign = to_b64(bytes(self.header) + bytes(self.body) + tl_type_bytes) for key in self._signer_keys: # Sign data signature = key.sign(data_to_sign, long_sign=False) # Add signature to signatures list s = Signature( signer_type=key.key_type_secmodule, ec_type=key.ec_type_secmodule, hash_type=key.hash_type_secmodule, sign=b64_to_bytes(signature), signer_pub_key=b64_to_bytes(key.public_key) ) signatures.append(s) # Finalize footer self._footer = Footer( tl_type=self._tl_type, signatures=signatures ) return self._footer
def sign(self, data, long_sign=False): data = b64_to_bytes(data) private_key = b64_to_bytes(self.private_key) signature = self._crypto.sign( data, self._crypto.import_private_key(private_key)) if not long_sign: signature = VirgilSignExtractor.extract_sign(signature) return to_b64(signature)
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()
def __manual_add_public_key(self): self.__logger.info("Adding Public Key to db") self.__ui.print_message("Manual adding Public Key to db...") key_type_list = [ ["factory", self.__trust_list_pub_keys], ] type_choice = self.__ui.choose_from_list(key_type_list, "Please choose Key type: ", "Key types:") public_key = self.__ui.get_user_input( "Enter Public Key (tiny base64): ", input_checker_callback=self.__ui.InputCheckers.check_base64, input_checker_msg= "Can't decode, please ensure it's base64 and try again") comment = self.__ui.get_user_input( "Enter comment for [{}] Key: ".format( key_type_list[type_choice][0])) key_id = CRCCCITT().calculate(b64_to_bytes(public_key)) key_data = { "type": key_type_list[type_choice][0], "comment": comment, "key": public_key } key_type_list[type_choice][1].save(str(key_id), key_data) self.__logger.info( "[{key_type}] Key id: [{key_id}] was added to db".format( key_type=key_type_list[type_choice][0], key_id=key_id)) self.__ui.print_message("Key added")
def __init__(self, key_type: str, private_key=None, public_key=None, ec_type=VirgilKeyPair.Type_EC_SECP256R1, hash_type=HashAlgorithm.SHA256): self._crypto = VirgilCrypto() self._crypto.signature_hash_algorithm = hash_type self.__hash_type = hash_type self.__key_type = key_type self.__ec_type = ec_type self.__public_key = None if not public_key else b64_to_bytes( public_key) self.__private_key = None if not private_key else b64_to_bytes( private_key) self.__key_id = None self.__signature = None self.device_serial = None
def generate(self, *, signature_limit=None, rec_pub_keys=None, signer_key: Optional[KeyGeneratorInterface] = None, private_key_base64: Optional[str] = None, start_date: Optional[int] = 0, expire_date: Optional[int] = 0, meta_data: Optional[bytes] = bytes()): def make_signature(): byte_buffer = io.BytesIO() # vs_pubkey_dated_t byte_buffer.write( start_date.to_bytes(4, byteorder='big', signed=False)) byte_buffer.write( expire_date.to_bytes(4, byteorder='big', signed=False)) byte_buffer.write( self.key_type_secmodule.to_bytes(1, byteorder='big', signed=False)) byte_buffer.write( self.ec_type_secmodule.to_bytes(1, byteorder='big', signed=False)) byte_buffer.write( len(meta_data).to_bytes(2, byteorder='big', signed=False)) byte_buffer.write(meta_data) byte_buffer.write(b64_to_bytes(self.public_key)) bytes_to_sign = byte_buffer.getvalue() return signer_key.sign(to_b64(bytes_to_sign), long_sign=False) if private_key_base64: self.__private_key = b64_to_bytes(private_key_base64) virgil_priv_key = self._crypto.import_private_key( self.__private_key) virgil_pubkey = self._crypto.extract_public_key(virgil_priv_key) self.__public_key = VirgilKeyPair.publicKeyToDER( virgil_pubkey.raw_key)[-65:] if self.__private_key is None: virgil_key_pair = VirgilKeyPair.generate(self.ec_type) self.__private_key = VirgilKeyPair.privateKeyToDER( virgil_key_pair.privateKey()) self.__public_key = VirgilKeyPair.publicKeyToDER( virgil_key_pair.publicKey())[-65:] if signer_key: self.__signature = make_signature() return self
def __receive_cloud_key(self) -> bool: """ Receive Cloud key from service and save it to db with trust list public keys """ # Initialize cloud key (if needed) self.__ui.print_message("Try to initialize Cloud key on service") self.__logger.info("Try to initialize Cloud key on service") cloud_key.init_cloud_key(self._context, self.__logger, self.__ui) # Retrieve public cloud key self.__ui.print_message("Receive Cloud public key from service") self.__logger.info("Receive Cloud public key from service") cloud_key_response = cloud_key.receive_cloud_public_key( self._context, self.__logger, self.__ui) self.__logger.info("Cloud key received: %s" % cloud_key_response) # Save public key to db # - prepare key info to be saved # -- convert public key to tiny format public_key = to_b64(b64_to_bytes(cloud_key_response["key"])[-65:]) meta_data = self._context.virgil_api_url key_info = { "type": consts.VSKeyTypeS.CLOUD.value, "ec_type": consts.ec_type_vs_to_secmodule_map.get( VirgilKeyPair.Type_EC_SECP256R1), "start_date": cloud_key_response["start_date"], "expiration_date": cloud_key_response["end_date"], "comment": "Cloud public key", "key": public_key, "meta_data": meta_data } # - save self.__trust_list_pub_keys.save("cloud_key", key_info, suppress_db_warning=False) self.__ui.print_message("Cloud key received and stored") self.__logger.info("Cloud key stored. key_info: %s" % key_info) return True
def body(self) -> Body: if self._body is None: keys = [] for _, key_data in self._pub_keys_dict.items(): key_type_str = consts.VSKeyTypeS(key_data["type"]) start_date = int(key_data["start_date"]) expiration_date = int(key_data["expiration_date"]) ec_type = int(key_data["ec_type"]) meta_data = key_data["meta_data"] key = PubKeyStructure( start_date=start_date, expiration_date=expiration_date, key_type=consts.key_type_str_to_num_map[key_type_str], ec_type=consts.VsEcTypeE(ec_type), meta_data=bytearray(meta_data, 'utf-8'), pub_key=b64_to_bytes(key_data["key"]) ) keys.append(key) self._body = Body(keys) return self._body
def make_signature(): byte_buffer = io.BytesIO() # vs_pubkey_dated_t byte_buffer.write( start_date.to_bytes(4, byteorder='big', signed=False)) byte_buffer.write( expire_date.to_bytes(4, byteorder='big', signed=False)) byte_buffer.write( self.key_type_secmodule.to_bytes(1, byteorder='big', signed=False)) byte_buffer.write( self.ec_type_secmodule.to_bytes(1, byteorder='big', signed=False)) byte_buffer.write( len(meta_data).to_bytes(2, byteorder='big', signed=False)) byte_buffer.write(meta_data) byte_buffer.write(b64_to_bytes(self.public_key)) bytes_to_sign = byte_buffer.getvalue() return signer_key.sign(to_b64(bytes_to_sign), long_sign=False)
def __save_private_key(self, key, file_path): byte_buffer = io.BytesIO() byte_buffer.write(b64_to_bytes(key)) open(file_path, "wb").write(bytes(byte_buffer.getvalue()))
def decrypt(self, data): data = b64_to_bytes(data) private_key = b64_to_bytes(self.private_key) decrypted = self._crypto.decrypt( data, self._crypto.import_private_key(private_key)) return to_b64(decrypted)
def verify(self, data, signature, long_sign=False): data = b64_to_bytes(data) public_key = b64_to_bytes( self.public_key_full) # verify signature with full public key return self._crypto.verify(data, signature, self._crypto.import_public_key(public_key))
def key_id(self): return CRCCCITT().calculate(b64_to_bytes(self.public_key))
def public_key_full(self): virgil_private_key = self._crypto.import_private_key( b64_to_bytes(self.private_key)) return to_b64(self._crypto.extract_public_key(virgil_private_key))