diff options
| author | Marcus Brinkmann <[email protected]> | 2002-11-28 19:39:48 +0000 | 
|---|---|---|
| committer | Marcus Brinkmann <[email protected]> | 2002-11-28 19:39:48 +0000 | 
| commit | 1c66649aad21afe144ac9568e47f58b4aff88aba (patch) | |
| tree | 4b3ce3b61b1f08aa929d4426caad79ee89f5c4eb /gpgmeplug/gpgmeplug.c | |
| parent | 2002-11-25 Marcus Brinkmann <[email protected]> (diff) | |
| download | gpgme-1c66649aad21afe144ac9568e47f58b4aff88aba.tar.gz gpgme-1c66649aad21afe144ac9568e47f58b4aff88aba.zip  | |
2002-11-28  Marcus Brinkmann  <[email protected]>
	* NEWS: Add note about moving "gpgmeplug" to the "cryptplug"
	package.
	* README: Remove instructions related to "gpgmeplug".
	* configure.ac: Remove enable option "gpgmeplug" and automake
	conditional BUILD_GPGMEPLUG, as well as the status info about it.
	(GPGMEPLUG): Remove variable.
	* Makefile.am (gpgmeplug): Remove variable.
	(SUBDIRS): Remove ${gpgmeplug}.
	* cryptplug.h, gpgme-openpgp.c, gpgmeplug.dox, gpgme-smime.c,
	Makefile.am, gpgmeplug.c, ChangeLog: Files removed.
CVSk: ----------------------------------------------------------------------
Diffstat (limited to 'gpgmeplug/gpgmeplug.c')
| -rw-r--r-- | gpgmeplug/gpgmeplug.c | 2921 | 
1 files changed, 0 insertions, 2921 deletions
diff --git a/gpgmeplug/gpgmeplug.c b/gpgmeplug/gpgmeplug.c deleted file mode 100644 index 8a916109..00000000 --- a/gpgmeplug/gpgmeplug.c +++ /dev/null @@ -1,2921 +0,0 @@ -/* -*- Mode: C -*- - -  $Id$ - -  GPGMEPLUG - an GPGME based cryptography plug-in following -              the common CRYPTPLUG specification. - -  Copyright (C) 2001 by Klar�lvdalens Datakonsult AB -  Copyright (C) 2002 g10 Code GmbH - -  GPGMEPLUG is free software; you can redistribute it and/or modify -  it under the terms of GNU General Public License as published by -  the Free Software Foundation; version 2 of the License. - -  GPGMEPLUG is distributed in the hope that it will be useful, -  it under the terms of GNU General Public License as published by -  the Free Software Foundation; version 2 of the License -  but WITHOUT ANY WARRANTY; without even the implied warranty of -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -  GNU General Public License for more details. - -  You should have received a copy of the GNU General Public License -  along with this program; if not, write to the Free Software -  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -*/ - - - -/*! \file gpgmeplug.c -    \brief GPGME implementation of CRYPTPLUG following the -    specification located in common API header cryptplug.h. - -    CRYPTPLUG is an independent cryptography plug-in API -    developed for Sphinx-enabeling KMail and Mutt. - -    CRYPTPLUG was designed for the Aegypten project, but it may -    be used by 3rd party developers as well to design pluggable -    crypto backends for the above mentioned MUAs. - -    \note All string parameters appearing in this API are to be -    interpreted as UTF-8 encoded. - -    \see cryptplug.h -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <errno.h> -#include <time.h> -#include <ctype.h> - -#ifndef BUG_URL -#define BUG_URL "http:://www.gnupg.org/aegypten/" -#endif - -#include "gpgme.h" -#ifndef GPGMEPLUG_PROTOCOL -#define GPGMEPLUG_PROTOCOL GPGME_PROTOCOL_OpenPGP -#endif - -/* definitions for signing */ -/* 1. opaque signatures (only used for S/MIME). */ -#ifndef GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT -#define GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT false -#define GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT  false -#define GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME   false -#define GPGMEPLUG_OPA_SIGN_CTYPE_MAIN        "" -#define GPGMEPLUG_OPA_SIGN_CDISP_MAIN        "" -#define GPGMEPLUG_OPA_SIGN_CTENC_MAIN        "" -#define GPGMEPLUG_OPA_SIGN_CTYPE_VERSION     "" -#define GPGMEPLUG_OPA_SIGN_CDISP_VERSION     "" -#define GPGMEPLUG_OPA_SIGN_CTENC_VERSION     "" -#define GPGMEPLUG_OPA_SIGN_BTEXT_VERSION     "" -#define GPGMEPLUG_OPA_SIGN_CTYPE_CODE        "" -#define GPGMEPLUG_OPA_SIGN_CDISP_CODE        "" -#define GPGMEPLUG_OPA_SIGN_CTENC_CODE        "" -#define GPGMEPLUG_OPA_SIGN_FLAT_PREFIX       "" -#define GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR    "" -#define GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX      "" -#endif -/* 2. detached signatures (used for S/MIME and for OpenPGP) */ -#ifndef GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT -#define GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT true -#define GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT  true -#define GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME   true -#define GPGMEPLUG_DET_SIGN_CTYPE_MAIN        "multipart/signed;protocol=application/pgp-signature;micalg=pgp-sha1" -#define GPGMEPLUG_DET_SIGN_CDISP_MAIN        "" -#define GPGMEPLUG_DET_SIGN_CTENC_MAIN        "" -#define GPGMEPLUG_DET_SIGN_CTYPE_VERSION     "" -#define GPGMEPLUG_DET_SIGN_CDISP_VERSION     "" -#define GPGMEPLUG_DET_SIGN_CTENC_VERSION     "" -#define GPGMEPLUG_DET_SIGN_BTEXT_VERSION     "" -#define GPGMEPLUG_DET_SIGN_CTYPE_CODE        "application/pgp-signature" -#define GPGMEPLUG_DET_SIGN_CDISP_CODE        "" -#define GPGMEPLUG_DET_SIGN_CTENC_CODE        "" -#define GPGMEPLUG_DET_SIGN_FLAT_PREFIX       "" -#define GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR    "" -#define GPGMEPLUG_DET_SIGN_FLAT_POSTFIX      "" -#endif -/* 3. common definitions for opaque and detached signing */ -#ifndef __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY -#define __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY false -#endif - -#define __GPGMEPLUG_ERROR_CLEARTEXT_IS_ZERO "Error: Cannot run checkMessageSignature() with cleartext == 0" - -/* definitions for encoding */ -#ifndef GPGMEPLUG_ENC_MAKE_MIME_OBJECT -#define GPGMEPLUG_ENC_INCLUDE_CLEARTEXT  false -#define GPGMEPLUG_ENC_MAKE_MIME_OBJECT   true -#define GPGMEPLUG_ENC_MAKE_MULTI_MIME    true -#define GPGMEPLUG_ENC_CTYPE_MAIN         "multipart/encrypted; protocol=application/pgp-encrypted" -#define GPGMEPLUG_ENC_CDISP_MAIN         "" -#define GPGMEPLUG_ENC_CTENC_MAIN         "" -#define GPGMEPLUG_ENC_CTYPE_VERSION      "application/pgp-encrypted" -#define GPGMEPLUG_ENC_CDISP_VERSION      "attachment" -#define GPGMEPLUG_ENC_CTENC_VERSION      "" -#define GPGMEPLUG_ENC_BTEXT_VERSION      "Version: 1" -#define GPGMEPLUG_ENC_CTYPE_CODE         "application/octet-stream" -#define GPGMEPLUG_ENC_CDISP_CODE         "inline; filename=\"msg.asc\"" -#define GPGMEPLUG_ENC_CTENC_CODE         "" -#define GPGMEPLUG_ENC_FLAT_PREFIX        "" -#define GPGMEPLUG_ENC_FLAT_SEPARATOR     "" -#define GPGMEPLUG_ENC_FLAT_POSTFIX       "" -#define __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY false -#endif -/* Note: The following specification will result in -       function encryptAndSignMessage() producing -       _empty_ mails. -       This must be changed as soon as our plugin -       is supporting the encryptAndSignMessage() function. */ -#ifndef GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT -#define GPGMEPLUG_ENCSIGN_INCLUDE_CLEARTEXT false -#define GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT  false -#define GPGMEPLUG_ENCSIGN_MAKE_MULTI_MIME   false -#define GPGMEPLUG_ENCSIGN_CTYPE_MAIN        "" -#define GPGMEPLUG_ENCSIGN_CDISP_MAIN        "" -#define GPGMEPLUG_ENCSIGN_CTENC_MAIN        "" -#define GPGMEPLUG_ENCSIGN_CTYPE_VERSION     "" -#define GPGMEPLUG_ENCSIGN_CDISP_VERSION     "" -#define GPGMEPLUG_ENCSIGN_CTENC_VERSION     "" -#define GPGMEPLUG_ENCSIGN_BTEXT_VERSION     "" -#define GPGMEPLUG_ENCSIGN_CTYPE_CODE        "" -#define GPGMEPLUG_ENCSIGN_CDISP_CODE        "" -#define GPGMEPLUG_ENCSIGN_CTENC_CODE        "" -#define GPGMEPLUG_ENCSIGN_FLAT_PREFIX       "" -#define GPGMEPLUG_ENCSIGN_FLAT_SEPARATOR    "" -#define GPGMEPLUG_ENCSIGN_FLAT_POSTFIX      "" -#endif - -#include "cryptplug.h" - - -#define days_from_seconds(x) ((x)/86400) - - -typedef struct { -  const char*             bugURL; -  const char*             signatureKeyCertificate; -  SignatureAlgorithm      signatureAlgorithm; -  SignatureCompoundMode   signatureCompoundMode; -  SendCertificates        sendCertificates; -  SignEmail               signEmail; -  bool                    saveSentSignatures; -  bool                    warnNoCertificate; -  PinRequests             numPINRequests; -  bool                    checkSignatureCertificatePathToRoot; -  bool                    signatureUseCRLs; -  EncryptionAlgorithm     encryptionAlgorithm; -  EncryptEmail            encryptEmail; -  bool                    saveMessagesEncrypted; -  bool                    checkEncryptionCertificatePathToRoot; -  bool                    encryptionUseCRLs; -  bool                    encryptionCRLExpiryNearWarning; -  int                     encryptionCRLNearExpiryInterval; -  struct DirectoryServer *directoryServers; -  unsigned int            numDirectoryServers; -  CertificateSource       certificateSource; -  CertificateSource       cRLSource; -  bool                    warnSendUnsigned; -  int                     numPINRequestsInterval; -  bool                    signatureCertificateExpiryNearWarning; -  int                     signatureCertificateExpiryNearInterval; -  bool                    cACertificateExpiryNearWarning; -  int                     cACertificateExpiryNearInterval; -  bool                    rootCertificateExpiryNearWarning; -  int                     rootCertificateExpiryNearInterval; -  bool                    warnSendUnencrypted; -  bool                    checkCertificatePath; -  bool                    receiverCertificateExpiryNearWarning; -  int                     receiverCertificateExpiryNearWarningInterval; -  bool                    certificateInChainExpiryNearWarning; -  int                     certificateInChainExpiryNearWarningInterval; -  bool                    receiverEmailAddressNotInCertificateWarning; -  const char* libVersion; /* a statically allocated string with the GPGME Version used */ -} Config; - - -Config config; - -#define NEAR_EXPIRY 14 - -/* Max number of parts in a DN */ -#define MAX_GPGME_IDX 20 - -/* some macros to replace ctype ones and avoid locale problems */ -#define spacep(p)   (*(p) == ' ' || *(p) == '\t') -#define digitp(p)   (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a)                     \ -                      || (*(a) >= 'A' && *(a) <= 'F')  \ -                      || (*(a) >= 'a' && *(a) <= 'f')) -/* the atoi macros assume that the buffer has only valid digits */ -#define atoi_1(p)   (*(p) - '0' ) -#define atoi_2(p)   ((atoi_1(p) * 10) + atoi_1((p)+1)) -#define atoi_4(p)   ((atoi_2(p) * 100) + atoi_2((p)+2)) -#define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \ -                     *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1)) - -static void * -xmalloc (size_t n) -{ -  char *p = malloc (n); -  if (!p) -    {  -      fputs ("\nfatal: out of core\n", stderr); -      exit (4); -    } -  return p; -} - -/* Please: Don't call an allocation function xfoo when it may return NULL. */ -/* Wrong: #define xstrdup( x ) (x)?strdup(x):0 */ -/* Right: */ -static char * -xstrdup (const char *string) -{ -  char *p = xmalloc (strlen (string)+1); -  strcpy (p, string); -  return p; -} - - - -bool initialize() -{ -  int engineCheckVersion = gpgme_engine_check_version (GPGMEPLUG_PROTOCOL); -  config.bugURL                               = malloc( strlen( BUG_URL ) + 1 ); -  strcpy( (char* )config.bugURL,                BUG_URL ); -  config.signatureKeyCertificate              = malloc( 1 ); -  strcpy( (char* )config.signatureKeyCertificate, "" ); -  config.signatureAlgorithm                   = SignAlg_SHA1; -  if( GPGMEPLUG_PROTOCOL == GPGME_PROTOCOL_CMS ) -    config.signatureCompoundMode              = SignatureCompoundMode_Opaque; -  else -    config.signatureCompoundMode              = SignatureCompoundMode_Detached; -  config.sendCertificates                     = SendCert_SendChainWithRoot; -  config.signEmail                            = SignEmail_SignAll; -  config.saveSentSignatures                   = true; -  config.warnNoCertificate                    = true; -  config.numPINRequests                       = PinRequest_Always; -  config.checkSignatureCertificatePathToRoot  = true; -  config.signatureUseCRLs                     = true; -  config.encryptionAlgorithm                  = EncryptAlg_RSA; -  config.encryptEmail                         = EncryptEmail_Ask; -  config.saveMessagesEncrypted                = true; -  config.checkEncryptionCertificatePathToRoot = true; -  config.encryptionUseCRLs                    = true; -  config.encryptionCRLExpiryNearWarning       = true; -  config.encryptionCRLNearExpiryInterval      = NEAR_EXPIRY; -  config.directoryServers                     = NULL; -  config.numDirectoryServers                  = 0; -  config.certificateSource                    = CertSrc_Server; -  config.cRLSource                            = CertSrc_Server; -  config.warnSendUnsigned                             = true; -  config.numPINRequestsInterval                       = NEAR_EXPIRY; -  config.signatureCertificateExpiryNearWarning        = true; -  config.signatureCertificateExpiryNearInterval       = NEAR_EXPIRY; -  config.cACertificateExpiryNearWarning               = true; -  config.cACertificateExpiryNearInterval              = NEAR_EXPIRY; -  config.rootCertificateExpiryNearWarning             = true; -  config.rootCertificateExpiryNearInterval            = NEAR_EXPIRY; -  config.warnSendUnencrypted                          = false; -  config.checkCertificatePath                         = true; -  config.receiverCertificateExpiryNearWarning         = true; -  config.receiverCertificateExpiryNearWarningInterval = NEAR_EXPIRY; -  config.certificateInChainExpiryNearWarning          = true; -  config.certificateInChainExpiryNearWarningInterval  = NEAR_EXPIRY; -  config.receiverEmailAddressNotInCertificateWarning  = true; -  config.libVersion = gpgme_check_version (NULL); -  if( engineCheckVersion != GPGME_No_Error ) -    fprintf( stderr, "gpgmeplug initialize() returned %i\n", engineCheckVersion ); -  return (engineCheckVersion == GPGME_No_Error); -}; - - -void deinitialize() -{ -  unsigned int i; -  for( i = 0; i < config.numDirectoryServers; ++i ) { -    free( (char *)config.directoryServers[i].servername ); -    free( (char *)config.directoryServers[i].description ); -  } -  free( config.directoryServers ); -} - - -bool hasFeature( Feature flag ) -{ -  /* our own plugins are supposed to support everything */ -  switch ( flag ) { -  case Feature_SignMessages:              return true; -  case Feature_VerifySignatures:          return true; -  case Feature_EncryptMessages:           return true; -  case Feature_DecryptMessages:           return true; -  case Feature_SendCertificates:          return true; -  case Feature_WarnSignCertificateExpiry: return true; -  case Feature_WarnSignEmailNotInCertificate: return true; -  case Feature_PinEntrySettings:          return true; -  case Feature_StoreMessagesWithSigs:     return true; -  case Feature_EncryptionCRLs:            return true; -  case Feature_WarnEncryptCertificateExpiry: return true; -  case Feature_WarnEncryptEmailNotInCertificate: return true; -  case Feature_StoreMessagesEncrypted:    return true; -  case Feature_CheckCertificatePath:      return true; -  case Feature_CertificateDirectoryService: return false; -  case Feature_CRLDirectoryService:       return false; -  /* undefined or not yet implemented: */ -  case Feature_undef:                     return false; -  default:                                      return false; -  } -} - - -const char* libVersion(){ return config.libVersion; } - - -const char* bugURL(){ return config.bugURL; } - - -void unsafeStationery( void** pixmap, const char** menutext, char* accel, -          const char** tooltip, const char** statusbartext ){} - -void signedStationery( void** pixmap, const char** menutext, char* accel, -          const char** tooltip, const char** statusbartext ){} - -void encryptedStationery( void** pixmap, const char** -          menutext, char* accel, -          const char** tooltip, const char** statusbartext ){} - -void signedEncryptedStationery( void** pixmap, const char** -          menutext, char* accel, -          const char** tooltip, const char** statusbartext ){} - -const char* signatureConfigurationDialog(){ return 0; } - -const char* signatureKeySelectionDialog(){ return 0; } - -const char* signatureAlgorithmDialog(){ return 0; } - -const char* signatureHandlingDialog(){ return 0; } - -void setSignatureKeyCertificate( const char* certificate ) -{ -  config.signatureKeyCertificate = certificate; -} - -const char* signatureKeyCertificate() -{ -  return config.signatureKeyCertificate; -} - -void setSignatureAlgorithm( SignatureAlgorithm sigAlg ) -{ -  config.signatureAlgorithm = sigAlg; -} - -SignatureAlgorithm signatureAlgorithm() -{ -  return config.signatureAlgorithm; -} - -void setSignatureCompoundMode( SignatureCompoundMode signComp ) -{ -  config.signatureCompoundMode = signComp; -} - -SignatureCompoundMode signatureCompoundMode() -{ -  return config.signatureCompoundMode; -} - -void setSendCertificates( SendCertificates sendCert ) -{ -  config.sendCertificates = sendCert; -} - -SendCertificates sendCertificates() -{ -  return config.sendCertificates; -} - -void setSignEmail( SignEmail signMail ) -{ -  config.signEmail = signMail; -} - -SignEmail signEmail() -{ -  return config.signEmail; -} - - - - - -void setWarnSendUnsigned( bool flag ) -{ -  config.warnSendUnsigned = flag; -} - -bool warnSendUnsigned() -{ -  return config.warnSendUnsigned; -} - - - - - - -void setSaveSentSignatures( bool flag ) -{ -  config.saveSentSignatures = flag; -} - -bool saveSentSignatures() -{ -  return config.saveSentSignatures; -} - -void setWarnNoCertificate( bool flag ) -{ -  config.warnNoCertificate = flag; -} - -bool warnNoCertificate() -{ -  return config.warnNoCertificate; -} - - -bool isEmailInCertificate( const char* email, const char* fingerprint ) -{ -  bool bOk = false; -  if( searchEmail && fingerprint ){ -    GpgmeCtx ctx; -    GpgmeError err; -    GpgmeKey rKey; -    int UID_idx; -    const char* attr_string; -    const char* email = searchEmail; -    int emailLen = strlen( email ); -    int emailCount = 0; - -    if (email && *email == '<'){ -      ++email; -      emailLen -= 2; -    } -     -    fprintf( stderr, "gpgmeplug isEmailInCertificate looking address %s\nin certificate with fingerprint %s\n", email, fingerprint ); - -    gpgme_new( &ctx ); -    gpgme_set_protocol( ctx, GPGMEPLUG_PROTOCOL ); - -    err = gpgme_op_keylist_start( ctx, fingerprint, 0 ); -    if ( GPGME_No_Error == err ) { -      err = gpgme_op_keylist_next( ctx, &rKey ); -      gpgme_op_keylist_end( ctx ); -      if ( GPGME_No_Error == err ) { -        /* extract email(s) */ -        for( UID_idx = 0;  -             (attr_string = gpgme_key_get_string_attr( -                              rKey, GPGME_ATTR_EMAIL, 0, UID_idx)); -             ++UID_idx ){ -          if( !attr_string || !*attr_string ) -            attr_string = gpgme_key_get_string_attr( -                            rKey, GPGME_ATTR_USERID, 0, UID_idx ); -          if( attr_string ){ -            if( *attr_string == '<' ) -              ++attr_string; -            if( *attr_string ){ -              ++emailCount; -              fprintf( stderr, "gpgmeplug isEmailInCertificate found email: %s\n", attr_string ); -              if( 0 == strncasecmp(attr_string, email, emailLen) ){ -                bOk = true; -                break; -              } -            } -          } -        } -        if( !emailCount ) -          fprintf( stderr, "gpgmeplug isEmailInCertificate found NO EMAIL\n" ); -        else if( !bOk ) -          fprintf( stderr, "gpgmeplug isEmailInCertificate found NO MATCHING email\n" ); -        gpgme_key_release( rKey ); -      }else{ -        fprintf( stderr, "gpgmeplug isEmailInCertificate found NO CERTIFICATE for fingerprint %s\n", fingerprint ); -      } -    }else{ -      fprintf( stderr, "gpgmeplug isEmailInCertificate could NOT open KEYLIST for fingerprint %s\n", fingerprint ); -    } -    gpgme_release( ctx ); -  }else{ -    if( searchEmail ) -      fprintf( stderr, "gpgmeplug isEmailInCertificate called with parameter FINGERPRINT being EMPTY\n" ); -    else -      fprintf( stderr, "gpgmeplug isEmailInCertificate called with parameter EMAIL being EMPTY\n" ); -  } -  return bOk; -} - - -void setNumPINRequests( PinRequests reqMode ) -{ -  config.numPINRequests = reqMode; - -  /* PENDING(g10) Put this value into gpg and make it ask for the pin -     according to this. Note that there is also -     setNumPINRequestsInterval() which is only used if reqMode == -     PinRequest_AfterMinutes. -  */ -} - -PinRequests numPINRequests() -{ -  return config.numPINRequests; -} - - - -void setNumPINRequestsInterval( int interval ) -{ -  config.numPINRequestsInterval = interval; - -  /* PENDING(g10) Put this value into gpg and make it ask for the pin -     according to this. Note that this should only be used if -     config.numPINRequests (set with setNumPINRequests()) has the -     value PinRequest_AfterMinutes. -  */ -} - -int numPINRequestsInterval() -{ -  return config.numPINRequestsInterval; -} - - - -void setCheckSignatureCertificatePathToRoot( bool flag ) -{ -  config.checkSignatureCertificatePathToRoot = flag; -} - -bool checkSignatureCertificatePathToRoot() -{ -  return config.checkSignatureCertificatePathToRoot; -} - -void setSignatureUseCRLs( bool flag ) -{ -  config.signatureUseCRLs = flag; -} - -bool signatureUseCRLs() -{ -  return config.signatureUseCRLs; -} - - - - - - -void setSignatureCertificateExpiryNearWarning( bool flag ) -{ -  config.signatureCertificateExpiryNearWarning = flag; -} - -bool signatureCertificateExpiryNearWarning( void ) -{ -  return config.signatureCertificateExpiryNearWarning; -} - - -int signatureCertificateDaysLeftToExpiry( const char* certificate ) -{ -  GpgmeCtx ctx; -  GpgmeError err; -  GpgmeKey rKey; -  int daysLeft = CRYPTPLUG_CERT_DOES_NEVER_EXPIRE; - -  gpgme_new( &ctx ); -  gpgme_set_protocol( ctx, GPGMEPLUG_PROTOCOL ); - -  err = gpgme_op_keylist_start( ctx, certificate, 0 ); -  if ( GPGME_No_Error == err ) { -    err = gpgme_op_keylist_next( ctx, &rKey ); -    gpgme_op_keylist_end( ctx ); -    if ( GPGME_No_Error == err ) { -      time_t expire_time = gpgme_key_get_ulong_attr( -                             rKey, GPGME_ATTR_EXPIRE, NULL, 0 ); -      if ( 0 != expire_time ) { -        time_t cur_time = time (NULL); -        if( cur_time > expire_time ) { -          daysLeft = days_from_seconds(cur_time - expire_time); -          daysLeft *= -1; -        } -        else -          daysLeft = days_from_seconds(expire_time - cur_time); -      } -      gpgme_key_release( rKey ); -    } -  } -  gpgme_release( ctx ); -     -  /*  -  fprintf( stderr, "gpgmeplug signatureCertificateDaysLeftToExpiry returned %d\n", daysLeft ); -  */ - -  return daysLeft; -} - - -void setSignatureCertificateExpiryNearInterval( int interval ) -{ -  config.signatureCertificateExpiryNearInterval = interval; -} - -int signatureCertificateExpiryNearInterval( void ) -{ -  return config.signatureCertificateExpiryNearInterval; -} - -void setCACertificateExpiryNearWarning( bool flag ) -{ -  config.cACertificateExpiryNearWarning = flag; -} - -bool caCertificateExpiryNearWarning( void ) -{ -  return config.cACertificateExpiryNearWarning; -} - -int caCertificateDaysLeftToExpiry( const char* certificate ) -{ -    /* PENDING(g10) -       Please return the number of days that are left until the -       CA certificate for the certificate specified in the parameter -       certificate expires. -    */ -  /* -  GpgmeCtx ctx; -  GpgmeError err; -  GpgmeKey rKey; -  time_t daysLeft = 0; - -  gpgme_new( &ctx ); -  gpgme_set_protocol( ctx, GPGMEPLUG_PROTOCOL ); - -  err = gpgme_op_keylist_start( ctx, certificate, 0 ); -  if ( GPGME_No_Error == err ) { -    err = gpgme_op_keylist_next( ctx, &rKey ); -    gpgme_op_keylist_end( ctx ); -    if ( GPGME_No_Error == err ) { -      time_t expire_time = gpgme_key_get_ulong_attr( -                             rKey, -                              -??????????????????????? GPGME_ATTR_EXPIRE,  ??????????????????????? -                              -                             NULL, 0 ); -      time_t cur_time = time (NULL); -      daysLeft = days_from_seconds(expire_time - cur_time); -      gpgme_key_release( rKey ); -    } -  } -  gpgme_release( ctx ); -     -    -  // fprintf( stderr, "gpgmeplug caCertificateDaysLeftToExpiry returned %d\n", daysLeft ); -  return daysLeft; -  */ -   -  return 10; /* dummy that triggers a warning in the MUA */ -} - -void setCACertificateExpiryNearInterval( int interval ) -{ -  config.cACertificateExpiryNearInterval = interval; -} - -int caCertificateExpiryNearInterval( void ) -{ -  return config.cACertificateExpiryNearInterval; -} - -void setRootCertificateExpiryNearWarning( bool flag ) -{ -  config.rootCertificateExpiryNearWarning = flag; -} - -bool rootCertificateExpiryNearWarning( void ) -{ -  return config.rootCertificateExpiryNearWarning; -} - -int rootCertificateDaysLeftToExpiry( const char* certificate ) -{ -    /* PENDING(g10) -       Please return the number of days that are left until the -       root certificate for the certificate specified in the parameter -       certificate expires. -    */ -  /* -  GpgmeCtx ctx; -  GpgmeError err; -  GpgmeKey rKey; -  time_t daysLeft = 0; - -  gpgme_new( &ctx ); -  gpgme_set_protocol( ctx, GPGMEPLUG_PROTOCOL ); - -  err = gpgme_op_keylist_start( ctx, certificate, 0 ); -  if ( GPGME_No_Error == err ) { -    err = gpgme_op_keylist_next( ctx, &rKey ); -    gpgme_op_keylist_end( ctx ); -    if ( GPGME_No_Error == err ) { -      time_t expire_time = gpgme_key_get_ulong_attr( -                             rKey, -                              -??????????????????????? GPGME_ATTR_EXPIRE,  ??????????????????????? -                              -                             NULL, 0 ); -      time_t cur_time = time (NULL); -      daysLeft = days_from_seconds(expire_time - cur_time); -      gpgme_key_release( rKey ); -    } -  } -  gpgme_release( ctx ); -     -    -  // fprintf( stderr, "gpgmeplug rootCertificateDaysLeftToExpiry returned %d\n", daysLeft ); -  return daysLeft; -  */ -   -  return 10; /* dummy that triggers a warning in the MUA */ -} - - -void setRootCertificateExpiryNearInterval( int interval ) -{ -  config.rootCertificateExpiryNearInterval = interval; -} - -int rootCertificateExpiryNearInterval( void ) -{ -  return config.rootCertificateExpiryNearInterval; -} - - - - - - - - -const char* encryptionConfigurationDialog(){ return 0; } - -const char* encryptionAlgorithmDialog(){ return 0; } - -const char* encryptionHandlingDialog(){ return 0; } - -const char* encryptionReceiverDialog(){ return 0; } - -void setEncryptionAlgorithm( EncryptionAlgorithm cryptAlg ) -{ -  config.encryptionAlgorithm = cryptAlg; -} - -EncryptionAlgorithm encryptionAlgorithm() -{ -  return config.encryptionAlgorithm; -} - -void setEncryptEmail( EncryptEmail cryptMode ) -{ -  config.encryptEmail = cryptMode; -} - -EncryptEmail encryptEmail() -{ -  return config.encryptEmail; -} - - - - - - -void setWarnSendUnencrypted( bool flag ) -{ -  config.warnSendUnencrypted = flag; -} - -bool warnSendUnencrypted() -{ -  return config.warnSendUnencrypted; -} - - - - - - - - - -void setSaveMessagesEncrypted( bool flag ) -{ -  config.saveMessagesEncrypted = flag; -} - -bool saveMessagesEncrypted() -{ -  return config.saveMessagesEncrypted; -} - - - - - - - -void setCheckCertificatePath( bool flag ) -{ -  config.checkCertificatePath = flag; -} - -bool checkCertificatePath() -{ -  return config.checkCertificatePath; -} - - - - - - - - -void setCheckEncryptionCertificatePathToRoot( bool flag ) -{ -  config.checkEncryptionCertificatePathToRoot = flag; -} - -bool checkEncryptionCertificatePathToRoot() -{ -  return config.checkEncryptionCertificatePathToRoot; -} - - - - - - - -void setReceiverCertificateExpiryNearWarning( bool flag ) -{ -  config.receiverCertificateExpiryNearWarning = flag; -} - -bool receiverCertificateExpiryNearWarning() -{ -  return config.receiverCertificateExpiryNearWarning; -} - - -int receiverCertificateDaysLeftToExpiry( const char* certificate ) -{ -  GpgmeCtx ctx; -  GpgmeError err; -  GpgmeKey rKey; -  int daysLeft = CRYPTPLUG_CERT_DOES_NEVER_EXPIRE; - -  gpgme_new( &ctx ); -  gpgme_set_protocol( ctx, GPGMEPLUG_PROTOCOL ); - -  err = gpgme_op_keylist_start( ctx, certificate, 0 ); -  if ( GPGME_No_Error == err ) { -    err = gpgme_op_keylist_next( ctx, &rKey ); -    gpgme_op_keylist_end( ctx ); -    if ( GPGME_No_Error == err ) { -      time_t expire_time = gpgme_key_get_ulong_attr( -                             rKey,GPGME_ATTR_EXPIRE, NULL, 0 ); -      if ( 0 != expire_time ) { -        time_t cur_time = time (NULL); -        if( cur_time > expire_time ) { -          daysLeft = days_from_seconds(cur_time - expire_time); -          daysLeft *= -1; -        } -        else -          daysLeft = days_from_seconds(expire_time - cur_time); -      } -      gpgme_key_release( rKey ); -    } -  } -  gpgme_release( ctx ); -     -  /* -  fprintf( stderr, "gpgmeplug receiverCertificateDaysLeftToExpiry returned %d\n", daysLeft ); -  */ - -  return daysLeft; -} - - -void setReceiverCertificateExpiryNearWarningInterval( int interval ) -{ -  config.receiverCertificateExpiryNearWarningInterval = interval; -} - -int receiverCertificateExpiryNearWarningInterval() -{ -  return config.receiverCertificateExpiryNearWarningInterval; -} - -void setCertificateInChainExpiryNearWarning( bool flag ) -{ -  config.certificateInChainExpiryNearWarning = flag; -} - -bool certificateInChainExpiryNearWarning() -{ -  return config.certificateInChainExpiryNearWarning; -} - - -int certificateInChainDaysLeftToExpiry( const char* certificate ) -{ -    /* PENDING(g10) -       Please return the number of days that are left until the -       the first certificate in the chain of the specified certificate -       expires. -    */ -  return 10; /* dummy that triggers a warning in the MUA */ -} - - -void setCertificateInChainExpiryNearWarningInterval( int interval ) -{ -  config.certificateInChainExpiryNearWarningInterval = interval; -} - -int certificateInChainExpiryNearWarningInterval() -{ -  return config.certificateInChainExpiryNearWarningInterval; -} - -void setReceiverEmailAddressNotInCertificateWarning( bool flag ) -{ -  config.receiverEmailAddressNotInCertificateWarning = flag; -} - -bool receiverEmailAddressNotInCertificateWarning() -{ -  return config.receiverEmailAddressNotInCertificateWarning; -} - - - - - - - - -void setEncryptionUseCRLs( bool flag ) -{ -  config.encryptionUseCRLs = flag; - -  /* PENDING(g10) Store this setting in gpgme and use it. If true, -     every certificate used for encryption should be checked against -     applicable CRLs. -  */ -} - -bool encryptionUseCRLs() -{ -  return config.encryptionUseCRLs; -} - - -int encryptionCRLsDaysLeftToExpiry() -{ -    /* PENDING(g10) -       Please return the number of days that are left until the -       CRL used for encryption expires. -    */ -  return 10; /* dummy that triggers a warning in the MUA */ -} - -void setEncryptionCRLExpiryNearWarning( bool flag ) -{ -  config.encryptionCRLExpiryNearWarning = flag; -} - -bool encryptionCRLExpiryNearWarning() -{ -  return config.encryptionCRLExpiryNearWarning; -} - -void setEncryptionCRLNearExpiryInterval( int interval ) -{ -  config.encryptionCRLNearExpiryInterval = interval; -} - -int encryptionCRLNearExpiryInterval() -{ -  return config.encryptionCRLNearExpiryInterval; -} - - -const char* directoryServiceConfigurationDialog(){ return 0; } - -void appendDirectoryServer( const char* servername, -                            int         port, -                            const char* description ) -{ -  struct DirectoryServer *newServers = NULL; -  newServers = realloc( config.directoryServers, -			(1+config.numDirectoryServers) * sizeof *newServers ); -  if( newServers ) { -    config.directoryServers = newServers; -    newServers[ config.numDirectoryServers ].servername = -      malloc( 1+strlen( servername ) ); -    if( newServers[ config.numDirectoryServers ].servername ) { -      strcpy( (char *)newServers[ config.numDirectoryServers ].servername, -        servername ); -      newServers[ config.numDirectoryServers ].description = -        malloc( 1+strlen(  description ) ); -      if( newServers[ config.numDirectoryServers ].description ) { -        strcpy( (char *)newServers[ config.numDirectoryServers ].description, -          description ); -        newServers[ config.numDirectoryServers ].port = port; -        config.numDirectoryServers += 1; -      } -    } -  } -} - -void setDirectoryServers( struct DirectoryServer server[], unsigned int size ) -{ -  unsigned int i; -  int oldSize = config.numDirectoryServers; -  struct DirectoryServer *newServers = NULL; -  newServers = calloc ( size, sizeof *newServers ); -  if( newServers ) { -    for( i=0; i < oldSize; ++i ) { -      free( (char *)config.directoryServers[i].servername ); -      free( (char *)config.directoryServers[i].description ); -    } -    free( config.directoryServers ); -    for( i=0; i < size; ++i ) { -      newServers[ i ].servername = malloc( 1+strlen( server[i].servername ) ); -      if( newServers[ i ].servername ) { -        strcpy( (char *)newServers[ i ].servername, server[i].servername ); -        newServers[ i ].description = malloc( 1+strlen( server[i].description ) ); -        if( newServers[ i ].description ) { -          strcpy( (char *)newServers[ i ].description, server[i].description ); -          newServers[ i ].port = server[i].port; -        } -      } -    } -    config.directoryServers = newServers; -    config.numDirectoryServers = size; -  } -} - -struct DirectoryServer * directoryServers( int* numServers ) -{ -  if( numServers ) -    *numServers = config.numDirectoryServers; -  return config.directoryServers; -}; - -void setCertificateSource( CertificateSource source ) -{ -  config.certificateSource = source; -} - -CertificateSource certificateSource() -{ -  return config.certificateSource; -} - -void setCRLSource( CertificateSource source ) -{ -  config.cRLSource = source; -} - -CertificateSource crlSource() -{ -  return config.cRLSource; -} - - -bool certificateValidity( const char* certificate, -                          int* level ){ return true; } - - -void storeNewCharPtr( char** dest, const char* src ) -{ -  int sLen = strlen( src ); -  *dest = xmalloc( sLen + 1 ); -  strcpy( *dest, src ); -} - - -bool signMessage( const char*  cleartext, -                  char** ciphertext, -                  const size_t* cipherLen, -                  const char*  certificate, -                  struct StructuringInfo* structuring, -                  int* errId, -                  char** errTxt ) -{ -  bool bIsOpaque; -  GpgmeCtx ctx; -  GpgmeError err; -  GpgmeKey rKey; -  GpgmeData data,  sig; -  char* rSig  = 0; -  bool  bOk   = false; -  int sendCerts = 1; - -  init_StructuringInfo( structuring ); - -  if( !ciphertext ) -    return false; - -  err = gpgme_new (&ctx); -  gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL); - -  gpgme_set_armor (ctx, __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY ? 0 : 1); -  /*  gpgme_set_textmode (ctx, 1); */ - -  switch ( config.sendCertificates ) { -    case SendCert_undef: -      break; -    case SendCert_DontSend: -      sendCerts = 0; -      break; -    case SendCert_SendOwn: -      sendCerts = 1; -      break; -    case SendCert_SendChainWithoutRoot: -      sendCerts = -2; -      break; -    case SendCert_SendChainWithRoot: -      sendCerts = -1; -      break; -    default: -      sendCerts = 0; -      break; -  } -  gpgme_set_include_certs (ctx, sendCerts); - -  /* select the signer's key if provided */ -  if (certificate != 0) { -      err = gpgme_op_keylist_start(ctx, certificate, 0); -      while (err == GPGME_No_Error) { -          err = gpgme_op_keylist_next(ctx, &rKey); -          if (err == GPGME_No_Error) { -              unsigned long u; -              u = gpgme_key_get_ulong_attr(rKey, GPGME_ATTR_CAN_SIGN, 0, 0); -              if( u ) { - -//                const char* s; -//                s = gpgme_key_get_string_attr(rKey, GPGME_ATTR_FPR, 0, 0); -//                fprintf( stderr, "gpgmeplug signMessage signing with key: %s\n", s ); - -                  /* clear existing signers */ -                  gpgme_signers_clear(ctx); -                  /* set the signing key */ -                  gpgme_signers_add(ctx, rKey); -                  /* we only support one signer for now */ -                  break; -              } -          } -      } -      gpgme_op_keylist_end(ctx); -  } - -  /* PENDING(g10) Implement this - -     gpgme_set_signature_algorithm( ctx, config.signatureAlgorithm ) -     --> This does not make sense.  The algorithm is a property of -     the certificate used [wk 2002-03-23] */ - -  gpgme_data_new_from_mem (&data, cleartext, -                            strlen( cleartext ), 1 ); -  gpgme_data_new ( &sig ); - -  /* NOTE: Currently we support Opaque signed messages only for S/MIME, -     but not for OpenPGP mode! */ -  if( GPGMEPLUG_PROTOCOL == GPGME_PROTOCOL_CMS ) -    bIsOpaque = (SignatureCompoundMode_Opaque == signatureCompoundMode()); -  else -    bIsOpaque = false; - -  err = gpgme_op_sign ( ctx, -                        data, -                        sig, -                        bIsOpaque -                        ? GPGME_SIG_MODE_NORMAL -                        : GPGME_SIG_MODE_DETACH ); - -  if ( err == GPGME_No_Error ) { -    if( __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY ) { -      *ciphertext = gpgme_data_release_and_get_mem( sig, (size_t*)cipherLen ); -      bOk = true; -    } -    else { -      rSig = gpgme_data_release_and_get_mem( sig, (size_t*)cipherLen ); -      *ciphertext = malloc( *cipherLen + 1 ); -      if( *ciphertext ) { -        if( *cipherLen ) { -          bOk = true; -          strncpy((char*)*ciphertext, rSig, *cipherLen ); -        } -        (*ciphertext)[*cipherLen] = '\0'; -      } -      free( rSig ); -    } -  } -  else { -    gpgme_data_release( sig ); -/* -*ciphertext = malloc( 70 ); -strcpy((char*)*ciphertext, "xyz\nsig-dummy\nzyx" ); -(*ciphertext)[17] = '\0'; -err = 0; -{ -*/ -    *ciphertext = 0; -    fprintf( stderr, "\n\n    gpgme_op_sign() returned this error code:  %i\n\n", err ); -    if( errId ) -      *errId = err; -    if( errTxt ) { -      const char* _errTxt = gpgme_strerror( err ); -      *errTxt = malloc( strlen( _errTxt ) + 1 ); -      if( *errTxt ) -        strcpy(*errTxt, _errTxt ); -    } -/* -} -*/ -  } -  gpgme_data_release( data ); -  gpgme_release (ctx); - -  if( bOk && structuring ) { -    if( bIsOpaque ) { -      structuring->includeCleartext = GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT; -      structuring->makeMimeObject   = GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT; -      if( structuring->makeMimeObject ) { -        structuring->makeMultiMime  = GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME; -        storeNewCharPtr( &structuring->contentTypeMain, -                        GPGMEPLUG_OPA_SIGN_CTYPE_MAIN ); -        storeNewCharPtr( &structuring->contentDispMain, -                        GPGMEPLUG_OPA_SIGN_CDISP_MAIN ); -        storeNewCharPtr( &structuring->contentTEncMain, -                        GPGMEPLUG_OPA_SIGN_CTENC_MAIN ); -        if( structuring->makeMultiMime ) { -            storeNewCharPtr( &structuring->contentTypeVersion, -                            GPGMEPLUG_OPA_SIGN_CTYPE_VERSION ); -            storeNewCharPtr( &structuring->contentDispVersion, -                            GPGMEPLUG_OPA_SIGN_CDISP_VERSION ); -            storeNewCharPtr( &structuring->contentTEncVersion, -                            GPGMEPLUG_OPA_SIGN_CTENC_VERSION ); -            storeNewCharPtr( &structuring->bodyTextVersion, -                            GPGMEPLUG_OPA_SIGN_BTEXT_VERSION ); -            storeNewCharPtr( &structuring->contentTypeCode, -                            GPGMEPLUG_OPA_SIGN_CTYPE_CODE ); -            storeNewCharPtr( &structuring->contentDispCode, -                            GPGMEPLUG_OPA_SIGN_CDISP_CODE ); -            storeNewCharPtr( &structuring->contentTEncCode, -                            GPGMEPLUG_OPA_SIGN_CTENC_CODE ); -        } -      } else { -        storeNewCharPtr( &structuring->flatTextPrefix, -                        GPGMEPLUG_OPA_SIGN_FLAT_PREFIX ); -        storeNewCharPtr( &structuring->flatTextSeparator, -                        GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR ); -        storeNewCharPtr( &structuring->flatTextPostfix, -                        GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX ); -      } -    } else { -      structuring->includeCleartext = GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT; -      structuring->makeMimeObject   = GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT; -      if( structuring->makeMimeObject ) { -        structuring->makeMultiMime  = GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME; -        storeNewCharPtr( &structuring->contentTypeMain, -                        GPGMEPLUG_DET_SIGN_CTYPE_MAIN ); -        storeNewCharPtr( &structuring->contentDispMain, -                        GPGMEPLUG_DET_SIGN_CDISP_MAIN ); -        storeNewCharPtr( &structuring->contentTEncMain, -                        GPGMEPLUG_DET_SIGN_CTENC_MAIN ); -        if( structuring->makeMultiMime ) { -            storeNewCharPtr( &structuring->contentTypeVersion, -                            GPGMEPLUG_DET_SIGN_CTYPE_VERSION ); -            storeNewCharPtr( &structuring->contentDispVersion, -                            GPGMEPLUG_DET_SIGN_CDISP_VERSION ); -            storeNewCharPtr( &structuring->contentTEncVersion, -                            GPGMEPLUG_DET_SIGN_CTENC_VERSION ); -            storeNewCharPtr( &structuring->bodyTextVersion, -                            GPGMEPLUG_DET_SIGN_BTEXT_VERSION ); -            storeNewCharPtr( &structuring->contentTypeCode, -                            GPGMEPLUG_DET_SIGN_CTYPE_CODE ); -            storeNewCharPtr( &structuring->contentDispCode, -                            GPGMEPLUG_DET_SIGN_CDISP_CODE ); -            storeNewCharPtr( &structuring->contentTEncCode, -                            GPGMEPLUG_DET_SIGN_CTENC_CODE ); -        } -      } else { -        storeNewCharPtr( &structuring->flatTextPrefix, -                        GPGMEPLUG_DET_SIGN_FLAT_PREFIX ); -        storeNewCharPtr( &structuring->flatTextSeparator, -                        GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR ); -        storeNewCharPtr( &structuring->flatTextPostfix, -                        GPGMEPLUG_DET_SIGN_FLAT_POSTFIX ); -      } -    } -  } -  return bOk; -} - - - -bool storeCertificatesFromMessage( -        const char* ciphertext ){ return true; } - - -/* returns address if address doesn't contain a <xxx> part - * else it returns a new string xxx and frees address - */ -static char* parseAddress( char* address ) -{ -  char* result = address; -  char* i; -  char* j; -  if( !result ) return result; -  i = index( address, '<' ); -  if( i ) { -    j = index( i+1, '>' ); -    if( j == NULL ) j = address+strlen(address); -    result = xmalloc( j-i ); -    strncpy( result, i+1, j-i-1 ); -    result[j-i-1] = '\0'; -    free( address ); -  } else { -    i = address; -    j = i+strlen(address); -  } -  { -    /* remove surrounding whitespace */ -    char* k = result+(j-i-1); -    char* l = result; -    while( isspace( *l ) ) ++l; -    while( isspace( *k ) ) --k; -    if( l != result || k != result+(j-i-1) ) { -      char* result2 = xmalloc( k-l+2 ); -      strncpy( result2, l, k-l+1 ); -      result2[k-l+1] = '\0'; -      free(result); -      result = result2; -    } -  } -  return result; -} - -static char* nextAddress( const char** address ) -{ -  const char *start = *address; -  char* result = NULL; -  int quote = 0; -  int comment = 0; -  int found = 0; -  if( *address == NULL ) return NULL; -  while( **address ) { - -    switch( **address ) { -    case '\\': /* escaped character */ -      ++(*address); -      break; -    case '"': -      if( comment == 0 ) { -        if( quote > 0 ) --quote; -        else ++quote; -      } -      break; -    case '(': /* comment start */ -      if( quote == 0 ) ++comment; -      break; -    case ')': /* comment end */ -      if( quote == 0 ) --comment; -      break; -    case '\0': -    case '\1': /* delimiter */ -      if( quote == 0 && comment == 0 ) { -        found = 1; -      } -      break; -    } -    ++(*address); -    if( found ) break; -  } -  if( found || **address == 0 ) { -    size_t len; -    len = *address - start; -    if( len > 0 ) { -      if( **address != 0 ) --len; -      result = xmalloc( len*sizeof(char)+1 ); -      strncpy( result, start, len ); -      result[len] = '\0'; -    } -  } -  return parseAddress(result); -} - -bool encryptMessage( const char*  cleartext, -                     const char** ciphertext, -                     const size_t* cipherLen, -                     const char*  certificate, -                     struct StructuringInfo* structuring, -                     int* errId, -                     char** errTxt ) -{ -  GpgmeCtx ctx; -  GpgmeError err; -  GpgmeData gCiphertext, gPlaintext; -  GpgmeRecipients rset; -  char*  rCiph = 0; -  bool   bOk   = false; - -  init_StructuringInfo( structuring ); - -  gpgme_new (&ctx); -  gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL); - -  gpgme_set_armor (ctx, __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY ? 0 : 1); -  /*  gpgme_set_textmode (ctx, 1); */ - -  gpgme_data_new_from_mem (&gPlaintext, cleartext, -                            1+strlen( cleartext ), 1 ); -  err = gpgme_data_new ( &gCiphertext ); - -  gpgme_recipients_new (&rset); - -  /* -  if( GPGMEPLUG_PROTOCOL == GPGME_PROTOCOL_CMS ) -  { -    gpgme_recipients_add_name (rset, -      "/CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=D�?sseldorf,C=DE" ); - -    fputs( "\nGPGSMPLUG encryptMessage() using test key of Aegypten Project\n", stderr ); -  } -  else -  */ -  { -    const char* p = certificate; -    char* tok; -    while( (tok = nextAddress( &p ) ) != 0 ) { -      gpgme_recipients_add_name (rset, tok ); -      fprintf( stderr, "\nGPGMEPLUG encryptMessage() using addressee %s\n", tok ); -      free(tok); -    } -  } - -  /* PENDING(g10) Implement this -     Possible values: RSA = 1, SHA1 = 2, TripleDES = 3 -     gpgme_set_encryption_algorithm( ctx, config.encryptionAlgorithm ); - -     -> Your are mixing public key and symmetric algorithms.  The -     latter may be configured but the sphix specifications do opnly -     allow 3-DES so this is not nothing we need to do.  The proper way -     to select the symmetric algorithm is anyway by looking at the -     capabilities of the certificate because this is the only way to -     know what the recipient can accept. [wk 2002-03-23] - -     PENDING(g10) Implement this -     gpgme_set_encryption_check_certificate_path( -     config.checkCertificatePath ) - -     PENDING(g10) Implement this -     gpgme_set_encryption_check_certificate_path_to_root( -     config.checkEncryptionCertificatePathToRoot ) - -     -> Not checking a certificate up to the ROOT CA is dangerous and -     stupid. There is no need for those options.  [wk 2002-03-23] */ - - - -  err = gpgme_op_encrypt (ctx, rset, gPlaintext, gCiphertext ); -  if( err ) { -    fprintf( stderr, "\ngpgme_op_encrypt() returned this error code:  %i\n", err ); -    if( errId ) -      *errId = err; -    if( errTxt ) { -      const char* _errTxt = gpgme_strerror( err ); -      *errTxt = malloc( strlen( _errTxt ) + 100 ); // leave room for reason string -      if( *errTxt ) { -        char* opInfo; -        strcpy(*errTxt, _errTxt ); -        opInfo = gpgme_get_op_info(ctx, 0); -        if( NULL != opInfo && *opInfo ){ -          const int opLen = strlen( opInfo ); -          const int reasonLen = 8; -          char reason[ 1+reasonLen ]; -          char* pos1; -          strcpy( reason, "<reason>" ); -          pos1 = strstr( opInfo, reason ); -          if( NULL != pos1 &&  -              opLen > reasonLen + (pos1 - opInfo) ){ -            char* pos2; -            pos1 += reasonLen; -            pos2 = strchr( pos1, '<' ); -            if( NULL != pos2 && -                pos1 < pos2 ){ -              long int reasonId; -              strcat( *errTxt, " - " ); -              *pos2 = '\0'; -              fprintf( stderr, "                        and this reason code:  %s\n\n", pos1 ); -              reasonId = strtol( pos1, NULL, 10 ); -              switch( reasonId ) { -                case  0: strcat( *errTxt, "No specific reason given" ); -                         break; -                case  1: strcat( *errTxt, "Not Found" ); -                         break; -                case  2: strcat( *errTxt, "Ambigious specification" ); -                         break; -                case  3: strcat( *errTxt, "Key can't be used for operation" ); -                         break; -                case  4: strcat( *errTxt, "Key has been revoked" ); -                         break; -                case  5: strcat( *errTxt, "Key has expired" ); -                         break; -                case  6: strcat( *errTxt, "No CRL known for certificate" ); -                         break; -                case  7: strcat( *errTxt, "No current CRL available" ); -                         break; -                case  8: strcat( *errTxt, "Contraints not matched" ); -                         break; -                default: { -                           strcat( *errTxt, "Extended error Id: #" ); -                           strcat( *errTxt, pos1 ); -                         }   -              } -              *pos2 = '<'; -            } -          } -          free( opInfo ); -        } -      } -    } -  } - -  gpgme_recipients_release (rset); -  gpgme_data_release (gPlaintext); - -  if( err == GPGME_No_Error ) { -    if( __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY ) { -      *ciphertext = gpgme_data_release_and_get_mem( gCiphertext, (size_t*)cipherLen ); -      bOk = true; -    } -    else { -      rCiph = gpgme_data_release_and_get_mem( gCiphertext, (size_t*)cipherLen ); -      *ciphertext = malloc( *cipherLen + 1 ); -      if( *ciphertext ) { -        if( *cipherLen ) { -          bOk = true; -          strncpy((char*)*ciphertext, rCiph, *cipherLen ); -        } -        ((char*)(*ciphertext))[*cipherLen] = 0; -      } -      free( rCiph ); -    } -  } -  else { -    gpgme_data_release ( gCiphertext ); -    *ciphertext = 0; -    /* error handling is missing: if only one untrusted key was found -      (or none at all), gpg won't sign the message.  (hier fehlt eine -      Fehlerbehandlung: fuer einen Recipient nur ein untrusted key -      (oder gar keiner) gefunden wurde, verweigert gpg das signieren.) -    */ -  } - -  gpgme_release (ctx); - -  fflush( stderr ); - -  if( bOk && structuring ) { -    structuring->includeCleartext = GPGMEPLUG_ENC_INCLUDE_CLEARTEXT; -    structuring->makeMimeObject   = GPGMEPLUG_ENC_MAKE_MIME_OBJECT; -    if( structuring->makeMimeObject ) { -      structuring->makeMultiMime  = GPGMEPLUG_ENC_MAKE_MULTI_MIME; -      storeNewCharPtr( &structuring->contentTypeMain, -                       GPGMEPLUG_ENC_CTYPE_MAIN ); -      storeNewCharPtr( &structuring->contentDispMain, -                       GPGMEPLUG_ENC_CDISP_MAIN ); -      storeNewCharPtr( &structuring->contentTEncMain, -                       GPGMEPLUG_ENC_CTENC_MAIN ); -      if( structuring->makeMultiMime ) { -        storeNewCharPtr( &structuring->contentTypeVersion, -                         GPGMEPLUG_ENC_CTYPE_VERSION ); -        storeNewCharPtr( &structuring->contentDispVersion, -                         GPGMEPLUG_ENC_CDISP_VERSION ); -        storeNewCharPtr( &structuring->contentTEncVersion, -                         GPGMEPLUG_ENC_CTENC_VERSION ); -        storeNewCharPtr( &structuring->bodyTextVersion, -                         GPGMEPLUG_ENC_BTEXT_VERSION ); -        storeNewCharPtr( &structuring->contentTypeCode, -                         GPGMEPLUG_ENC_CTYPE_CODE ); -        storeNewCharPtr( &structuring->contentDispCode, -                         GPGMEPLUG_ENC_CDISP_CODE ); -        storeNewCharPtr( &structuring->contentTEncCode, -                         GPGMEPLUG_ENC_CTENC_CODE ); -      } -    } else { -      storeNewCharPtr( &structuring->flatTextPrefix, -                       GPGMEPLUG_ENC_FLAT_PREFIX ); -      storeNewCharPtr( &structuring->flatTextSeparator, -                       GPGMEPLUG_ENC_FLAT_SEPARATOR ); -      storeNewCharPtr( &structuring->flatTextPostfix, -                       GPGMEPLUG_ENC_FLAT_POSTFIX ); -    } -  } -  return bOk; -} - - -bool encryptAndSignMessage( const char* cleartext, -                            const char** ciphertext, -                            const char* certificate, -                            struct StructuringInfo* structuring ) -{ -  bool bOk; - -  init_StructuringInfo( structuring ); - -  bOk = false; - -  /* implementation of this function is still missing */ - -  if( bOk && structuring ) { -    structuring->includeCleartext = GPGMEPLUG_ENCSIGN_INCLUDE_CLEARTEXT; -    structuring->makeMimeObject   = GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT; -    if( structuring->makeMimeObject ) { -      structuring->makeMultiMime  = GPGMEPLUG_ENCSIGN_MAKE_MULTI_MIME; -      storeNewCharPtr( &structuring->contentTypeMain, -                       GPGMEPLUG_ENCSIGN_CTYPE_MAIN ); -      storeNewCharPtr( &structuring->contentDispMain, -                       GPGMEPLUG_ENCSIGN_CDISP_MAIN ); -      storeNewCharPtr( &structuring->contentTEncMain, -                       GPGMEPLUG_ENCSIGN_CTENC_MAIN ); -      if( structuring->makeMultiMime ) { -        storeNewCharPtr( &structuring->contentTypeVersion, -                         GPGMEPLUG_ENCSIGN_CTYPE_VERSION ); -        storeNewCharPtr( &structuring->contentDispVersion, -                         GPGMEPLUG_ENCSIGN_CDISP_VERSION ); -        storeNewCharPtr( &structuring->contentTEncVersion, -                         GPGMEPLUG_ENCSIGN_CTENC_VERSION ); -        storeNewCharPtr( &structuring->bodyTextVersion, -                         GPGMEPLUG_ENCSIGN_BTEXT_VERSION ); -        storeNewCharPtr( &structuring->contentTypeCode, -                         GPGMEPLUG_ENCSIGN_CTYPE_CODE ); -        storeNewCharPtr( &structuring->contentDispCode, -                         GPGMEPLUG_ENCSIGN_CDISP_CODE ); -        storeNewCharPtr( &structuring->contentTEncCode, -                         GPGMEPLUG_ENCSIGN_CTENC_CODE ); -      } -    } else { -      storeNewCharPtr( &structuring->flatTextPrefix, -                       GPGMEPLUG_ENCSIGN_FLAT_PREFIX ); -      storeNewCharPtr( &structuring->flatTextSeparator, -                       GPGMEPLUG_ENCSIGN_FLAT_SEPARATOR ); -      storeNewCharPtr( &structuring->flatTextPostfix, -                       GPGMEPLUG_ENCSIGN_FLAT_POSTFIX ); -    } -  } -  return bOk; -} - - -bool decryptMessage( const char* ciphertext, -                     bool        cipherIsBinary, -                     int         cipherLen, -                     const char** cleartext, -                     const char* certificate, -                     int* errId, -                     char** errTxt ) -{ -  GpgmeCtx ctx; -  GpgmeError err; -  GpgmeData gCiphertext, gPlaintext; -  size_t rCLen = 0; -  char*  rCiph = 0; -  bool bOk = false; - -  if( !ciphertext ) -    return false; - -  err = gpgme_new (&ctx); -  gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL); -   -  gpgme_set_armor (ctx, cipherIsBinary ? 0 : 1); -  /*  gpgme_set_textmode (ctx, cipherIsBinary ? 0 : 1); */ - -  /* -  gpgme_data_new_from_mem( &gCiphertext, ciphertext, -                           1+strlen( ciphertext ), 1 ); */ -  gpgme_data_new_from_mem( &gCiphertext, -                           ciphertext, -                           cipherIsBinary -                           ? cipherLen -                           : strlen( ciphertext ), -                           1 ); - -  gpgme_data_new( &gPlaintext ); - -  err = err = gpgme_op_decrypt( ctx, gCiphertext, gPlaintext ); -  if( err ) { -    fprintf( stderr, "\ngpgme_op_decrypt() returned this error code:  %i\n\n", err ); -    if( errId ) -      *errId = err; -    if( errTxt ) { -      const char* _errTxt = gpgme_strerror( err ); -      *errTxt = malloc( strlen( _errTxt ) + 1 ); -      if( *errTxt ) -        strcpy(*errTxt, _errTxt ); -    } -  } -   -  gpgme_data_release( gCiphertext ); - -  rCiph = gpgme_data_release_and_get_mem( gPlaintext,  &rCLen ); - -  *cleartext = malloc( rCLen + 1 ); -  if( *cleartext ) { -      if( rCLen ) { -          bOk = true; -          strncpy((char*)*cleartext, rCiph, rCLen ); -      } -      ((char*)(*cleartext))[rCLen] = 0; -  } - -  free( rCiph ); -  gpgme_release( ctx ); -  return bOk; -} - - -const char* requestCertificateDialog(){ return 0; } - - -/* The buffer generatedKey contains the LEN bytes you want. -   Caller is responsible for freeing. */ -bool requestDecentralCertificate( const char* certparms,  -                                  char** generatedKey, int* length ) -{ -    GpgmeError err; -    GpgmeCtx ctx; -    GpgmeData pub; -    int len; - -    err = gpgme_data_new (&pub); -    fprintf( stderr,  "1: gpgme returned %d\n", err ); -    if( err != GPGME_No_Error ) -        return false; - -    err = gpgme_new (&ctx); -    fprintf( stderr,  "2: gpgme returned %d\n", err ); -    if( err != GPGME_No_Error ) { -        gpgme_data_release( pub ); -        return false; -    } - -    gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS); -    /* Don't ASCII-armor, the MUA will use base64 encoding */ -    /*    gpgme_set_armor (ctx, 1); */ -    err = gpgme_op_genkey (ctx, certparms, pub, NULL, NULL); -    fprintf( stderr,  "3: gpgme returned %d\n", err ); -    if( err != GPGME_No_Error ) { -        gpgme_data_release( pub ); -        gpgme_release( ctx ); -        return false; -    } - -    gpgme_release (ctx); -    *generatedKey = gpgme_data_release_and_get_mem (pub, &len); -    *length = len; - -    return true; -} - -bool requestCentralCertificateAndPSE( const char* name, -          const char* email, const char* organization, const char* department, -          const char* ca_address ){ return true; } - -bool createPSE(){ return true; } - -bool registerCertificate( const char* certificate ){ return true; } - -bool requestCertificateProlongation( const char* certificate, -                                     const char* ca_address ){ return true; } - -const char* certificateChain(){ return 0; } - -bool deleteCertificate( const char* certificate ){ return true; } - -bool archiveCertificate( const char* certificate ){ return true; } - - -const char* displayCRL(){ return 0; } - -void updateCRL(){} - - -char * -trim_trailing_spaces( char *string ) -{ -    char *p, *mark; - -    for( mark = NULL, p = string; *p; p++ ) { -	if( isspace( *p ) ) { -	    if( !mark ) -		mark = p; -	} -	else -	    mark = NULL; -    } -    if( mark ) -	*mark = '\0' ; - -    return string ; -} - -/* Parse a DN and return an array-ized one.  This is not a validating -   parser and it does not support any old-stylish syntax; gpgme is -   expected to return only rfc2253 compatible strings. */ -static const unsigned char * -parse_dn_part (struct DnPair *array, const unsigned char *string) -{ -  const unsigned char *s, *s1; -  size_t n; -  unsigned char *p; - -  /* parse attributeType */ -  for (s = string+1; *s && *s != '='; s++) -    ; -  if (!*s) -    return NULL; /* error */ -  n = s - string; -  if (!n) -    return NULL; /* empty key */ -  array->key = p = xmalloc (n+1); -   -   -  memcpy (p, string, n); -  p[n] = 0; -  trim_trailing_spaces (p); -  if ( !strcmp (p, "1.2.840.113549.1.9.1") ) -    strcpy (p, "EMail"); -  string = s + 1; - -  if (*string == '#') -    { /* hexstring */ -      string++; -      for (s=string; hexdigitp (s); s++) -        s++; -      n = s - string; -      if (!n || (n & 1)) -        return NULL; /* empty or odd number of digits */ -      n /= 2; -      array->value = p = xmalloc (n+1); -       -       -      for (s1=string; n; s1 += 2, n--) -        *p++ = xtoi_2 (s1); -      *p = 0; -   } -  else -    { /* regular v3 quoted string */ -      for (n=0, s=string; *s; s++) -        { -          if (*s == '\\') -            { /* pair */ -              s++; -              if (*s == ',' || *s == '=' || *s == '+' -                  || *s == '<' || *s == '>' || *s == '#' || *s == ';'  -                  || *s == '\\' || *s == '\"' || *s == ' ') -                n++; -              else if (hexdigitp (s) && hexdigitp (s+1)) -                { -                  s++; -                  n++; -                } -              else -                return NULL; /* invalid escape sequence */ -            } -          else if (*s == '\"') -            return NULL; /* invalid encoding */ -          else if (*s == ',' || *s == '=' || *s == '+' -                   || *s == '<' || *s == '>' || *s == '#' || *s == ';' ) -            break;  -          else -            n++; -        } - -      array->value = p = xmalloc (n+1); -       -       -      for (s=string; n; s++, n--) -        { -          if (*s == '\\') -            {  -              s++; -              if (hexdigitp (s)) -                { -                  *p++ = xtoi_2 (s); -                  s++; -                } -              else -                *p++ = *s; -            } -          else -            *p++ = *s; -        } -      *p = 0; -    } -  return s; -} - - -/* Parse a DN and return an array-ized one.  This is not a validating -   parser and it does not support any old-stylish syntax; gpgme is -   expected to return only rfc2253 compatible strings. */ -static struct DnPair * -parse_dn (const unsigned char *string) -{ -  struct DnPair *array; -  size_t arrayidx, arraysize; -  int i; - -  if( !string ) -    return NULL; - -  arraysize = 7; /* C,ST,L,O,OU,CN,email */ -  arrayidx = 0; -  array = xmalloc ((arraysize+1) * sizeof *array); -   -   -  while (*string) -    { -      while (*string == ' ') -        string++; -      if (!*string) -        break; /* ready */ -      if (arrayidx >= arraysize) -        { /* mutt lacks a real safe_realoc - so we need to copy */ -          struct DnPair *a2; - -          arraysize += 5; -          a2 = xmalloc ((arraysize+1) * sizeof *array); -          for (i=0; i < arrayidx; i++) -            { -              a2[i].key = array[i].key; -              a2[i].value = array[i].value; -            } -          free (array); -          array = a2; -        } -      array[arrayidx].key = NULL; -      array[arrayidx].value = NULL; -      string = parse_dn_part (array+arrayidx, string); -      arrayidx++; -      if (!string) -        goto failure; -      while (*string == ' ') -        string++; -      if (*string && *string != ',' && *string != ';' && *string != '+') -        goto failure; /* invalid delimiter */ -      if (*string) -        string++; -    } -  array[arrayidx].key = NULL; -  array[arrayidx].value = NULL; -  return array; - - failure: -  for (i=0; i < arrayidx; i++) -    { -      free (array[i].key); -      free (array[i].value); -    } -  free (array); -  return NULL; -} - -static int  -add_dn_part( char* result, struct DnPair* dn, const char* part ) -{ -  int any = 0; - -  if( dn ) { -    for(; dn->key; ++dn ) { -      if( !strcmp( dn->key, part ) ) { -        if( any ) strcat( result, "+" ); -        /* email hack */ -        if( !strcmp( part, "1.2.840.113549.1.9.1" ) ) strcat( result, "EMail" ); -        else strcat( result, part ); -        strcat( result, "=" ); -        strcat( result, dn->value ); -        any = 1; -      } -    } -  } -  return any; -} - -static char*  -reorder_dn( struct DnPair *dn ) -{ -  /* note: The must parts are: CN, L, OU, O, C */ -  const char* stdpart[] = { -    "CN", "S", "SN", "GN", "T", "UID", -          "MAIL", "EMAIL", "MOBILE", "TEL", "FAX", "STREET", -    "L",  "PC", "SP", "ST", -    "OU", -    "O", -    "C", -    NULL -  }; -  int any=0, any2=0, len=0, i; -  char* result; -  if( dn ) { -    for( i = 0; dn[i].key; ++i ) { -      len += strlen( dn[i].key ); -      len += strlen( dn[i].value ); -      len += 4; /* ',' and '=', and possibly "(" and ")" */ -    } -  } -  result = xmalloc( (len+1)*sizeof(char) ); -  *result = 0; - -  /* add standard parts */ -  for( i = 0; stdpart[i]; ++i ) { -    if( any ) { -      strcat( result, "," ); -    } -    any = add_dn_part( result, dn, stdpart[i] ); -  } - -  /* add remaining parts in no particular order */ -  if( dn ) { -    for(; dn->key; ++dn ) { -      for( i = 0; stdpart[i]; ++i ) { -        if( !strcmp( dn->key, stdpart[i] ) ) { -          break; -        } -      } -      if( !stdpart[i] ) { -        if( any ) strcat( result, "," ); -        if( !any2 ) strcat( result, "("); -        any = add_dn_part( result, dn, dn->key ); -        any2 = 1; -      } -    } -  } -  if( any2 ) strcat( result, ")"); -  return result; -} - -struct CertIterator { -  GpgmeCtx ctx;   -  struct CertificateInfo info; -}; - -struct CertIterator*  -startListCertificates( const char* pattern, int remote ) -{ -    GpgmeError err; -    struct CertIterator* it; -    const char* patterns[] = { pattern, NULL }; -    fprintf( stderr,  "startListCertificates( \"%s\", %d )\n", pattern, remote ); - -    it = xmalloc( sizeof( struct CertIterator ) ); - -    err = gpgme_new (&(it->ctx)); -    /*fprintf( stderr,  "2: gpgme returned %d\n", err );*/ -    if( err != GPGME_No_Error ) { -      free( it ); -      return NULL; -    } - -    gpgme_set_protocol (it->ctx, GPGME_PROTOCOL_CMS); -    if( remote ) gpgme_set_keylist_mode ( it->ctx, GPGME_KEYLIST_MODE_EXTERN );  -    else gpgme_set_keylist_mode ( it->ctx, GPGME_KEYLIST_MODE_LOCAL ); -    err =  gpgme_op_keylist_ext_start ( it->ctx, patterns, 0, 0); -    if( err != GPGME_No_Error ) { -      fprintf( stderr,  "gpgme_op_keylist_ext_start returned %d", err ); -      endListCertificates( it ); -      return NULL; -    } -    memset( &(it->info), 0, sizeof( struct CertificateInfo ) ); -    return it; -} - -/* free() each string in a char*[] and the array itself */ -static void  -freeStringArray( char** c ) -{ -    char** _c = c; - -    while( c && *c ) { -      /*fprintf( stderr, "freeing \"%s\"\n", *c );*/ -      free( *c ); -      ++c; -    } -    free( _c ); -} - -/* free all malloc'ed data in a struct CertificateInfo */ -static void  -freeInfo( struct CertificateInfo* info ) -{ -  struct DnPair* a = info->dnarray; -  assert( info ); -  freeStringArray( info->userid ); -  free( info->serial); -  free( info->fingerprint ); -  free( info->issuer ); -  free( info->chainid ); -  free( info->caps ); -  while( a && a->key && a->value ) { -    free (a->key); -    free (a->value); -    ++a; -  } -  free (info->dnarray); -  memset( info, 0, sizeof( *info ) ); -} - -/* Format the fingerprint nicely. The caller should -   free the returned value using free() */ -static char* make_fingerprint( const char* fpr ) -{ -  int len = strlen(fpr); -  int i = 0; -  char* result = xmalloc( (len + len/2 + 1)*sizeof(char) ); - -  for(; *fpr; ++fpr, ++i ) { -    if( i%3 == 2) { -      result[i] = ':'; ++i; -    } -    result[i] = *fpr; -  } -  result[i] = 0; -  return result; -} - -int  -nextCertificate( struct CertIterator* it, struct CertificateInfo** result ) -{ -  GpgmeError err; -  GpgmeKey   key; -  int retval = GPGME_No_Error; -  assert( it ); -  fprintf( stderr,  "nextCertificates( %p, %p )\n", it, result ); -  err = gpgme_op_keylist_next ( it->ctx, &key); -  if( err != GPGME_EOF ) {    -    int idx; -    const char* s; -    unsigned long u; -    char* names[MAX_GPGME_IDX+1]; -    struct DnPair *issuer_dn, *tmp_dn; -    retval = err; -    memset( names, 0, sizeof( names ) ); -    freeInfo( &(it->info) ); - -    for( idx = 0; (s = gpgme_key_get_string_attr (key, GPGME_ATTR_USERID, 0, idx)) && idx < MAX_GPGME_IDX;  -	 ++idx ) { -      names[idx] = xstrdup( s ); -    } -     -    it->info.userid = xmalloc( sizeof( char* ) * (idx+1) ); -    memset( it->info.userid, 0, sizeof( char* ) * (idx+1) ); -    it->info.dnarray = 0; -    for( idx = 0; names[idx] != 0; ++idx ) { -      struct DnPair* a = parse_dn( names[idx] );  -      if( idx == 0 ) { -	it->info.userid[idx] = reorder_dn( a ); -	it->info.dnarray = a; -	free (names[idx]); -        names[idx] = NULL; -      } else { -	it->info.userid[idx] = names[idx]; -      } -    } -    it->info.userid[idx] = 0; - -    s = gpgme_key_get_string_attr (key, GPGME_ATTR_SERIAL, 0, 0);  -    it->info.serial = s? xstrdup(s) : NULL; - -    s = gpgme_key_get_string_attr (key, GPGME_ATTR_FPR, 0, 0);  -    it->info.fingerprint = make_fingerprint( s ); - -    s = gpgme_key_get_string_attr (key, GPGME_ATTR_ISSUER, 0, 0);  -    if( s ) { -      issuer_dn = tmp_dn = parse_dn( s );      -      /*it->info.issuer = xstrdup(s);*/ -      it->info.issuer = reorder_dn( issuer_dn ); -      while( tmp_dn && tmp_dn->key ) { -	free( tmp_dn->key ); -	free( tmp_dn->value ); -	++tmp_dn; -      } -      free( issuer_dn ); -      issuer_dn = tmp_dn = NULL; -    } else { -      it->info.issuer = NULL; -    } -    s = gpgme_key_get_string_attr (key, GPGME_ATTR_CHAINID, 0, 0);  -    it->info.chainid = s? xstrdup(s): NULL; - -    s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEY_CAPS, 0, 0);  -    it->info.caps = s? xstrdup(s) : NULL; - -    u = gpgme_key_get_ulong_attr (key, GPGME_ATTR_CREATED, 0, 0);  -    it->info.created = u; - -    u = gpgme_key_get_ulong_attr (key, GPGME_ATTR_EXPIRE, 0, 0);  -    it->info.expire = u; - -    u = gpgme_key_get_ulong_attr (key, GPGME_ATTR_IS_SECRET, 0, 0);  -    it->info.secret = u; - -    u = gpgme_key_get_ulong_attr (key, GPGME_ATTR_UID_INVALID, 0, 0);  -    it->info.invalid = u; - -    u = gpgme_key_get_ulong_attr (key, GPGME_ATTR_KEY_EXPIRED, 0, 0);  -    it->info.expired = u; - -    u = gpgme_key_get_ulong_attr (key, GPGME_ATTR_KEY_DISABLED, 0, 0);  -    it->info.disabled = u; - -    gpgme_key_release (key); -    /*return &(it->info);*/ -    *result =  &(it->info); -  } else { -    *result = NULL; -  } -  return retval; -} - -int -endListCertificates( struct CertIterator* it ) -{ -  char *s = gpgme_get_op_info (it->ctx, 0); -  int truncated = s && strstr (s, "<truncated/>"); -  fprintf( stderr,  "endListCertificates( %p )\n", it ); -  if( s ) free( s ); -  assert(it); -  freeInfo( &(it->info) ); -  gpgme_op_keylist_end(it->ctx); -  gpgme_release (it->ctx); -  free( it ); -  return truncated; -} - -int -importCertificateWithFPR( const char* fingerprint, char** additional_info ) -{ -  GpgmeError err; -  GpgmeCtx  ctx; -  GpgmeData keydata; -  GpgmeRecipients recips; -  char* buf; -  const char* tmp1; -  char* tmp2; -  int count = 0; - -  err = gpgme_new( &ctx ); -  /*fprintf( stderr,  "2: gpgme returned %d\n", err );*/ -  if( err != GPGME_No_Error ) { -    return err; -  } -  gpgme_set_protocol( ctx, GPGME_PROTOCOL_CMS ); -  gpgme_set_keylist_mode( ctx, GPGME_KEYLIST_MODE_LOCAL ); - -  err = gpgme_data_new( &keydata ); -  if( err ) { -    fprintf( stderr,  "gpgme_data_new returned %d\n", err ); -    gpgme_release( ctx ); -    return err; -  } - -  err = gpgme_recipients_new( &recips ); -  if( err ) { -    fprintf( stderr,  "gpgme_recipients_new returned %d\n", err ); -    gpgme_data_release( keydata ); -    gpgme_release( ctx ); -    return err; -  } -   -  buf = malloc( sizeof(char)*( strlen( fingerprint ) + 1 ) ); -  if( !buf ) { -    gpgme_recipients_release( recips ); -    gpgme_data_release( keydata );     -    gpgme_release( ctx ); -    return GPGME_Out_Of_Core; -  } -  tmp1 = fingerprint; -  tmp2 = buf; -  while( *tmp1 ) { -    if( *tmp1 != ':' ) *tmp2++ = *tmp1; -    tmp1++; -  } -  *tmp2 = 0; -  fprintf( stderr,  "calling gpgme_recipients_add_name( %s )\n", buf );   -  err = gpgme_recipients_add_name( recips, buf );  -  if( err ) { -    fprintf( stderr,  "gpgme_recipients_add_name returned %d\n", err ); -    free (buf); -    gpgme_recipients_release( recips ); -    gpgme_data_release( keydata );     -    gpgme_release( ctx ); -    return err; -  } - -  err = gpgme_op_export( ctx, recips, keydata ); -  if( err ) { -    fprintf( stderr,  "gpgme_op_export returned %d\n", err ); -    free (buf); -    *additional_info = gpgme_get_op_info( ctx, 0 ); -    gpgme_recipients_release( recips ); -    gpgme_data_release( keydata );     -    gpgme_release( ctx ); -    return err; -  } -  free (buf); -  buf = NULL; - -  err = gpgme_op_import_ext( ctx, keydata, &count ); -  *additional_info = gpgme_get_op_info( ctx, 0 ); -  if( err ) {     -    fprintf( stderr,  "gpgme_op_import_ext returned %d\n", err ); -    gpgme_recipients_release( recips ); -    gpgme_data_release( keydata ); -    gpgme_release( ctx ); -    return err; -  } -  if( count < 1 ) { -    /* we didn't import anything?!? */ -    fprintf( stderr,  "gpgme_op_import_ext did not import any certificates\n" ); -    gpgme_recipients_release( recips ); -    gpgme_data_release( keydata ); -    gpgme_release( ctx ); -    return -1; /* FIXME */ -  } - -  gpgme_recipients_release( recips ); -  gpgme_data_release( keydata );     -  gpgme_release( ctx ); -  return 0; -} -int -importCertificateFromMem( const char* data, size_t length , char** additional_info ) -{ -  GpgmeError err; -  GpgmeCtx  ctx; -  GpgmeData keydata; -  int count = 0; - -  err = gpgme_new( &ctx ); -  /*fprintf( stderr,  "2: gpgme returned %d\n", err );*/ -  if( err != GPGME_No_Error ) { -    return err; -  } -  gpgme_set_protocol( ctx, GPGME_PROTOCOL_CMS ); -  gpgme_set_keylist_mode( ctx, GPGME_KEYLIST_MODE_LOCAL ); - -  err = gpgme_data_new_from_mem( &keydata, data, length, 0 ); -  if( err ) { -    fprintf( stderr,  "gpgme_data_new returned %d\n", err ); -    gpgme_release( ctx ); -    return err; -  } - -  err = gpgme_op_import_ext( ctx, keydata, &count ); -  *additional_info = gpgme_get_op_info( ctx, 0 ); -  if( err) { -    fprintf( stderr,  "gpgme_op_import_ext returned %d\n", err ); -    gpgme_data_release( keydata );     -    gpgme_release( ctx ); -    return err; -  } -  if( count < 1 ) { -    /* we didn't import anything?!? */ -    fprintf( stderr,  "gpgme_op_import_ext did not import any certificate\n" );     -    gpgme_data_release( keydata );     -    gpgme_release( ctx ); -    return -1; /* FIXME */ -  } - -  gpgme_data_release( keydata );     -  gpgme_release( ctx ); -  return 0; -} - -/*  == == == == == == == == == == == == == == == == == == == == == == == == == -   ==                                                                      == -  ==         Continuation of CryptPlug code                               == - ==                                                                      == -== == == == == == == == == == == == == == == == == == == == == == == == ==  */ - - -/* -  Find all certificate for a given addressee and return them in a -  '\1' separated list. -  NOTE: The certificate parameter must point to a not-yet allocated -        char*.  The function will allocate the memory needed and -        return the size in newSize. -  If secretOnly is true, only secret keys are returned. -*/ -bool findCertificates( const char* addressee, -                       char** certificates, -                       int* newSize, -                       bool secretOnly ) -{ -#define MAXCERTS 1024 -  /* use const char declarations since all of them are needed twice */ -  const char* delimiter = "\1"; -  const char* openBracket = "    ("; -  const char* closeBracket = ")"; - -  GpgmeCtx ctx; -  GpgmeError err; -  GpgmeKey rKey; -  const char *s; -  const char *s2; -  char* dn; -  struct DnPair* a; -  int nFound = 0; -  int iFound = 0; -  int siz = 0; -  char* DNs[MAXCERTS]; -  char* FPRs[MAXCERTS]; -   -  if( ! certificates ){ -    fprintf( stderr, "gpgme: findCertificates called with invalid *certificates pointer\n" ); -    return false; -  } - -  if( ! newSize ){ -    fprintf( stderr, "gpgme: findCertificates called with invalid newSize pointer\n" ); -    return false; -  } - -  *certificates = 0; -  *newSize = 0; -   -  /* calculate length of buffer needed for certs plus fingerprints */ -  gpgme_new (&ctx); -  gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL); -  err = gpgme_op_keylist_start(ctx, addressee, secretOnly ? 1 : 0); -  while( GPGME_No_Error == err ) { -    err = gpgme_op_keylist_next(ctx, &rKey); -    if( GPGME_No_Error == err ) { -      s = gpgme_key_get_string_attr (rKey, GPGME_ATTR_USERID, NULL, 0); -      if( s ) { -        dn = xstrdup( s ); -        s2 = gpgme_key_get_string_attr (rKey, GPGME_ATTR_FPR, NULL, 0); -        if( s2 ) { -          if( nFound ) -            siz += strlen( delimiter ); -          a = parse_dn( dn ); -          free( dn ); -          dn = reorder_dn( a ); -          siz += strlen( dn ); -          siz += strlen( openBracket ); -          siz += strlen( s2 ); -          siz += strlen( closeBracket ); -          DNs[ nFound ] = dn; -          dn = NULL; /* prevent it from being free'ed below. */ -          FPRs[nFound ] = xstrdup( s2 ); -          ++nFound; -          if( nFound >= MAXCERTS ) { -            fprintf( stderr, -                     "gpgme: findCertificates found too many certificates (%d)\n", -                     MAXCERTS ); -            break; -          } -        } -        free (dn);  -      } -    } -  } -  gpgme_op_keylist_end( ctx ); -  gpgme_release (ctx); -   -   -  if( 0 < siz ) { -    /* add one for trailing ZERO char */ -    ++siz; -    *newSize = siz; -    /* allocate the buffer */ -    *certificates = xmalloc( sizeof(char) * siz ); -    memset( *certificates, 0, sizeof(char) * siz ); -    /* fill the buffer */ -    for (iFound=0; iFound < nFound; iFound++) { -      if( !iFound ) -        strcpy(*certificates, DNs[iFound] ); -      else { -        strcat(*certificates, delimiter ); -        strcat(*certificates, DNs[iFound] ); -      } -      strcat(  *certificates, openBracket ); -      strcat(  *certificates, FPRs[iFound] ); -      strcat(  *certificates, closeBracket ); -      free( DNs[ iFound ] ); -      free( FPRs[iFound ] ); -    } -  } -     -  return ( 0 < nFound ); -} - - -static const char* -sig_status_to_string( GpgmeSigStat status ) -{ -  const char *result; - -  switch (status) { -    case GPGME_SIG_STAT_NONE: -      result = "Oops: Signature not verified"; -      break; -    case GPGME_SIG_STAT_NOSIG: -      result = "No signature found"; -      break; -    case GPGME_SIG_STAT_GOOD: -      result = "Good signature"; -      break; -    case GPGME_SIG_STAT_BAD: -      result = "BAD signature"; -      break; -    case GPGME_SIG_STAT_NOKEY: -      result = "No public key to verify the signature"; -      break; -    case GPGME_SIG_STAT_ERROR: -      result = "Error verifying the signature"; -      break; -    case GPGME_SIG_STAT_DIFF: -      result = "Different results for signatures"; -      break; -    default: -      result = "Error: Unknown status"; -      break; -  } - -  return result; -} - - -void obtain_signature_information( GpgmeCtx * ctx, -                                   GpgmeSigStat status, -                                   struct SignatureMetaData* sigmeta ) -{ -  GpgmeError err; -  GpgmeKey key; -  const char* statusStr; -  const char* fpr; -  unsigned long sumGPGME; -  SigStatusFlags sumPlug; -  time_t created; -  struct DnPair* a; -  int sig_idx=0; -  int UID_idx=0; -   -  /* Provide information in the sigmeta struct */ -  /* the status string */ -  statusStr = sig_status_to_string( status ); -  sigmeta->status = malloc( strlen( statusStr ) + 1 ); -  if( sigmeta->status ) { -    strcpy( sigmeta->status, statusStr ); -    sigmeta->status[strlen( statusStr )] = '\0'; -  } else -    ; /* nothing to do, is already 0 */ - -  /* Extended information for any number of signatures. */ -  fpr = gpgme_get_sig_status( *ctx, sig_idx, &status, &created ); -  sigmeta->extended_info = 0; -  while( fpr != NULL ) { -    struct tm* ctime_val; -    const char* sig_status; - -    void* alloc_return = realloc( sigmeta->extended_info, -                                  sizeof( struct SignatureMetaDataExtendedInfo ) -                                  * ( sig_idx + 1 ) ); -    if( alloc_return ) { -      sigmeta->extended_info = alloc_return; - -      /* clear the data area */ -      memset( &sigmeta->extended_info[sig_idx],  -              0, -              sizeof (struct SignatureMetaDataExtendedInfo) ); - -      /* the creation time */ -      sigmeta->extended_info[sig_idx].creation_time = malloc( sizeof( struct tm ) ); -      if( sigmeta->extended_info[sig_idx].creation_time ) { -        ctime_val = localtime( &created ); -        memcpy( sigmeta->extended_info[sig_idx].creation_time, -                ctime_val, sizeof( struct tm ) ); -      } - -      /* the extended signature verification status */ -      sumGPGME = gpgme_get_sig_ulong_attr( *ctx, -                                           sig_idx, -                                           GPGME_ATTR_SIG_SUMMARY, -                                           0 ); -      fprintf( stderr, "gpgmeplug checkMessageSignature status flags: %lX\n", sumGPGME ); -      /* translate GPGME status flags to common CryptPlug status flags */ -      sumPlug = 0; -      if( sumGPGME & GPGME_SIGSUM_VALID       ) sumPlug |= SigStat_VALID      ; -      if( sumGPGME & GPGME_SIGSUM_GREEN       ) sumPlug |= SigStat_GREEN      ; -      if( sumGPGME & GPGME_SIGSUM_RED         ) sumPlug |= SigStat_RED        ; -      if( sumGPGME & GPGME_SIGSUM_KEY_REVOKED ) sumPlug |= SigStat_KEY_REVOKED; -      if( sumGPGME & GPGME_SIGSUM_KEY_EXPIRED ) sumPlug |= SigStat_KEY_EXPIRED; -      if( sumGPGME & GPGME_SIGSUM_SIG_EXPIRED ) sumPlug |= SigStat_SIG_EXPIRED; -      if( sumGPGME & GPGME_SIGSUM_KEY_MISSING ) sumPlug |= SigStat_KEY_MISSING; -      if( sumGPGME & GPGME_SIGSUM_CRL_MISSING ) sumPlug |= SigStat_CRL_MISSING; -      if( sumGPGME & GPGME_SIGSUM_CRL_TOO_OLD ) sumPlug |= SigStat_CRL_TOO_OLD; -      if( sumGPGME & GPGME_SIGSUM_BAD_POLICY  ) sumPlug |= SigStat_BAD_POLICY ; -      if( sumGPGME & GPGME_SIGSUM_SYS_ERROR   ) sumPlug |= SigStat_SYS_ERROR  ; -      if( !sumPlug ) -        sumPlug = SigStat_NUMERICAL_CODE | sumGPGME; -      sigmeta->extended_info[sig_idx].sigStatusFlags = sumPlug; - -      sigmeta->extended_info[sig_idx].validity = GPGME_VALIDITY_UNKNOWN; - -      err = gpgme_get_sig_key (*ctx, sig_idx, &key); - -      if ( err == GPGME_No_Error) { -        const char* attr_string; -        unsigned long attr_ulong; - -        /* extract key identidy */ -        attr_string = gpgme_key_get_string_attr(key, GPGME_ATTR_KEYID, 0, 0); -        if (attr_string != 0) -            storeNewCharPtr( &sigmeta->extended_info[sig_idx].keyid, attr_string ); - -        /* extract finger print */ -        attr_string = gpgme_key_get_string_attr(key, GPGME_ATTR_FPR, 0, 0); -        if (attr_string != 0) -            storeNewCharPtr( &sigmeta->extended_info[sig_idx].fingerprint, -                            attr_string ); - -        /* algorithms useable with this key */ -        attr_string = gpgme_key_get_string_attr(key, GPGME_ATTR_ALGO, 0, 0); -        if (attr_string != 0) -            storeNewCharPtr( &sigmeta->extended_info[sig_idx].algo, -                            attr_string ); -        attr_ulong = gpgme_key_get_ulong_attr(key, GPGME_ATTR_ALGO, 0, 0); -        sigmeta->extended_info[sig_idx].algo_num = attr_ulong; - -        /* extract key validity */ -        attr_ulong = gpgme_key_get_ulong_attr(key, GPGME_ATTR_VALIDITY, 0, 0); -        sigmeta->extended_info[sig_idx].validity = attr_ulong; - -        /* extract user id, according to the documentation it's representable -        * as a number, but it seems that it also has a string representation -        */ -        attr_string = gpgme_key_get_string_attr(key, GPGME_ATTR_USERID, 0, 0); -        if (attr_string != 0) { -            a = parse_dn( attr_string ); -            sigmeta->extended_info[sig_idx].userid = reorder_dn( a ); -        } -         -        attr_ulong = gpgme_key_get_ulong_attr(key, GPGME_ATTR_USERID, 0, 0); -        sigmeta->extended_info[sig_idx].userid_num = attr_ulong; - -        /* extract the length */ -          sigmeta->extended_info[sig_idx].keylen = attr_ulong; - -        /* extract the creation time of the key */ -        attr_ulong = gpgme_key_get_ulong_attr(key, GPGME_ATTR_CREATED, 0, 0); -        sigmeta->extended_info[sig_idx].key_created = attr_ulong; - -        /* extract the expiration time of the key */ -        attr_ulong = gpgme_key_get_ulong_attr(key, GPGME_ATTR_EXPIRE, 0, 0); -        sigmeta->extended_info[sig_idx].key_expires = attr_ulong; - -        /* extract user name */ -        attr_string = gpgme_key_get_string_attr(key, GPGME_ATTR_NAME, 0, 0); -        if (attr_string != 0) { -            a = parse_dn( attr_string ); -            sigmeta->extended_info[sig_idx].name = reorder_dn( a ); -        } - -        /* extract email(s) */ -        sigmeta->extended_info[sig_idx].emailCount = 0; -        sigmeta->extended_info[sig_idx].emailList = 0; -        for( UID_idx=0;  -             (attr_string = gpgme_key_get_string_attr(key, -                              GPGME_ATTR_EMAIL, 0, UID_idx));  -             ++UID_idx ){ -          if (*attr_string) { -            fprintf( stderr, "gpgmeplug checkMessageSignature found email: %s\n", attr_string ); -            if( !sigmeta->extended_info[sig_idx].emailCount ) -                alloc_return =  -                    malloc( sizeof( char*) ); -            else -                alloc_return =  -                    realloc( sigmeta->extended_info[sig_idx].emailList, -                             sizeof( char*) -                             * (sigmeta->extended_info[sig_idx].emailCount + 1) ); -            if( alloc_return ) { -              sigmeta->extended_info[sig_idx].emailList = alloc_return; -              storeNewCharPtr(  -                  &( sigmeta->extended_info[sig_idx].emailList[ -                          sigmeta->extended_info[sig_idx].emailCount ] ), -                  attr_string ); -              ++sigmeta->extended_info[sig_idx].emailCount; -            } -          } -        } -        if( !sigmeta->extended_info[sig_idx].emailCount ) -          fprintf( stderr, "gpgmeplug checkMessageSignature found NO EMAIL\n" ); - -        /* extract the comment */ -        attr_string = gpgme_key_get_string_attr(key, GPGME_ATTR_COMMENT, 0, 0); -        if (attr_string != 0) -            storeNewCharPtr( &sigmeta->extended_info[sig_idx].comment, -                            attr_string ); -      } -      else -        storeNewCharPtr( &sigmeta->extended_info[sig_idx].fingerprint, fpr ); - -      sig_status = sig_status_to_string( status ); -      storeNewCharPtr( &sigmeta->extended_info[sig_idx].status_text, -                       sig_status ); - -    } else -      break; /* if allocation fails once, it isn't likely to -                succeed the next time either */ - -    fpr = gpgme_get_sig_status (*ctx, ++sig_idx, &status, &created); -  } -  sigmeta->extended_info_count = sig_idx; -  sigmeta->nota_xml = gpgme_get_notation( *ctx ); -  sigmeta->status_code = status; -} - - -bool checkMessageSignature( char** cleartext, -                            const char* signaturetext, -                            bool signatureIsBinary, -                            int signatureLen, -                            struct SignatureMetaData* sigmeta ) -{ -  GpgmeCtx ctx; -  GpgmeSigStat status; -  GpgmeData datapart, sigpart; -  char* rClear = 0; -  size_t clearLen; -  bool isOpaqueSigned; -   -  if( !cleartext ) { -    if( sigmeta ) -      storeNewCharPtr( &sigmeta->status, -                        __GPGMEPLUG_ERROR_CLEARTEXT_IS_ZERO ); - -    return false; -  } - -  isOpaqueSigned = !*cleartext; - -  gpgme_new( &ctx ); -  gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL); -  gpgme_set_armor (ctx,    signatureIsBinary ? 0 : 1); -  /*  gpgme_set_textmode (ctx, signatureIsBinary ? 0 : 1); */ - -  if( isOpaqueSigned ) -    gpgme_data_new( &datapart ); -  else -    gpgme_data_new_from_mem( &datapart, *cleartext, -                             strlen( *cleartext ), 1 ); - -  gpgme_data_new_from_mem( &sigpart, -                           signaturetext, -                           signatureIsBinary -                           ? signatureLen -                           : strlen( signaturetext ), -                           1 ); - -  gpgme_op_verify( ctx, sigpart, isOpaqueSigned ? NULL : datapart, -		   isOpaqueSigned ? datapart : NULL, &status ); - -  if( isOpaqueSigned ) { -    rClear = gpgme_data_release_and_get_mem( datapart, &clearLen ); -    *cleartext = malloc( clearLen + 1 ); -    if( *cleartext ) { -      if( clearLen ) -        strncpy(*cleartext, rClear, clearLen ); -      (*cleartext)[clearLen] = '\0'; -    } -    free( rClear ); -  } -  else -    gpgme_data_release( datapart ); - -  gpgme_data_release( sigpart ); - -  obtain_signature_information( &ctx, status, sigmeta ); -   -  gpgme_release( ctx ); -  return ( status == GPGME_SIG_STAT_GOOD ); -} - - -bool decryptAndCheckMessage( const char*  ciphertext, -                             bool         cipherIsBinary, -                             int          cipherLen, -                             const char** cleartext, -                             const char*  certificate, -                             bool*        signatureFound, -                             struct SignatureMetaData* sigmeta, -                             int*   errId, -                             char** errTxt ) -{ -  GpgmeCtx ctx; -  GpgmeError err; -  GpgmeSigStat sigstatus; -  GpgmeData gCiphertext, gPlaintext; -  size_t rCLen = 0; -  char*  rCiph = 0; -  bool bOk = false; - -  if( !ciphertext ) -    return false; - -  err = gpgme_new (&ctx); -  gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL); -   -  gpgme_set_armor (ctx, cipherIsBinary ? 0 : 1); -  /*  gpgme_set_textmode (ctx, cipherIsBinary ? 0 : 1); */ - -  /* -  gpgme_data_new_from_mem( &gCiphertext, ciphertext, -                           1+strlen( ciphertext ), 1 ); */ -  gpgme_data_new_from_mem( &gCiphertext, -                           ciphertext, -                           cipherIsBinary -                           ? cipherLen -                           : strlen( ciphertext ), -                           1 ); - -  gpgme_data_new( &gPlaintext ); - -  err = gpgme_op_decrypt_verify( ctx, gCiphertext, gPlaintext, &sigstatus ); -  gpgme_data_release( gCiphertext ); -  if( err ) { -    fprintf( stderr, "\ngpgme_op_decrypt_verify() returned this error code:  %i\n\n", err ); -    if( errId ) -      *errId = err; -    if( errTxt ) { -      const char* _errTxt = gpgme_strerror( err ); -      *errTxt = malloc( strlen( _errTxt ) + 1 ); -      if( *errTxt ) -        strcpy(*errTxt, _errTxt ); -    } -    gpgme_data_release( gPlaintext ); -    gpgme_release( ctx ); -    return bOk; -  } - -  rCiph = gpgme_data_release_and_get_mem( gPlaintext,  &rCLen ); - -  *cleartext = malloc( rCLen + 1 ); -  if( *cleartext ) { -      if( rCLen ) { -          bOk = true; -          strncpy((char*)*cleartext, rCiph, rCLen ); -      } -      ((char*)(*cleartext))[rCLen] = 0; -  } -  free( rCiph ); - -  if( signatureFound ) -    *signatureFound = sigstatus != GPGME_SIG_STAT_NONE; -  if( sigmeta && sigstatus != GPGME_SIG_STAT_NONE ) -    obtain_signature_information( &ctx, sigstatus, sigmeta ); -   -  gpgme_release( ctx ); -  return bOk; -}  | 
