docs: def gpg_fetch_key( key_url, key_id=None, config_dir=None ):
      """
      Fetch a GPG public key from the given URL.
      Supports anything urllib2 supports.
      If the URL has no scheme, then assume it's a PGP key server, and use GPG to go get it.
      The key is not accepted into any keyrings.
      Return the key data on success.  If key_id is given, verify the key matches.
      Return None on error, or on failure to carry out any key verification
      """
  
      dat = None
      from_blockstack = False
  
      # make sure it's valid 
      try:
          urlparse.urlparse(key_url)
      except:
          log.error("Invalid URL")
          return None
  
      if "://" in key_url and not key_url.lower().startswith("iks://"):
  
          opener = None 
          key_data = None
  
          # handle blockstack:// URLs
          if key_url.startswith("blockstack://"):
              blockstack_opener = BlockstackHandler( config_path=os.path.join(config_dir, blockstack_client.CONFIG_FILENAME) )
              opener = urllib2.build_opener( blockstack_opener )
              from_blockstack = True
  
          elif key_url.lower().startswith("http://") or key_url.lower().startswith("https://"):
              # fetch, but at least try not to look like a bot
              opener = urllib2.build_opener()
              opener.addheaders = [('User-agent', 'Mozilla/5.0')]
  
          else:
              # defaults
              opener = urllib2.build_opener()
  
          try:
              f = opener.open( key_url )
              key_data_str = f.read()
              key_data = None
  
              if from_blockstack:
                  # expect: {'key name': 'PEM string'}
                  key_data_dict = json.loads(key_data_str)
                  assert len(key_data_dict) == 1, "Got multiple keys"
                  key_data = str(key_data_dict[key_data_dict.keys()[0]])
  
              else:
                  # expect: PEM string
                  key_data = key_data_str
  
              f.close()
  
          except Exception, e:
              log.exception(e)
              if key_id is not None:
                  log.error("Failed to fetch key '%s' from '%s'" % (key_id, key_url))
              else:
                  log.error("Failed to fetch key from '%s'" % key_url)
              return None
  
          # verify, if we have the ID.
          # if we don't have the key ID, then we must be fetching from blockstack 
          # (since then the data will have already been verified by the protocol, using locally-hosted trusted information)
          if not from_blockstack and key_id is None:
              log.error( "No key ID given for key located at %s" % key_url )
              return None
  
          if key_id is not None:
              rc = gpg_verify_key( key_id, key_data, config_dir=config_dir )
              if not rc:
                  log.error("Failed to verify key %s" % key_id)
                  return None
  
          dat = key_data 
  
      else:
          # iks protocol, fetch from keyserver
          key_server = key_url
          if '://' in key_server:
              key_server = urlparse.urlparse(key_server).netloc
  
          dat = gpg_download_key( key_id, key_server, config_dir=config_dir )
          assert dat is not None and len(dat) > 0, "BUG: no key data received for '%s' from '%s'" % (key_id, key_url)
  
      return dat