Skip to content

Commit

Permalink
builtin/sign: allow to use multiple public keys for verification
Browse files Browse the repository at this point in the history
`ostree sign` is able to use several public keys provided via arguments
and via file with keys.

Signed-off-by: Denis Pynkin <[email protected]>
  • Loading branch information
d4s committed Sep 5, 2019
1 parent ab09099 commit 76404a0
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 27 deletions.
62 changes: 35 additions & 27 deletions src/ostree/ot-builtin-sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ usage_error (GOptionContext *context, const char *message, GError **error)
gboolean
ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
g_autoptr(OstreeRepo) repo = NULL;
g_autoptr (GOptionContext) context = NULL;
g_autoptr (OstreeRepo) repo = NULL;
g_autoptr (OstreeSign) sign = NULL;
g_autofree char *resolved_commit = NULL;
const char *commit;
Expand All @@ -92,7 +92,10 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation,

commit = argv[1];

if (!opt_filename && argc < 3)
/* Verification could be done via system files with public keys */
if (!opt_verify &&
!opt_filename &&
argc < 3)
{
usage_error (context, "Need at least one KEY-ID to sign with", error);
goto out;
Expand All @@ -110,10 +113,7 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation,

sign = ostree_sign_get_by_name (opt_sign_name, error);
if (sign == NULL)
{
ret = FALSE;
goto out;
}
goto out;

for (ii = 0; ii < n_key_ids; ii++)
{
Expand All @@ -129,24 +129,24 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation,
}
if (opt_verify)
{
g_autoptr (GError) local_error = NULL;


if (!g_strcmp0(ostree_sign_get_name(sign), "ed25519"))
{
gsize key_len = 0;
g_autofree guchar *key = g_base64_decode (key_ids[ii], &key_len);
pk = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, key, key_len, sizeof(guchar));
}

if (!ostree_sign_set_pk (sign, pk, error))
{
ret = FALSE;
goto out;
}
if (!ostree_sign_set_pk (sign, pk, &local_error))
continue;

if (ostree_sign_commit_verify (sign,
repo,
resolved_commit,
cancellable,
error))
&local_error))
ret = TRUE;
}
else
Expand Down Expand Up @@ -174,34 +174,36 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation,
}
}

/* Read signatures from file */
if (opt_filename)
/* Try to verify with user-provided file or system configuration */
if (opt_verify)
{
if (opt_verify)
if ((n_key_ids == 0) || opt_filename)
{
g_autoptr (GVariantBuilder) builder = NULL;
g_autoptr (GVariant) options = NULL;

builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (builder, "{sv}", "filename", g_variant_new_string (opt_filename));
/* The last chance for verification source -- system files */
if (opt_filename)
g_variant_builder_add (builder, "{sv}", "filename", g_variant_new_string (opt_filename));
options = g_variant_builder_end (builder);

if (!ostree_sign_load_pk (sign, options, error))
{
ret = FALSE;
goto out;
}
goto out;

if (ostree_sign_commit_verify (sign,
repo,
resolved_commit,
cancellable,
error))
ret = TRUE;
if (ret != TRUE)
goto out;
} /* Check via file */
else
{ /* Sign with keys from provided file */
}
else
{
/* Sign with keys from provided file */
if (opt_filename)
{
g_autoptr (GFile) keyfile = NULL;
g_autoptr (GFileInputStream) key_stream_in = NULL;
g_autoptr (GDataInputStream) key_data_in = NULL;
Expand Down Expand Up @@ -233,7 +235,7 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation,
goto out;

if (line == NULL)
goto out;
break;


if (!g_strcmp0(ostree_sign_get_name(sign), "dummy"))
Expand All @@ -251,7 +253,10 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation,
}

if (!ostree_sign_set_sk (sign, sk, error))
continue;
{
ret = FALSE;
goto out;
}

ret = ostree_sign_commit (sign,
repo,
Expand All @@ -271,5 +276,8 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation,
"No valid signatures found");

out:
/* It is possible to have an error due multiple signatures check */
if (ret == TRUE)
g_clear_error (error);
return ret;
}
18 changes: 18 additions & 0 deletions tests/test-signed-commit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ SEED="$(openssl pkey -outform DER -in ${PEMFILE} | tail -c 32 | base64)"
# Secret key is concantination of SEED and PUBLIC
SECRET="$(echo ${SEED}${PUBLIC} | base64 -d | base64 -w 0)"

WRONG_PUBLIC="$(openssl genpkey -algorithm ED25519 | openssl pkey -outform DER | tail -c 32 | base64)"

echo "SEED = $SEED"
echo "PUBLIC = $PUBLIC"

Expand All @@ -85,7 +87,15 @@ ${CMD_PREFIX} ostree --repo=repo show ${COMMIT} --print-detached-metadata-key=os
echo "ok Detached ed25519 signature added"

# Verify vith sign mechanism
if ${CMD_PREFIX} ostree --repo=${test_tmpdir}/repo sign --verify --sign-type=ed25519 ${COMMIT} ${WRONG_PUBLIC}; then
exit 1
fi
${CMD_PREFIX} ostree --repo=${test_tmpdir}/repo sign --verify --sign-type=ed25519 ${COMMIT} ${PUBLIC}
${CMD_PREFIX} ostree --repo=${test_tmpdir}/repo sign --verify --sign-type=ed25519 ${COMMIT} ${PUBLIC} ${PUBLIC}
${CMD_PREFIX} ostree --repo=${test_tmpdir}/repo sign --verify --sign-type=ed25519 ${COMMIT} ${WRONG_PUBLIC} ${PUBLIC}
${CMD_PREFIX} ostree --repo=${test_tmpdir}/repo sign --verify --sign-type=ed25519 ${COMMIT} ${WRONG_PUBLIC} ${WRONG_PUBLIC} ${PUBLIC}
${CMD_PREFIX} ostree --repo=${test_tmpdir}/repo sign --verify --sign-type=ed25519 ${COMMIT} ${PUBLIC} ${WRONG_PUBLIC} ${WRONG_PUBLIC}
${CMD_PREFIX} ostree --repo=${test_tmpdir}/repo sign --verify --sign-type=ed25519 ${COMMIT} ${WRONG_PUBLIC} ${WRONG_PUBLIC} ${PUBLIC} ${WRONG_PUBLIC} ${WRONG_PUBLIC}
echo "ok ed25519 signature verified"

# Check if we able to use all available modules to sign the same commit
Expand Down Expand Up @@ -128,9 +138,17 @@ for((i=0;i<100;i++)); do
# Generate a list with some public signatures
openssl genpkey -algorithm ED25519 | openssl pkey -outform DER | tail -c 32 | base64
done > ${PUBKEYS}
# Check if file contain no valid signatures
if ${CMD_PREFIX} ostree --repo=${test_tmpdir}/repo sign --verify --sign-type=ed25519 --keys-file=${PUBKEYS} ${COMMIT}; then
exit 1
fi
# Check if no valid signatures provided via args&file
if ${CMD_PREFIX} ostree --repo=${test_tmpdir}/repo sign --verify --sign-type=ed25519 --keys-file=${PUBKEYS} ${COMMIT} ${WRONG_PUBLIC}; then
exit 1
fi

#Test keys file and public key
${CMD_PREFIX} ostree --repo=${test_tmpdir}/repo sign --verify --sign-type=ed25519 --keys-file=${PUBKEYS} ${COMMIT} ${PUBLIC}

# Add correct key into the list
echo ${PUBLIC} >> ${PUBKEYS}
Expand Down

0 comments on commit 76404a0

Please sign in to comment.