def test_root_gen_sign_verify():
    # Integration test

    # Build a basic root metadata file with empty key_mgr delegation and one
    # root key, threshold 1, version 1.
    rmd = metadata_construction.build_root_metadata(
        root_version=1,
        root_pubkeys=[SAMPLE_KEYVAL],
        root_threshold=1,
        key_mgr_pubkeys=[],
        key_mgr_threshold=1)
    rmd = signing.wrap_as_signable(rmd)

    signed_portion = rmd['signed']

    canonical_signed_portion = common.canonserialize(signed_portion)

    if not SSLIB_AVAILABLE:
        pytest.skip('--TEST SKIPPED⚠️ : Unable to perform GPG signing without '
                    'securesystemslib and GPG.')
        return

    # gpg_key_obj = securesystemslib.gpg.functions.export_pubkey(
    #         SAMPLE_FINGERPRINT)

    gpg_sig = root_signing.sign_via_gpg(canonical_signed_portion,
                                        SAMPLE_FINGERPRINT)

    signed_rmd = copy.deepcopy(rmd)

    signed_rmd['signatures'][SAMPLE_KEYVAL] = gpg_sig

    # # Dump working files
    # with open('T_gpg_sig.json', 'wb') as fobj:
    #     fobj.write(common.canonserialize(gpg_sig))

    # with open('T_gpg_key_obj.json', 'wb') as fobj:
    #     fobj.write(common.canonserialize(gpg_key_obj))

    # with open('T_canonical_sigless_md.json', 'wb') as fobj:
    #     fobj.write(canonical_signed_portion)

    # with open('T_full_rmd.json', 'wb') as fobj:
    #     fobj.write(common.canonserialize(signed_rmd))

    # Verify using the SSL code and the expected pubkey object.
    # # (Purely as a test -- we wouldn't normally do this.)
    # verified = securesystemslib.gpg.functions.verify_signature(
    #     gpg_sig, gpg_key_obj, canonical_signed_portion)

    # assert verified

    authentication.verify_gpg_signature(gpg_sig, SAMPLE_KEYVAL,
                                        canonical_signed_portion)

    print('--TEST SUCCESS✅: GPG signing (using GPG and securesystemslib) and '
          'GPG signature verification (using only cryptography)')
示例#2
0
    def create_root(self, keys):
        root_keys = keys["root"]

        root_pubkeys = [k["public"] for k in root_keys]
        key_mgr_pubkeys = [k["public"] for k in keys["key_mgr"]]

        root_version = 1

        root_md = cct_metadata_construction.build_root_metadata(
            root_pubkeys=root_pubkeys[0:1],
            root_threshold=1,
            root_version=root_version,
            key_mgr_pubkeys=key_mgr_pubkeys,
            key_mgr_threshold=1,
        )

        # Wrap the metadata in a signing envelope.
        root_md = cct_signing.wrap_as_signable(root_md)

        root_md_serialized_unsigned = cct_common.canonserialize(root_md)

        root_filepath = self.folder / f"{root_version}.root.json"
        print("Writing out: ", root_filepath)
        # Write unsigned sample root metadata.
        with open(root_filepath, "wb") as fout:
            fout.write(root_md_serialized_unsigned)

        # This overwrites the file with a signed version of the file.
        cct_root_signing.sign_root_metadata_via_gpg(
            root_filepath, root_keys[0]["fingerprint"])

        # Load untrusted signed root metadata.
        signed_root_md = cct_common.load_metadata_from_file(root_filepath)

        cct_authentication.verify_signable(signed_root_md,
                                           root_pubkeys,
                                           1,
                                           gpg=True)

        console.print("[green]Root metadata signed & verified!")
示例#3
0
def demo_root_signing_and_verifying_and_chaining():
    # Build sample root metadata.  ('metadata' -> 'md')
    root_md = cct_metadata_construction.build_root_metadata(
        root_pubkeys=[ROOT_PUBKEY_HEX],
        root_threshold=1,
        root_version=1,
        key_mgr_pubkeys=[KEYMGR_PUBLIC_HEX],
        key_mgr_threshold=1)

    # Wrap the metadata in a signing envelope.
    root_md = cct_signing.wrap_as_signable(root_md)

    root_md_serialized_unsigned = cct_common.canonserialize(root_md)

    print('\n-- Unsigned root metadata version 1 generated.\n')

    # # This is the part of the data over which signatures are constructed.
    # root_md_serialized_portion_to_sign = cct_common.canonserialize(
    #         root_md['signed'])

    # TODO: ✅ Format-validate constructed root metadata using checkformat
    #          function.

    if not os.path.exists('demo'):
        os.mkdir('demo')

    # Write unsigned sample root metadata.
    with open(ROOT_FNAME_V1, 'wb') as fobj:
        fobj.write(root_md_serialized_unsigned)
    print('\n-- Unsigned root metadata version 1 written.\n')

    # Sign sample root metadata.
    junk = input_func(
        'Preparing to request root signature.  Please plug in your '
        'YubiKey and prepare to put in your user PIN in a GPG dialog box. '
        ' When the YubiKey is plugged in and you are READY TO ENTER your '
        'pin, hit enter to begin.')

    # This overwrites the file with a signed version of the file.
    cct_root_signing.sign_root_metadata_via_gpg(ROOT_FNAME_V1,
                                                ROOT_PUBKEY_GPG_FINGERPRINT)
    cct_root_signing.sign_root_metadata_via_gpg(ROOT_FNAME_V1,
                                                ROOT_PUBKEY_GPG_FINGERPRINT)
    junk = input_func(
        '\n-- Root metadata v1 signed.  Next: load signed root v1.\n')

    # Load untrusted signed root metadata.
    signed_root_md = cct_common.load_metadata_from_file(ROOT_FNAME_V1)
    junk = input_func(
        '\n-- Signed root metadata v1 loaded.  Next: verify signed root v1\n')

    # Verify untrusted signed root metadata.  (Normally, one uses the prior
    # version of root, but here we're bootstrapping for the demo.  We'll verify
    # with a prior version lower down in this demo.)
    cct_authentication.verify_signable(signed_root_md, [ROOT_PUBKEY_HEX],
                                       1,
                                       gpg=True)
    junk = input_func(
        '\n-- Root metadata v1 fully verified.  Next: build root metadata v2.\n'
    )

    # Build sample second version of root metadata.  In this case, let's try
    # adding another authorized key and requiring signatures from both keys.
    root_md2 = cct_metadata_construction.build_root_metadata(
        root_pubkeys=[ROOT_PUBKEY_HEX, ROOT_PUBKEY_2_HEX],
        root_threshold=2,
        root_version=2,
        key_mgr_pubkeys=[KEYMGR_PUBLIC_HEX],
        key_mgr_threshold=1)

    # Wrap the version 2 metadata in a signing envelope, canonicalize it, and
    # serialize it to write to disk.
    root_md2 = cct_signing.wrap_as_signable(root_md2)
    root_md2 = cct_common.canonserialize(root_md2)

    # Write unsigned sample root metadata.
    with open(ROOT_FNAME_V2, 'wb') as fobj:
        fobj.write(root_md2)
    junk = input_func(
        '\n-- Unsigned root metadata version 2 generated and written.  Next: sign root v2\n'
    )

    # This overwrites the file with a signed version of the file.
    # We'll sign with both keys specified.
    cct_root_signing.sign_root_metadata_via_gpg(ROOT_FNAME_V2,
                                                ROOT_PUBKEY_GPG_FINGERPRINT)
    cct_root_signing.sign_root_metadata_via_gpg(ROOT_FNAME_V2,
                                                ROOT_PUBKEY_2_GPG_FINGERPRINT)
    junk = input_func(
        '\n-- Root metadata v2 signed.  Next: load and verify signed root v2 based on root v1 (root chaining).\n'
    )

    # Load the now-signed version from disk.
    signed_root_md2 = cct_common.load_metadata_from_file(ROOT_FNAME_V2)

    # Test root chaining (verifying v2 using v1)
    cct_authentication.verify_root(signed_root_md, signed_root_md2)
    print('\n-- Root metadata v2 fully verified based directly on Root '
          'metadata v1 (root chaining success)\n')

    print('\n-- Success. :)\n')

    # Build sample third version of root metadata.  In this case, let's reduce
    # the number of required keys to one.
    root_md3 = cct_metadata_construction.build_root_metadata(
        root_pubkeys=[ROOT_PUBKEY_HEX, ROOT_PUBKEY_2_HEX],
        root_threshold=1,
        root_version=3,
        key_mgr_pubkeys=[KEYMGR_PUBLIC_HEX],
        key_mgr_threshold=1)

    # Wrap the version 2 metadata in a signing envelope, canonicalize it, and
    # serialize it to write to disk.
    root_md3 = cct_signing.wrap_as_signable(root_md3)
    root_md3 = cct_common.canonserialize(root_md3)

    # Write unsigned sample root metadata.
    with open(ROOT_FNAME_V3, 'wb') as fobj:
        fobj.write(root_md3)
    junk = input_func(
        '\n-- Unsigned root metadata version 2 generated and written.  Next: sign root v2\n'
    )

    # This overwrites the file with a signed version of the file.
    # We'll sign with both keys specified.
    cct_root_signing.sign_root_metadata_via_gpg(ROOT_FNAME_V3,
                                                ROOT_PUBKEY_GPG_FINGERPRINT)
    cct_root_signing.sign_root_metadata_via_gpg(ROOT_FNAME_V3,
                                                ROOT_PUBKEY_2_GPG_FINGERPRINT)
    junk = input_func(
        '\n-- Root metadata v2 signed.  Next: load and verify signed root v2 based on root v1 (root chaining).\n'
    )

    # Load the now-signed version from disk.
    signed_root_md3 = cct_common.load_metadata_from_file(ROOT_FNAME_V3)

    # Test root chaining (verifying v2 using v1)
    cct_authentication.verify_root(signed_root_md2, signed_root_md3)
    print('\n-- Root metadata v3 fully verified based directly on Root '
          'metadata v2 (root chaining success)\n')

    print('\n-- Success. :)\n')

    return signed_root_md, signed_root_md2, signed_root_md3