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:
parent
557f423609
commit
ea291a0605
|
|
@ -64,8 +64,8 @@ usage_error (GOptionContext *context, const char *message, GError **error)
|
||||||
gboolean
|
gboolean
|
||||||
ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
|
ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
|
||||||
{
|
{
|
||||||
g_autoptr(GOptionContext) context = NULL;
|
g_autoptr (GOptionContext) context = NULL;
|
||||||
g_autoptr(OstreeRepo) repo = NULL;
|
g_autoptr (OstreeRepo) repo = NULL;
|
||||||
g_autoptr (OstreeSign) sign = NULL;
|
g_autoptr (OstreeSign) sign = NULL;
|
||||||
g_autofree char *resolved_commit = NULL;
|
g_autofree char *resolved_commit = NULL;
|
||||||
const char *commit;
|
const char *commit;
|
||||||
|
|
@ -92,7 +92,10 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation,
|
||||||
|
|
||||||
commit = argv[1];
|
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);
|
usage_error (context, "Need at least one KEY-ID to sign with", error);
|
||||||
goto out;
|
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);
|
sign = ostree_sign_get_by_name (opt_sign_name, error);
|
||||||
if (sign == NULL)
|
if (sign == NULL)
|
||||||
{
|
goto out;
|
||||||
ret = FALSE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ii = 0; ii < n_key_ids; ii++)
|
for (ii = 0; ii < n_key_ids; ii++)
|
||||||
{
|
{
|
||||||
|
|
@ -129,6 +129,9 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation,
|
||||||
}
|
}
|
||||||
if (opt_verify)
|
if (opt_verify)
|
||||||
{
|
{
|
||||||
|
g_autoptr (GError) local_error = NULL;
|
||||||
|
|
||||||
|
|
||||||
if (!g_strcmp0(ostree_sign_get_name(sign), "ed25519"))
|
if (!g_strcmp0(ostree_sign_get_name(sign), "ed25519"))
|
||||||
{
|
{
|
||||||
gsize key_len = 0;
|
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));
|
pk = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, key, key_len, sizeof(guchar));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ostree_sign_set_pk (sign, pk, error))
|
if (!ostree_sign_set_pk (sign, pk, &local_error))
|
||||||
{
|
continue;
|
||||||
ret = FALSE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ostree_sign_commit_verify (sign,
|
if (ostree_sign_commit_verify (sign,
|
||||||
repo,
|
repo,
|
||||||
resolved_commit,
|
resolved_commit,
|
||||||
cancellable,
|
cancellable,
|
||||||
error))
|
&local_error))
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -174,34 +174,36 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read signatures from file */
|
/* Try to verify with user-provided file or system configuration */
|
||||||
if (opt_filename)
|
if (opt_verify)
|
||||||
{
|
{
|
||||||
if (opt_verify)
|
if ((n_key_ids == 0) || opt_filename)
|
||||||
{
|
{
|
||||||
g_autoptr (GVariantBuilder) builder = NULL;
|
g_autoptr (GVariantBuilder) builder = NULL;
|
||||||
g_autoptr (GVariant) options = NULL;
|
g_autoptr (GVariant) options = NULL;
|
||||||
|
|
||||||
builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
|
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);
|
options = g_variant_builder_end (builder);
|
||||||
|
|
||||||
if (!ostree_sign_load_pk (sign, options, error))
|
if (!ostree_sign_load_pk (sign, options, error))
|
||||||
{
|
goto out;
|
||||||
ret = FALSE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (ostree_sign_commit_verify (sign,
|
if (ostree_sign_commit_verify (sign,
|
||||||
repo,
|
repo,
|
||||||
resolved_commit,
|
resolved_commit,
|
||||||
cancellable,
|
cancellable,
|
||||||
error))
|
error))
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
if (ret != TRUE)
|
|
||||||
goto out;
|
|
||||||
} /* Check via file */
|
} /* 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 (GFile) keyfile = NULL;
|
||||||
g_autoptr (GFileInputStream) key_stream_in = NULL;
|
g_autoptr (GFileInputStream) key_stream_in = NULL;
|
||||||
g_autoptr (GDataInputStream) key_data_in = NULL;
|
g_autoptr (GDataInputStream) key_data_in = NULL;
|
||||||
|
|
@ -233,7 +235,7 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (line == NULL)
|
if (line == NULL)
|
||||||
goto out;
|
break;
|
||||||
|
|
||||||
|
|
||||||
if (!g_strcmp0(ostree_sign_get_name(sign), "dummy"))
|
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))
|
if (!ostree_sign_set_sk (sign, sk, error))
|
||||||
continue;
|
{
|
||||||
|
ret = FALSE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
ret = ostree_sign_commit (sign,
|
ret = ostree_sign_commit (sign,
|
||||||
repo,
|
repo,
|
||||||
|
|
@ -271,5 +276,8 @@ ostree_builtin_sign (int argc, char **argv, OstreeCommandInvocation *invocation,
|
||||||
"No valid signatures found");
|
"No valid signatures found");
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
/* It is possible to have an error due multiple signatures check */
|
||||||
|
if (ret == TRUE)
|
||||||
|
g_clear_error (error);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,8 @@ SEED="$(openssl pkey -outform DER -in ${PEMFILE} | tail -c 32 | base64)"
|
||||||
# Secret key is concantination of SEED and PUBLIC
|
# Secret key is concantination of SEED and PUBLIC
|
||||||
SECRET="$(echo ${SEED}${PUBLIC} | base64 -d | base64 -w 0)"
|
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 "SEED = $SEED"
|
||||||
echo "PUBLIC = $PUBLIC"
|
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"
|
echo "ok Detached ed25519 signature added"
|
||||||
|
|
||||||
# Verify vith sign mechanism
|
# 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}
|
||||||
|
${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"
|
echo "ok ed25519 signature verified"
|
||||||
|
|
||||||
# Check if we able to use all available modules to sign the same commit
|
# 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
|
# Generate a list with some public signatures
|
||||||
openssl genpkey -algorithm ED25519 | openssl pkey -outform DER | tail -c 32 | base64
|
openssl genpkey -algorithm ED25519 | openssl pkey -outform DER | tail -c 32 | base64
|
||||||
done > ${PUBKEYS}
|
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
|
if ${CMD_PREFIX} ostree --repo=${test_tmpdir}/repo sign --verify --sign-type=ed25519 --keys-file=${PUBKEYS} ${COMMIT}; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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
|
# Add correct key into the list
|
||||||
echo ${PUBLIC} >> ${PUBKEYS}
|
echo ${PUBLIC} >> ${PUBKEYS}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue