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
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