class_docstr: Implementation for experiment payload builder
  using public key RSA encryption.
class_docstr_tok: ["Implementation","for","experiment","payload","builder","using","public","key","RSA","encryption","."]
docstr: param: name - payload builder name
  param: receiver_keypath - file path to .pem file
                            with recipient public key
  param: sender_keypath - file path to .pem file
                            with sender private key
docstr_tok: ["param",":","name","-","payload","builder","name","param",":","receiver_keypath","-","file","path","to",".pem","file","with","recipient","public","key","param",":","sender_keypath","-","file","path","to",".pem","file","with","sender","private","key"]
code: def __init__(
      self, name: str, receiver_keypath: str, sender_keypath: str = None
  ):
      """
      param: name - payload builder name
      param: receiver_keypath - file path to .pem file
                                with recipient public key
      param: sender_keypath - file path to .pem file
                                with sender private key
      """
      super(EncryptedPayloadBuilder, self).__init__(name)
  
      # XXX Set logger verbosity level here
      self.logger = logs.get_logger(self.__class__.__name__)
  
      self.recipient_key_path = receiver_keypath
      self.recipient_key = None
      try:
          self.recipient_key = RSA.import_key(
              open(self.recipient_key_path).read()
          )
      except:
          check_for_kb_interrupt()
          msg = (
              "FAILED to import recipient public key from: {0}".format(
                  self.recipient_key_path
              )
          )
          self.logger.error(msg)
          raise ValueError(msg)
  
      self.sender_key_path = sender_keypath
  
      self.sender_key: SigningKey = None
      self.verify_key: VerifyKey = None
      self.sender_fingerprint = None
  
      if self.sender_key_path is None:
          self.logger.error(
              "Signing key path must be specified for encrypted payloads. ABORTING."
          )
          raise ValueError()
  
      # We expect ed25519 signing key in "openssh private key" format
      try:
          (
              public_key_data,
              private_key_data,
          ) = Ed25519KeyUtil.parse_private_key_file(
              self.sender_key_path, self.logger
          )
          if public_key_data is None or private_key_data is None:
              self._raise_error(
                  "Failed to import private signing key from {0}. ABORTING.".format(
                      self.sender_key_path
                  )
              )
  
          self.sender_key = SigningKey(private_key_data)
          self.verify_key = VerifyKey(public_key_data)
      except Exception:
          self._raise_error(
              "FAILED to open/read private signing key file: {0}".format(
                  self.sender_key_path
              )
          )
  
      self.sender_fingerprint = self._get_fingerprint(public_key_data)
  
      self.simple_builder = UnencryptedPayloadBuilder(
          "simple-builder-for-encryptor"
      )
  
imports: from Crypto.PublicKey import RSA
  from Crypto.Cipher import PKCS1_OAEP
  from Crypto.Hash import SHA256
  import nacl.secret
  import nacl.utils
  from nacl.signing import SigningKey, VerifyKey
  import base64
  import json
  from sshpubkeys import SSHKey
  from studio.ed25519_key_util import Ed25519KeyUtil
  from studio.payload_builders.payload_builder import PayloadBuilder
  from studio.util import logs
  from studio.payload_builders.unencrypted_payload_builder import UnencryptedPayloadBuilder
  from studio.util.util import check_for_kb_interrupt
label_desc: Use image node_id 1 to create a new EncryptedPayloadBuilder object from inherited base classes: PayloadBuilder with example: obj = EncryptedPayloadBuilder(name, receiver_keypath, sender_keypath)