def test_rebuild_gpg_home_signed(context, trusted_email, tmpdir):

    gpg = sgpg.GPG(context)
    for path in glob.glob(
            os.path.join(GPG_HOME, "keys", "{}.*".format(trusted_email))):
        shutil.copyfile(path, os.path.join(tmpdir, os.path.basename(path)))
    sgpg.rebuild_gpg_home_signed(
        context,
        context.config['gpg_home'],
        "{}{}".format(KEYS_AND_FINGERPRINTS[0][2], ".pub"),
        "{}{}".format(KEYS_AND_FINGERPRINTS[0][2], ".sec"),
        tmpdir,
    )
    with open(os.path.join(PUBKEY_DIR, "manifest.json")) as fh:
        manifest = json.load(fh)
    for fingerprint, info in manifest.items():
        with open(os.path.join(PUBKEY_DIR, info['signed_path'])) as fh:
            sgpg.import_key(gpg, fh.read())
        if info['signing_email'] == trusted_email:
            sgpg.get_list_sigs_output(
                context,
                fingerprint,
                expected={'sig_keyids': [info['signing_keyid']]})
    messages = check_sigs(context,
                          manifest,
                          PUBKEY_DIR,
                          trusted_emails=[trusted_email])
    assert messages == []
def test_get_list_sigs_output_failure(base_context, mocker):

    # check_call needs popen to be a decorator
    @contextmanager
    def popen(*args, **kwargs):
        yield FakeProc(output=b'No public key', returncode=0)

    mocker.patch.object(subprocess, "Popen", new=popen)
    with pytest.raises(ScriptWorkerGPGException):
        sgpg.get_list_sigs_output(base_context, "nonexistent_fingerprint")
def test_sign_key_exportable(context, exportable):
    gpg_home2 = os.path.join(context.config['gpg_home'], "two")
    context.config['gpg_home'] = os.path.join(context.config['gpg_home'],
                                              "one")
    gpg = sgpg.GPG(context)
    gpg2 = sgpg.GPG(context, gpg_home=gpg_home2)
    my_fingerprint = KEYS_AND_FINGERPRINTS[0][1]
    my_keyid = KEYS_AND_FINGERPRINTS[0][0]
    # import my keys
    for suffix in (".sec", ".pub"):
        with open("{}{}".format(KEYS_AND_FINGERPRINTS[0][2], suffix),
                  "r") as fh:
            contents = fh.read()
            sgpg.import_key(gpg, contents)
    # create gpg.conf's
    sgpg.create_gpg_conf(context.config['gpg_home'],
                         my_fingerprint=my_fingerprint)
    sgpg.create_gpg_conf(gpg_home2, my_fingerprint=my_fingerprint)
    sgpg.check_ownertrust(context)
    sgpg.check_ownertrust(context, gpg_home=gpg_home2)
    # generate a new key
    fingerprint = sgpg.generate_key(gpg,
                                    "one",
                                    "one",
                                    "one",
                                    key_length=GENERATE_KEY_SMALLER_KEY_SIZE)
    # sign it, exportable signature is `exportable`
    sgpg.sign_key(context,
                  fingerprint,
                  signing_key=my_fingerprint,
                  exportable=exportable)
    # export my privkey and import it in gpg_home2
    priv_key = sgpg.export_key(gpg, my_fingerprint, private=True)
    sgpg.import_key(gpg2, priv_key)
    # export both pubkeys and import in gpg_home2
    for fp in (my_fingerprint, fingerprint):
        pub_key = sgpg.export_key(gpg, fp)
        sgpg.import_key(gpg2, pub_key)
    # check sigs on `fingerprint` key.  If exportable, we're good.  If not exportable,
    # it'll throw
    expected = {'sig_keyids': [my_keyid]}
    if exportable:
        sgpg.get_list_sigs_output(context,
                                  fingerprint,
                                  gpg_home=gpg_home2,
                                  expected=expected)
    else:
        with pytest.raises(ScriptWorkerGPGException):
            sgpg.get_list_sigs_output(context,
                                      fingerprint,
                                      gpg_home=gpg_home2,
                                      expected=expected)
def test_sign_key(context):
    """This test calls get_list_sigs_output in several different ways.  Each
    is valid; the main thing is more code coverage.

tru:o:1:1472876459:1:3:1:5
pub:u:4096:1:EA608995918B2DF9:1472876455:::u:::escaESCA:
fpr:::::::::A9F598A3179551CC664C15DEEA608995918B2DF9:
uid:u::::1472876455::6477C0BAC30FB3E244C8F1907D78C6B243AFD516::two (two) <two>:
sig:::1:EA608995918B2DF9:1472876455::::two (two) <two>:13x:::::8:
sig:::1:9633F5F38B9BD3C5:1472876459::::one (one) <one>:10l:::::8:


tru::1:1472876460:0:3:1:5
pub:u:4096:1:BC76BF8F77D1B3F5:1472876457:::u:::escaESCA:
fpr:::::::::7CFAD9E699D8559F1D3A50CCBC76BF8F77D1B3F5:
uid:u::::1472876457::91AC286E48FDA7378B86F63FA6DDC2A46B54808F::three (three) <three>:
sig:::1:BC76BF8F77D1B3F5:1472876457::::three (three) <three>:13x:::::8:
    """
    gpg = sgpg.GPG(context)
    # create my key, get fingerprint + keyid
    my_fingerprint = sgpg.generate_key(
        gpg, "one", "one", "one", key_length=GENERATE_KEY_SMALLER_KEY_SIZE)
    my_keyid = sgpg.fingerprint_to_keyid(gpg, my_fingerprint)
    # create signed key, get fingerprint + keyid
    signed_fingerprint = sgpg.generate_key(
        gpg, "two", "two", "two", key_length=GENERATE_KEY_SMALLER_KEY_SIZE)
    signed_keyid = sgpg.fingerprint_to_keyid(gpg, signed_fingerprint)
    # create unsigned key, get fingerprint + keyid
    unsigned_fingerprint = sgpg.generate_key(
        gpg,
        "three",
        "three",
        "three",
        key_length=GENERATE_KEY_SMALLER_KEY_SIZE)
    unsigned_keyid = sgpg.fingerprint_to_keyid(gpg, unsigned_fingerprint)
    # update gpg configs, sign signed key
    sgpg.create_gpg_conf(context.config['gpg_home'],
                         my_fingerprint=my_fingerprint)
    sgpg.check_ownertrust(context)
    sgpg.sign_key(context, signed_fingerprint)
    # signed key get_list_sigs_output
    signed_output = sgpg.get_list_sigs_output(context, signed_fingerprint)
    # unsigned key get_list_sigs_output
    # Call get_list_sigs_output with validate=False, then parse it, for more code coverage
    unsigned_output1 = sgpg.get_list_sigs_output(context,
                                                 unsigned_fingerprint,
                                                 validate=False)
    unsigned_output = sgpg.parse_list_sigs_output(unsigned_output1, "unsigned")
    # signed key has my signature + self-signed
    assert sorted([signed_keyid,
                   my_keyid]) == sorted(signed_output['sig_keyids'])
    assert ["one (one) <one>",
            "two (two) <two>"] == sorted(signed_output['sig_uids'])
    # unsigned key is only self-signed
    assert [unsigned_keyid] == unsigned_output['sig_keyids']
    assert ["three (three) <three>"] == unsigned_output['sig_uids']
    # sign the unsigned key and test
    sgpg.sign_key(context,
                  unsigned_fingerprint,
                  signing_key=signed_fingerprint)
    # Call get_list_sigs_output with expected, for more code coverage
    new_output = sgpg.get_list_sigs_output(
        context,
        unsigned_fingerprint,
        expected={
            "keyid": unsigned_keyid,
            "fingerprint": unsigned_fingerprint,
            "uid": "three (three) <three>",
            "sig_keyids": [signed_keyid, unsigned_keyid],
            "sig_uids": ["three (three) <three>", "two (two) <two>"]
        })
    # sig_uids goes unchecked; sig_keyids only checks that it's a subset.
    # let's do another check.
    assert ["three (three) <three>",
            "two (two) <two>"] == sorted(new_output['sig_uids'])