gpgme_op_verify behaves weird

Marcus Brinkmann marcus.brinkmann at ruhr-uni-bochum.de
Tue Sep 5 14:06:13 CEST 2006


At Tue, 5 Sep 2006 11:42:57 +0200,
Francois Gaudin <alf at bordel-ambiant.org> wrote:
> so, my problem is that I can sign text, but the verification failed with a 
> segfault and I can't find why.

Should be easy, let's walk through the various issues.

First of all, return values are not error codes, they are error codes
plus encoded error source information.  So the right way to access the
error code is

  gpgme_err_code (result)

for comparison, assertions etc.

> 	gpgme_data_rewind(signature) ;
> // should be the following, but for a fucking mysterious reason, it doesn't 
> want to work
> // 	gpgme_data_seek(signature,0,SEEK_SET) ;

See the FAQ at http://www.gnupg.org/(en)/faq/gpgme-faq.html:

  Why does the function gpgme_data_seek not work?

  You probably did not compile the program with largefile
  support. GPGME is compiled with largefile support by default, so
  off_t is a 64-bit data type. Because gpgme_data_seek uses off_t as a
  parameter type, you have to compile your program with largefile
  support as well, so that the data types used by GPGME and by your
  program match.

  Note that you have to compile your program with largefile support
  even if you do not use gpgme_data_seek, because file descriptors are
  exchanged between the program and GPGME.

  The GPGME documentation contains much more information on the
  subject. See section 2.3 Largefile support of the GPGME Reference
  Manual.

> 	gpgme_data_read(signature,buffer,1024) ;
> 
> 	signatureStr += buffer ;
> 
> 	qDebug() << "signature" << signatureStr ;

Here you have to rewind a second time if you want to verify the signature.

> 	// test part
> 	result = gpgme_op_verify (context, signature, msg , NULL) ;
> 	qDebug() << "verify result" << result ;
> 	Q_ASSERT(result != GPG_ERR_INV_VALUE) ;
> 	Q_ASSERT(result != GPG_ERR_NO_DATA) ;
> // 	Q_ASSERT(result == GPG_ERR_NO_ERROR) ;
> 	qDebug() << "verify" ;

Always catch all errors.  From the output below:

> verify result 117440570

And this means:
$ gpg-error 117440570
117440570 = (7, 58) = (GPG_ERR_SOURCE_GPGME, GPG_ERR_NO_DATA) = (GPGME, No data)
So, no data was found.
 	
> 	gpgme_verify_result_t verification = gpgme_op_verify_result(context) ;
> 	Q_ASSERT(verification != NULL) ;
> 	qDebug() << "result" ;

The result structure is not always well-formed after a failed
operation.  GPGME tries to make as much information available as
possible, of course.  In particular, if no data was found, no
signatures were found either, so:
 	
> 	gpgme_signature_t signatures = verification->signatures ;

This is likely NULL.

> 	qDebug() << signatures->summary ;

And this will then segfault.

> so it seems to well sign but the value returned by gpgme_op_verify is 
> weird ...

The higher bits encode the error source (GPGME in this case), and the
lower bits the error value.  We use this to be able to report errors
from deeper layers with as little loss of information as possible.

I suggest that you browse through the manual if you didn't already,
especially the first sections, and then the sections for the crypto
operations you are using.  The manual is not complete, because it does
not document how the crypto backends behave in all possible cases, but
the issues specific to GPGME should all be answered.
 
Happy hacking,
Marcus




More information about the Gnupg-devel mailing list