strange gpgme owner trust bug [long, sorry]
Albrecht Dreß
albrecht.dress@arcor.de
Thu Jul 10 19:41:03 2003
--Yylu36WmvOXNoKYn
Content-Type: multipart/mixed; boundary="Dxnq1zWXvFF0Q93v"
Content-Disposition: inline
--Dxnq1zWXvFF0Q93v
Content-Type: text/plain; format=flowed; charset=ISO-8859-15
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
Hi all,
I have a strange problem retreiving the owner trust field from a key using=
=20
gpgme 0.3.15.
Usually, after checking a signed file using gpgme_op_verify(), the field=20
is returned correctly for the signer's key. When I sign something in the=20
same application using gpgme_op_sign(), and then check any signed file=20
again, the owner trust returned is *always* 0.
To illustrate this, I attach a minimal test case which I compiled using
gcc -Wall gpgme_test.c -o gpgme_test `gpgme-config --libs`
Now create a small text file (e.g. "TEST") and sign it with your private=20
key (which you should trust ultimately) using
gpg --clearsign -a TEST
The test program is run using the signed file, some other file, plus your=
=20
secret key id. It checks the file from arg #1 and dumps a few information=
=20
about the key, signs file arg #2 with key arg #3 (you must enter the pass=
=20
phrase), and then repeats the signature check of file #1:
linux > ./gpgme_test TEST.asc gpgme_test.c '<your-email@provider.xy>'
get_sig_info_from_ctx: key results
name =3D removed
email =3D removed
validity =3D 5
owner trust =3D 5
sign_file
ENTER
xxxxxxxxxxxxxxxx removed
xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xx x
<correct passphrase entered>
get_sig_info_from_ctx: key results
name =3D removed
email =3D removed
validity =3D 5
owner trust =3D 0
The owner trust changed, which is obviously wrong... I see this effect on=
=20
a Intel/SuSE 7.2 box running gpg 1.2.2 and on a Yellowdog (PowerPC) Linux=
=20
running gpg 1.2.3.
Is this a bug? Feature? Bad test program? Any other ideas?
Cheers, Albrecht.
--=20
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Albrecht Dre=DF - Johanna-Kirchner-Stra=DFe 13 - D-53123 Bonn (German=
y)
Phone (+49) 228 6199571 - mailto:albrecht.dress@arcor.de
_________________________________________________________________________
--Dxnq1zWXvFF0Q93v
Content-Type: text/x-c; charset=us-ascii
Content-Disposition: attachment; filename="gpgme_test.c"
#include <gpgme.h>
#include <stdio.h>
static void check_file_sig(const char * filename);
static void get_sig_info_from_ctx(GpgmeCtx ctx);
void sign_file(const char *filename, const char * signer);
const char * get_pass(void * hook, const char * desc, void ** r_hd);
int
main(int argc, char **argv)
{
if (argc < 4) {
fprintf(stderr, "usage: %s <signed file> <file to sign> <signer>\n", argv[0]);
return 1;
}
gpgme_check_version(NULL);
check_file_sig(argv[1]);
sign_file(argv[2], argv[3]);
check_file_sig(argv[1]);
return 0;
}
static void
check_file_sig(const char * filename)
{
GpgmeError err;
GpgmeCtx ctx;
GpgmeData sig, out;
GpgmeSigStat status;
gpgme_new(&ctx);
if ((err = gpgme_data_new_from_file(&sig, filename, 1)) != GPGME_No_Error) {
fprintf(stderr, "gpgme could not get data from file: %s\n", gpgme_strerror(err));
exit(1);
}
gpgme_data_new(&out);
if ((err = gpgme_op_verify(ctx, sig, out, &status)) != GPGME_No_Error) {
fprintf(stderr, "gpgme signature verification failed: %s\n", gpgme_strerror(err));
exit(1);
} else
get_sig_info_from_ctx(ctx);
gpgme_data_release(sig);
gpgme_data_release(out);
gpgme_release(ctx);
}
static void
get_sig_info_from_ctx(GpgmeCtx ctx)
{
GpgmeKey key;
gpgme_get_sig_key(ctx, 0, &key);
printf("%s: key results\n\tname = %s\n\temail = %s\n\tvalidity = %lu\n"
"\towner trust = %lu\n",
__FUNCTION__,
gpgme_key_get_string_attr(key, GPGME_ATTR_NAME, NULL, 0),
gpgme_key_get_string_attr(key, GPGME_ATTR_EMAIL, NULL, 0),
gpgme_key_get_ulong_attr(key, GPGME_ATTR_VALIDITY, NULL, 0),
gpgme_key_get_ulong_attr(key, GPGME_ATTR_OTRUST, NULL, 0));
gpgme_key_unref(key);
}
const char *
get_pass(void * hook, const char * desc, void ** r_hd)
{
static char pb_buf[256];
int len;
if (!desc)
return NULL;
printf("%s\n", desc);
fgets(pb_buf, 255, stdin);
len = strlen(pb_buf);
while (len && pb_buf[len - 1] < ' ') {
len--;
pb_buf[len] = '\0';
}
return pb_buf;
}
void
sign_file(const char *filename, const char * signer)
{
GpgmeCtx ctx;
GpgmeError err;
GpgmeKey key;
GpgmeData in, out;
printf("%s\n", __FUNCTION__);
gpgme_new(&ctx);
gpgme_op_keylist_start(ctx, signer, 1);
if (gpgme_op_keylist_next(ctx, &key) == GPGME_EOF) {
fprintf(stderr, "could not find secret key for %s\n", signer);
exit(1);
}
gpgme_signers_add(ctx, key);
gpgme_key_unref(key);
gpgme_op_keylist_end(ctx);
gpgme_set_armor(ctx, 1);
gpgme_set_passphrase_cb(ctx, get_pass, NULL);
if ((err = gpgme_data_new_from_file(&in, filename, 1)) != GPGME_No_Error) {
fprintf(stderr, "gpgme could not get data from file: %s\n", gpgme_strerror(err));
exit(1);
}
gpgme_data_new(&out);
if ((err = gpgme_op_sign(ctx, in, out, GPGME_SIG_MODE_CLEAR)) != GPGME_No_Error) {
fprintf(stderr, "signing failed: %s\n", gpgme_strerror(err));
exit(1);
}
gpgme_data_release(in);
gpgme_data_release(out);
gpgme_release(ctx);
}
--Dxnq1zWXvFF0Q93v--
--Yylu36WmvOXNoKYn
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
iD8DBQA/DaWSn/9unNAn/9ERAoFNAKCkQVQ1tWklvA/3dXLUSPWjPVrH2wCgvBmx
HAl52CfREudOMRlkzPkVi4g=
=cO4q
-----END PGP SIGNATURE-----
--Yylu36WmvOXNoKYn--