builtin/sign: allow to use multiple public keys for verification

`ostree sign` is able to use several public keys provided via arguments
and via file with keys.

Signed-off-by: Denis Pynkin <denis.pynkin@collabora.com>
This commit is contained in:
Denis Pynkin 2019-09-05 16:33:52 +03:00
parent 557f423609
commit ea291a0605
2 changed files with 53 additions and 27 deletions

View File

@ -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;
@ -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;
}
for (ii = 0; ii < n_key_ids; ii++)
{
@ -129,6 +129,9 @@ 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;
@ -136,17 +139,14 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation,
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
@ -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 ((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}"));
/* 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;
}
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 */
{
/* 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;
@ -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"))
@ -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,
@ -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;
}

View File

@ -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"
@ -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
@ -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}