00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
#ifdef HAVE_CONFIG_H
00028
#include <config.h>
00029
#endif
00030
00031
#include "kleo/oidmap.h"
00032
00033
#include <gpgmepp/context.h>
00034
#include <gpgmepp/data.h>
00035
#include <gpgmepp/importresult.h>
00036
00054
#include <qstring.h>
00055
00056
#include <string>
00057
#include <vector>
00058
#include <algorithm>
00059
#include <iostream>
00060
#include <memory>
00061
00062
#include <stdio.h>
00063
#include <string.h>
00064
#include <strings.h>
00065
#include <assert.h>
00066
#include <errno.h>
00067
#include <time.h>
00068
#include <ctype.h>
00069
#include <locale.h>
00070
00071
#define __GPGMEPLUG_ERROR_CLEARTEXT_IS_ZERO "Error: Cannot run checkMessageSignature() with cleartext == 0"
00072
00073
00074
00075
00076
00077
00078
#ifndef GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT
00079
#define GPGMEPLUG_ENCSIGN_INCLUDE_CLEARTEXT false
00080
#define GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT false
00081
#define GPGMEPLUG_ENCSIGN_MAKE_MULTI_MIME false
00082
#define GPGMEPLUG_ENCSIGN_CTYPE_MAIN ""
00083
#define GPGMEPLUG_ENCSIGN_CDISP_MAIN ""
00084
#define GPGMEPLUG_ENCSIGN_CTENC_MAIN ""
00085
#define GPGMEPLUG_ENCSIGN_CTYPE_VERSION ""
00086
#define GPGMEPLUG_ENCSIGN_CDISP_VERSION ""
00087
#define GPGMEPLUG_ENCSIGN_CTENC_VERSION ""
00088
#define GPGMEPLUG_ENCSIGN_BTEXT_VERSION ""
00089
#define GPGMEPLUG_ENCSIGN_CTYPE_CODE ""
00090
#define GPGMEPLUG_ENCSIGN_CDISP_CODE ""
00091
#define GPGMEPLUG_ENCSIGN_CTENC_CODE ""
00092
#define GPGMEPLUG_ENCSIGN_FLAT_PREFIX ""
00093
#define GPGMEPLUG_ENCSIGN_FLAT_SEPARATOR ""
00094
#define GPGMEPLUG_ENCSIGN_FLAT_POSTFIX ""
00095
#endif
00096
00097
#include "cryptplug.h"
00098
#include <kdebug.h>
00099
00100 SMIMECryptPlug::SMIMECryptPlug() : CryptPlug() {
00101 GPGMEPLUG_PROTOCOL = GPGME_PROTOCOL_CMS;
00102 mProtocol = GpgME::Context::CMS;
00103
00104
00105
00106 GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT =
false;
00107 GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT =
true;
00108 GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME =
false;
00109 GPGMEPLUG_OPA_SIGN_CTYPE_MAIN =
"application/pkcs7-mime; smime-type=signed-data; name=\"smime.p7m\"";
00110 GPGMEPLUG_OPA_SIGN_CDISP_MAIN =
"attachment; filename=\"smime.p7m\"";
00111 GPGMEPLUG_OPA_SIGN_CTENC_MAIN =
"base64";
00112 GPGMEPLUG_OPA_SIGN_CTYPE_VERSION =
"";
00113 GPGMEPLUG_OPA_SIGN_CDISP_VERSION =
"";
00114 GPGMEPLUG_OPA_SIGN_CTENC_VERSION =
"";
00115 GPGMEPLUG_OPA_SIGN_BTEXT_VERSION =
"";
00116 GPGMEPLUG_OPA_SIGN_CTYPE_CODE =
"";
00117 GPGMEPLUG_OPA_SIGN_CDISP_CODE =
"";
00118 GPGMEPLUG_OPA_SIGN_CTENC_CODE =
"";
00119 GPGMEPLUG_OPA_SIGN_FLAT_PREFIX =
"";
00120 GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR =
"";
00121 GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX =
"";
00122
00123 GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT =
true;
00124 GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT =
true;
00125 GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME =
true;
00126 GPGMEPLUG_DET_SIGN_CTYPE_MAIN =
"multipart/signed; protocol=\"application/pkcs7-signature\"; micalg=sha1";
00127 GPGMEPLUG_DET_SIGN_CDISP_MAIN =
"";
00128 GPGMEPLUG_DET_SIGN_CTENC_MAIN =
"";
00129 GPGMEPLUG_DET_SIGN_CTYPE_VERSION =
"";
00130 GPGMEPLUG_DET_SIGN_CDISP_VERSION =
"";
00131 GPGMEPLUG_DET_SIGN_CTENC_VERSION =
"";
00132 GPGMEPLUG_DET_SIGN_BTEXT_VERSION =
"";
00133 GPGMEPLUG_DET_SIGN_CTYPE_CODE =
"application/pkcs7-signature; name=\"smime.p7s\"";
00134 GPGMEPLUG_DET_SIGN_CDISP_CODE =
"attachment; filename=\"smime.p7s\"";
00135 GPGMEPLUG_DET_SIGN_CTENC_CODE =
"base64";
00136 GPGMEPLUG_DET_SIGN_FLAT_PREFIX =
"";
00137 GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR =
"";
00138 GPGMEPLUG_DET_SIGN_FLAT_POSTFIX =
"";
00139
00140 __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY =
true;
00141
00142
00143 GPGMEPLUG_ENC_INCLUDE_CLEARTEXT =
false;
00144 GPGMEPLUG_ENC_MAKE_MIME_OBJECT =
true;
00145 GPGMEPLUG_ENC_MAKE_MULTI_MIME =
false;
00146 GPGMEPLUG_ENC_CTYPE_MAIN =
"application/pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\"";
00147 GPGMEPLUG_ENC_CDISP_MAIN =
"attachment; filename=\"smime.p7m\"";
00148 GPGMEPLUG_ENC_CTENC_MAIN =
"base64";
00149 GPGMEPLUG_ENC_CTYPE_VERSION =
"";
00150 GPGMEPLUG_ENC_CDISP_VERSION =
"";
00151 GPGMEPLUG_ENC_CTENC_VERSION =
"";
00152 GPGMEPLUG_ENC_BTEXT_VERSION =
"";
00153 GPGMEPLUG_ENC_CTYPE_CODE =
"";
00154 GPGMEPLUG_ENC_CDISP_CODE =
"";
00155 GPGMEPLUG_ENC_CTENC_CODE =
"";
00156 GPGMEPLUG_ENC_FLAT_PREFIX =
"";
00157 GPGMEPLUG_ENC_FLAT_SEPARATOR =
"";
00158 GPGMEPLUG_ENC_FLAT_POSTFIX =
"";
00159 __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY =
true;
00160 }
00161
00162 OpenPGPCryptPlug::OpenPGPCryptPlug() : CryptPlug() {
00163 GPGMEPLUG_PROTOCOL = GPGME_PROTOCOL_OpenPGP;
00164 mProtocol = GpgME::Context::OpenPGP;
00165
00166
00167
00168 GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT =
false;
00169 GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT =
false;
00170 GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME =
false;
00171 GPGMEPLUG_OPA_SIGN_CTYPE_MAIN =
"";
00172 GPGMEPLUG_OPA_SIGN_CDISP_MAIN =
"";
00173 GPGMEPLUG_OPA_SIGN_CTENC_MAIN =
"";
00174 GPGMEPLUG_OPA_SIGN_CTYPE_VERSION =
"";
00175 GPGMEPLUG_OPA_SIGN_CDISP_VERSION =
"";
00176 GPGMEPLUG_OPA_SIGN_CTENC_VERSION =
"";
00177 GPGMEPLUG_OPA_SIGN_BTEXT_VERSION =
"";
00178 GPGMEPLUG_OPA_SIGN_CTYPE_CODE =
"";
00179 GPGMEPLUG_OPA_SIGN_CDISP_CODE =
"";
00180 GPGMEPLUG_OPA_SIGN_CTENC_CODE =
"";
00181 GPGMEPLUG_OPA_SIGN_FLAT_PREFIX =
"";
00182 GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR =
"";
00183 GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX =
"";
00184
00185 GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT =
true;
00186 GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT =
true;
00187 GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME =
true;
00188 GPGMEPLUG_DET_SIGN_CTYPE_MAIN =
"multipart/signed; protocol=\"application/pgp-signature\"; micalg=pgp-sha1";
00189 GPGMEPLUG_DET_SIGN_CDISP_MAIN =
"";
00190 GPGMEPLUG_DET_SIGN_CTENC_MAIN =
"";
00191 GPGMEPLUG_DET_SIGN_CTYPE_VERSION =
"";
00192 GPGMEPLUG_DET_SIGN_CDISP_VERSION =
"";
00193 GPGMEPLUG_DET_SIGN_CTENC_VERSION =
"";
00194 GPGMEPLUG_DET_SIGN_BTEXT_VERSION =
"";
00195 GPGMEPLUG_DET_SIGN_CTYPE_CODE =
"application/pgp-signature";
00196 GPGMEPLUG_DET_SIGN_CDISP_CODE =
"";
00197 GPGMEPLUG_DET_SIGN_CTENC_CODE =
"";
00198 GPGMEPLUG_DET_SIGN_FLAT_PREFIX =
"";
00199 GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR =
"";
00200 GPGMEPLUG_DET_SIGN_FLAT_POSTFIX =
"";
00201
00202 __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY =
false;
00203
00204
00205 GPGMEPLUG_ENC_INCLUDE_CLEARTEXT =
false;
00206 GPGMEPLUG_ENC_MAKE_MIME_OBJECT =
true;
00207 GPGMEPLUG_ENC_MAKE_MULTI_MIME =
true;
00208 GPGMEPLUG_ENC_CTYPE_MAIN =
"multipart/encrypted; protocol=\"application/pgp-encrypted\"";
00209 GPGMEPLUG_ENC_CDISP_MAIN =
"";
00210 GPGMEPLUG_ENC_CTENC_MAIN =
"";
00211 GPGMEPLUG_ENC_CTYPE_VERSION =
"application/pgp-encrypted";
00212 GPGMEPLUG_ENC_CDISP_VERSION =
"attachment";
00213 GPGMEPLUG_ENC_CTENC_VERSION =
"";
00214 GPGMEPLUG_ENC_BTEXT_VERSION =
"Version: 1";
00215 GPGMEPLUG_ENC_CTYPE_CODE =
"application/octet-stream";
00216 GPGMEPLUG_ENC_CDISP_CODE =
"inline; filename=\"msg.asc\"";
00217 GPGMEPLUG_ENC_CTENC_CODE =
"";
00218 GPGMEPLUG_ENC_FLAT_PREFIX =
"";
00219 GPGMEPLUG_ENC_FLAT_SEPARATOR =
"";
00220 GPGMEPLUG_ENC_FLAT_POSTFIX =
"";
00221 __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY =
false;
00222 }
00223
00224
#define days_from_seconds(x) ((x)/86400)
00225
00226
00227
#define MAX_GPGME_IDX 20
00228
00229
00230
#define spacep(p) (*(p) == ' ' || *(p) == '\t')
00231
#define digitp(p) (*(p) >= '0' && *(p) <= '9')
00232
#define hexdigitp(a) (digitp (a) \
00233
|| (*(a) >= 'A' && *(a) <= 'F') \
00234
|| (*(a) >= 'a' && *(a) <= 'f'))
00235
00236
#define atoi_1(p) (*(p) - '0' )
00237
#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1))
00238
#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2))
00239
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
00240
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
00241
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
00242
00243
static void *
00244 xmalloc (size_t n)
00245 {
00246
void *p = malloc (n);
00247
if (!p)
00248 {
00249 fputs (
"\nfatal: out of core\n", stderr);
00250 exit (4);
00251 }
00252
return p;
00253 }
00254
00255
00256
00257
00258
static char *
00259 xstrdup (
const char *string)
00260 {
00261
char *p = (
char*)xmalloc (strlen (string)+1);
00262 strcpy (p, string);
00263
return p;
00264 }
00265
00266
00267
00268
static void
00269 my_gpgme_key_release (gpgme_key_t key)
00270 {
00271
if (key)
00272 gpgme_key_release (key);
00273 }
00274
00275
00276 CryptPlug::CryptPlug() {
00277 }
00278
00279 CryptPlug::~CryptPlug() {
00280 }
00281
00282
bool CryptPlug::initialize() {
00283 GpgME::setDefaultLocale( LC_CTYPE, setlocale( LC_CTYPE, 0 ) );
00284 GpgME::setDefaultLocale( LC_MESSAGES, setlocale( LC_MESSAGES, 0 ) );
00285
return (gpgme_engine_check_version (GPGMEPLUG_PROTOCOL) == GPG_ERR_NO_ERROR);
00286 };
00287
00288
00289
bool CryptPlug::hasFeature( Feature flag )
00290 {
00291
00292
switch ( flag ) {
00293
case Feature_SignMessages:
00294
case Feature_VerifySignatures:
00295
case Feature_EncryptMessages:
00296
case Feature_DecryptMessages:
00297
case Feature_SendCertificates:
00298
case Feature_PinEntrySettings:
00299
case Feature_StoreMessagesWithSigs:
00300
case Feature_EncryptionCRLs:
00301
case Feature_StoreMessagesEncrypted:
00302
case Feature_CheckCertificatePath:
00303
return true;
00304
case Feature_WarnSignCertificateExpiry:
00305
case Feature_WarnSignEmailNotInCertificate:
00306
case Feature_WarnEncryptCertificateExpiry:
00307
case Feature_WarnEncryptEmailNotInCertificate:
00308
return GPGMEPLUG_PROTOCOL == GPGME_PROTOCOL_CMS;
00309
00310
case Feature_CRLDirectoryService:
00311
case Feature_CertificateDirectoryService:
00312
case Feature_undef:
00313
default:
00314
return false;
00315 }
00316 }
00317
00318
00319
00320
00321
00322
00323
int CryptPlug::interfaceVersion (
int *min_version)
00324 {
00325
if (min_version)
00326 *min_version = 0;
00327
return 1;
00328 }
00329
00330
static
00331
int getAttrExpireFormKey( gpgme_key_t* rKey)
00332 {
00333
int daysLeft = CRYPTPLUG_CERT_DOES_NEVER_EXPIRE;
00334
if ( rKey && *rKey && (*rKey)->subkeys && (*rKey)->subkeys->expires >= 0 ) {
00335 time_t expire_time = (*rKey)->subkeys->expires;
00336 time_t cur_time = time (NULL);
00337
if( cur_time > expire_time ) {
00338 daysLeft = days_from_seconds(cur_time - expire_time);
00339 daysLeft *= -1;
00340 }
00341
else
00342 daysLeft = days_from_seconds(expire_time - cur_time);
00343 }
00344
return daysLeft;
00345 }
00346
00347
00348
static
00349
void storeNewCharPtr(
char** dest,
const char* src )
00350 {
00351
int sLen = strlen( src );
00352 *dest = (
char*)xmalloc( sLen + 1 );
00353 strcpy( *dest, src );
00354 }
00355
00356
00357
bool CryptPlug::signMessage(
const char* cleartext,
00358
char** ciphertext,
00359
const size_t* cipherLen,
00360
const char* certificate,
00361
struct StructuringInfo* structuring,
00362
int* errId,
00363
char** errTxt,
00364 SendCertificates sendCertificates,
00365 SignatureCompoundMode signatureCompoundMode )
00366 {
00367
bool bIsOpaque;
00368 gpgme_ctx_t ctx;
00369 gpgme_error_t err;
00370 gpgme_key_t rKey;
00371 gpgme_data_t data, sig;
00372
char* rSig = 0;
00373
bool bOk =
false;
00374
int sendCerts = 1;
00375
00376 init_StructuringInfo( structuring );
00377
00378
if( !ciphertext )
00379
return false;
00380
00381 err = gpgme_new (&ctx);
00382 gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
00383
00384 gpgme_set_armor (ctx, __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY ? 0 : 1);
00385
00386
00387
switch ( sendCertificates ) {
00388
case SendCert_undef:
00389
break;
00390
case SendCert_DontSend:
00391 sendCerts = 0;
00392
break;
00393
case SendCert_SendOwn:
00394 sendCerts = 1;
00395
break;
00396
case SendCert_SendChainWithoutRoot:
00397 sendCerts = -2;
00398
break;
00399
case SendCert_SendChainWithRoot:
00400 sendCerts = -1;
00401
break;
00402
default:
00403 sendCerts = 0;
00404
break;
00405 }
00406 gpgme_set_include_certs (ctx, sendCerts);
00407
00408
00409
if (certificate != 0) {
00410 err = gpgme_op_keylist_start(ctx, certificate, 0);
00411
while (!err) {
00412 err = gpgme_op_keylist_next(ctx, &rKey);
00413
if (!err) {
00414
if ( rKey && rKey->can_sign ) {
00415
00416 gpgme_signers_clear(ctx);
00417
00418 gpgme_signers_add(ctx, rKey);
00419
00420
break;
00421 }
00422 }
00423 }
00424 gpgme_op_keylist_end(ctx);
00425 }
00426
00427
00428
00429
00430
00431
00432
00433 gpgme_data_new_from_mem (&data, cleartext,
00434 strlen( cleartext ), 1 );
00435 gpgme_data_new ( &sig );
00436
00437
00438
00439
if( GPGMEPLUG_PROTOCOL == GPGME_PROTOCOL_CMS )
00440 bIsOpaque = (signatureCompoundMode == SignatureCompoundMode_Opaque);
00441
else
00442 bIsOpaque =
false;
00443
00444 err = gpgme_op_sign ( ctx,
00445 data,
00446 sig,
00447 bIsOpaque
00448 ? GPGME_SIG_MODE_NORMAL
00449 : GPGME_SIG_MODE_DETACH );
00450
00451
if ( !err ) {
00452
if( __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY ) {
00453 *ciphertext = gpgme_data_release_and_get_mem( sig, (size_t*)cipherLen );
00454 bOk =
true;
00455 }
00456
else {
00457 rSig = gpgme_data_release_and_get_mem( sig, (size_t*)cipherLen );
00458 *ciphertext = (
char*)malloc( *cipherLen + 1 );
00459
if( *ciphertext ) {
00460
if( *cipherLen ) {
00461 bOk =
true;
00462 strncpy((
char*)*ciphertext, rSig, *cipherLen );
00463 }
00464 (*ciphertext)[*cipherLen] =
'\0';
00465 }
00466 free( rSig );
00467 }
00468 }
00469
else {
00470 gpgme_data_release( sig );
00471
00472
00473
00474
00475
00476
00477
00478 *ciphertext = 0;
00479 fprintf( stderr,
"\n\n gpgme_op_sign() returned this error code: %i\n\n", err );
00480
if( errId )
00481 *errId = err;
00482
if( errTxt ) {
00483
const char* _errTxt = gpgme_strerror( err );
00484 *errTxt = (
char*)malloc( strlen( _errTxt ) + 1 );
00485
if( *errTxt )
00486 strcpy(*errTxt, _errTxt );
00487 }
00488
00489
00490
00491 }
00492 gpgme_data_release( data );
00493 gpgme_release (ctx);
00494
00495
if( bOk && structuring ) {
00496
if( bIsOpaque ) {
00497 structuring->includeCleartext = GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT;
00498 structuring->makeMimeObject = GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT;
00499
if( structuring->makeMimeObject ) {
00500 structuring->makeMultiMime = GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME;
00501 storeNewCharPtr( &structuring->contentTypeMain,
00502 GPGMEPLUG_OPA_SIGN_CTYPE_MAIN );
00503 storeNewCharPtr( &structuring->contentDispMain,
00504 GPGMEPLUG_OPA_SIGN_CDISP_MAIN );
00505 storeNewCharPtr( &structuring->contentTEncMain,
00506 GPGMEPLUG_OPA_SIGN_CTENC_MAIN );
00507
if( structuring->makeMultiMime ) {
00508 storeNewCharPtr( &structuring->contentTypeVersion,
00509 GPGMEPLUG_OPA_SIGN_CTYPE_VERSION );
00510 storeNewCharPtr( &structuring->contentDispVersion,
00511 GPGMEPLUG_OPA_SIGN_CDISP_VERSION );
00512 storeNewCharPtr( &structuring->contentTEncVersion,
00513 GPGMEPLUG_OPA_SIGN_CTENC_VERSION );
00514 storeNewCharPtr( &structuring->bodyTextVersion,
00515 GPGMEPLUG_OPA_SIGN_BTEXT_VERSION );
00516 storeNewCharPtr( &structuring->contentTypeCode,
00517 GPGMEPLUG_OPA_SIGN_CTYPE_CODE );
00518 storeNewCharPtr( &structuring->contentDispCode,
00519 GPGMEPLUG_OPA_SIGN_CDISP_CODE );
00520 storeNewCharPtr( &structuring->contentTEncCode,
00521 GPGMEPLUG_OPA_SIGN_CTENC_CODE );
00522 }
00523 }
else {
00524 storeNewCharPtr( &structuring->flatTextPrefix,
00525 GPGMEPLUG_OPA_SIGN_FLAT_PREFIX );
00526 storeNewCharPtr( &structuring->flatTextSeparator,
00527 GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR );
00528 storeNewCharPtr( &structuring->flatTextPostfix,
00529 GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX );
00530 }
00531 }
else {
00532 structuring->includeCleartext = GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT;
00533 structuring->makeMimeObject = GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT;
00534
if( structuring->makeMimeObject ) {
00535 structuring->makeMultiMime = GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME;
00536 storeNewCharPtr( &structuring->contentTypeMain,
00537 GPGMEPLUG_DET_SIGN_CTYPE_MAIN );
00538 storeNewCharPtr( &structuring->contentDispMain,
00539 GPGMEPLUG_DET_SIGN_CDISP_MAIN );
00540 storeNewCharPtr( &structuring->contentTEncMain,
00541 GPGMEPLUG_DET_SIGN_CTENC_MAIN );
00542
if( structuring->makeMultiMime ) {
00543 storeNewCharPtr( &structuring->contentTypeVersion,
00544 GPGMEPLUG_DET_SIGN_CTYPE_VERSION );
00545 storeNewCharPtr( &structuring->contentDispVersion,
00546 GPGMEPLUG_DET_SIGN_CDISP_VERSION );
00547 storeNewCharPtr( &structuring->contentTEncVersion,
00548 GPGMEPLUG_DET_SIGN_CTENC_VERSION );
00549 storeNewCharPtr( &structuring->bodyTextVersion,
00550 GPGMEPLUG_DET_SIGN_BTEXT_VERSION );
00551 storeNewCharPtr( &structuring->contentTypeCode,
00552 GPGMEPLUG_DET_SIGN_CTYPE_CODE );
00553 storeNewCharPtr( &structuring->contentDispCode,
00554 GPGMEPLUG_DET_SIGN_CDISP_CODE );
00555 storeNewCharPtr( &structuring->contentTEncCode,
00556 GPGMEPLUG_DET_SIGN_CTENC_CODE );
00557 }
00558 }
else {
00559 storeNewCharPtr( &structuring->flatTextPrefix,
00560 GPGMEPLUG_DET_SIGN_FLAT_PREFIX );
00561 storeNewCharPtr( &structuring->flatTextSeparator,
00562 GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR );
00563 storeNewCharPtr( &structuring->flatTextPostfix,
00564 GPGMEPLUG_DET_SIGN_FLAT_POSTFIX );
00565 }
00566 }
00567 }
00568
return bOk;
00569 }
00570
00571
00572
00573
bool CryptPlug::storeCertificatesFromMessage(
const char* ){
return true; }
00574
00575
00576
00577
00578
00579
static char* parseAddress(
char* address )
00580 {
00581
char* result = address;
00582
char* i;
00583
char* j;
00584
if( !result )
return result;
00585 i = index( address,
'<' );
00586
if( i ) {
00587 j = index( i+1,
'>' );
00588
if( j == NULL ) j = address+strlen(address);
00589 result = (
char*)xmalloc( j-i );
00590 strncpy( result, i+1, j-i-1 );
00591 result[j-i-1] =
'\0';
00592 free( address );
00593 }
else {
00594 i = address;
00595 j = i+strlen(address);
00596 }
00597 {
00598
00599
char* k = result+(j-i-1);
00600
char* l = result;
00601
while( isspace( *l ) ) ++l;
00602
while( isspace( *k ) ) --k;
00603
if( l != result || k != result+(j-i-1) ) {
00604
char* result2 = (
char*)xmalloc( k-l+2 );
00605 strncpy( result2, l, k-l+1 );
00606 result2[k-l+1] =
'\0';
00607 free(result);
00608 result = result2;
00609 }
00610 }
00611
return result;
00612 }
00613
00614
static char* nextAddress(
const char** address )
00615 {
00616
const char *start = *address;
00617
char* result = NULL;
00618
int quote = 0;
00619
int comment = 0;
00620
int found = 0;
00621
if( *address == NULL )
return NULL;
00622
while( **address ) {
00623
00624
switch( **address ) {
00625
case '\\':
00626 ++(*address);
00627
break;
00628
case '"':
00629
if( comment == 0 ) {
00630
if( quote > 0 ) --quote;
00631
else ++quote;
00632 }
00633
break;
00634
case '(':
00635
if( quote == 0 ) ++comment;
00636
break;
00637
case ')':
00638
if( quote == 0 ) --comment;
00639
break;
00640
case '\0':
00641
case '\1':
00642
if( quote == 0 && comment == 0 ) {
00643 found = 1;
00644 }
00645
break;
00646 }
00647 ++(*address);
00648
if( found )
break;
00649 }
00650
if( found || **address == 0 ) {
00651 size_t len;
00652 len = *address - start;
00653
if( len > 0 ) {
00654
if( **address != 0 ) --len;
00655 result = (
char*)xmalloc( len*
sizeof(
char)+1 );
00656 strncpy( result, start, len );
00657 result[len] =
'\0';
00658 }
00659 }
00660
return parseAddress(result);
00661 }
00662
00663
bool CryptPlug::encryptMessage(
const char* cleartext,
00664
const char** ciphertext,
00665
const size_t* cipherLen,
00666
const char* certificate,
00667
struct StructuringInfo* structuring,
00668
int* errId,
00669
char** errTxt )
00670 {
00671 gpgme_ctx_t ctx;
00672 gpgme_error_t err;
00673 gpgme_data_t gCiphertext, gPlaintext;
00674
char* rCiph = 0;
00675
bool bOk =
false;
00676
00677 init_StructuringInfo( structuring );
00678
00679 gpgme_new (&ctx);
00680 gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
00681
00682 gpgme_set_armor (ctx, __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY ? 0 : 1);
00683
00684
00685 gpgme_data_new_from_mem (&gPlaintext, cleartext,
00686 1+strlen( cleartext ), 1 );
00687 err = gpgme_data_new ( &gCiphertext );
00688
00689
00690 std::vector<char*> recips;
00691
00692 {
00693
const char* p = certificate;
00694
char* tok;
00695
while( (tok = nextAddress( &p ) ) != 0 ) {
00696 fprintf( stderr,
"\nGPGMEPLUG encryptMessage() using addressee %s\n", tok );
00697 recips.push_back( tok );
00698 }
00699 }
00700
00701 recips.push_back( 0 );
00702
const char ** patterns =
new const char*[ recips.size() ];
00703
const char ** patterns_it = patterns;
00704 std::copy( recips.begin(), recips.end(), patterns_it );
00705 recips.pop_back();
00706
00707 std::vector<gpgme_key_t> keys;
00708
#if 0 // BROKEN FOR FINGERPRINTS
00709
err = gpgme_op_keylist_ext_start( ctx, patterns, 0, 0 );
00710
while ( !err ) {
00711 gpgme_key_t key = 0;
00712 err = gpgme_op_keylist_next( ctx, &key );
00713 keys.push_back( key );
00714 }
00715
if ( gpg_err_code( err ) == GPG_ERR_EOF )
00716 err = GPG_ERR_NO_ERROR;
00717 gpgme_op_keylist_end( ctx );
00718
#else
00719
for (
const char ** pit = patterns ; *pit && !err ; ++pit ) {
00720 gpgme_key_t key = 0;
00721 err = gpgme_get_key( ctx, *pit, &key,
false );
00722
if ( key )
00723 keys.push_back( key );
00724 }
00725
#endif
00726
00727 keys.push_back( 0 );
00728 gpgme_key_t * rset =
new gpgme_key_t[ keys.size() ];
00729 gpgme_key_t * rset_it = rset;
00730 std::copy( keys.begin(), keys.end(), rset_it );
00731 keys.pop_back();
00732
00733 std::for_each( recips.begin(), recips.end(), &free );
00734
delete[] patterns;
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
if ( !err )
00760 err = gpgme_op_encrypt (ctx, rset, (gpgme_encrypt_flags_t)0, gPlaintext, gCiphertext );
00761
if( err ) {
00762 fprintf( stderr,
"\ngpgme_op_encrypt() returned this error code: %i\n", err );
00763
if( errId )
00764 *errId = err;
00765
if( errTxt ) {
00766
const char* _errTxt = gpgme_strerror( err );
00767
const size_t errTxtLen = strlen( _errTxt ) + 100;
00768 *errTxt = (
char*)malloc( errTxtLen + 1 );
00769
if( *errTxt ) {
00770 std::string str = _errTxt;
00771 gpgme_encrypt_result_t opInfo = gpgme_op_encrypt_result( ctx );
00772
if ( opInfo && opInfo->invalid_recipients ) {
00773 str +=
" - ";
00774 str += gpgme_strerror( opInfo->invalid_recipients->reason );
00775
00776 }
00777 strncmp( *errTxt, str.c_str(), errTxtLen );
00778 (*errTxt)[errTxtLen] =
'\0';
00779 }
00780 }
00781 }
00782
00783 std::for_each( keys.begin(), keys.end(), &my_gpgme_key_release );
00784
delete[] rset;
00785 gpgme_data_release (gPlaintext);
00786
00787
if( !err ) {
00788
if( __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY ) {
00789 *ciphertext = gpgme_data_release_and_get_mem( gCiphertext, (size_t*)cipherLen );
00790 bOk =
true;
00791 }
00792
else {
00793 rCiph = gpgme_data_release_and_get_mem( gCiphertext, (size_t*)cipherLen );
00794 *ciphertext = (
char*)malloc( *cipherLen + 1 );
00795
if( *ciphertext ) {
00796
if( *cipherLen ) {
00797 bOk =
true;
00798 strncpy((
char*)*ciphertext, rCiph, *cipherLen );
00799 }
00800 ((
char*)(*ciphertext))[*cipherLen] = 0;
00801 }
00802 free( rCiph );
00803 }
00804 }
00805
else {
00806 gpgme_data_release ( gCiphertext );
00807 *ciphertext = 0;
00808
00809
00810
00811
00812
00813 }
00814
00815 gpgme_release (ctx);
00816
00817 fflush( stderr );
00818
00819
if( bOk && structuring ) {
00820 structuring->includeCleartext = GPGMEPLUG_ENC_INCLUDE_CLEARTEXT;
00821 structuring->makeMimeObject = GPGMEPLUG_ENC_MAKE_MIME_OBJECT;
00822
if( structuring->makeMimeObject ) {
00823 structuring->makeMultiMime = GPGMEPLUG_ENC_MAKE_MULTI_MIME;
00824 storeNewCharPtr( &structuring->contentTypeMain,
00825 GPGMEPLUG_ENC_CTYPE_MAIN );
00826 storeNewCharPtr( &structuring->contentDispMain,
00827 GPGMEPLUG_ENC_CDISP_MAIN );
00828 storeNewCharPtr( &structuring->contentTEncMain,
00829 GPGMEPLUG_ENC_CTENC_MAIN );
00830
if( structuring->makeMultiMime ) {
00831 storeNewCharPtr( &structuring->contentTypeVersion,
00832 GPGMEPLUG_ENC_CTYPE_VERSION );
00833 storeNewCharPtr( &structuring->contentDispVersion,
00834 GPGMEPLUG_ENC_CDISP_VERSION );
00835 storeNewCharPtr( &structuring->contentTEncVersion,
00836 GPGMEPLUG_ENC_CTENC_VERSION );
00837 storeNewCharPtr( &structuring->bodyTextVersion,
00838 GPGMEPLUG_ENC_BTEXT_VERSION );
00839 storeNewCharPtr( &structuring->contentTypeCode,
00840 GPGMEPLUG_ENC_CTYPE_CODE );
00841 storeNewCharPtr( &structuring->contentDispCode,
00842 GPGMEPLUG_ENC_CDISP_CODE );
00843 storeNewCharPtr( &structuring->contentTEncCode,
00844 GPGMEPLUG_ENC_CTENC_CODE );
00845 }
00846 }
else {
00847 storeNewCharPtr( &structuring->flatTextPrefix,
00848 GPGMEPLUG_ENC_FLAT_PREFIX );
00849 storeNewCharPtr( &structuring->flatTextSeparator,
00850 GPGMEPLUG_ENC_FLAT_SEPARATOR );
00851 storeNewCharPtr( &structuring->flatTextPostfix,
00852 GPGMEPLUG_ENC_FLAT_POSTFIX );
00853 }
00854 }
00855
return bOk;
00856 }
00857
00858
00859
bool CryptPlug::encryptAndSignMessage(
const char* ,
00860
const char** ,
00861
const char* ,
00862
struct StructuringInfo* structuring )
00863 {
00864
bool bOk;
00865
00866 init_StructuringInfo( structuring );
00867
00868 bOk =
false;
00869
00870
00871
00872
if( bOk && structuring ) {
00873 structuring->includeCleartext = GPGMEPLUG_ENCSIGN_INCLUDE_CLEARTEXT;
00874 structuring->makeMimeObject = GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT;
00875
if( structuring->makeMimeObject ) {
00876 structuring->makeMultiMime = GPGMEPLUG_ENCSIGN_MAKE_MULTI_MIME;
00877 storeNewCharPtr( &structuring->contentTypeMain,
00878 GPGMEPLUG_ENCSIGN_CTYPE_MAIN );
00879 storeNewCharPtr( &structuring->contentDispMain,
00880 GPGMEPLUG_ENCSIGN_CDISP_MAIN );
00881 storeNewCharPtr( &structuring->contentTEncMain,
00882 GPGMEPLUG_ENCSIGN_CTENC_MAIN );
00883
if( structuring->makeMultiMime ) {
00884 storeNewCharPtr( &structuring->contentTypeVersion,
00885 GPGMEPLUG_ENCSIGN_CTYPE_VERSION );
00886 storeNewCharPtr( &structuring->contentDispVersion,
00887 GPGMEPLUG_ENCSIGN_CDISP_VERSION );
00888 storeNewCharPtr( &structuring->contentTEncVersion,
00889 GPGMEPLUG_ENCSIGN_CTENC_VERSION );
00890 storeNewCharPtr( &structuring->bodyTextVersion,
00891 GPGMEPLUG_ENCSIGN_BTEXT_VERSION );
00892 storeNewCharPtr( &structuring->contentTypeCode,
00893 GPGMEPLUG_ENCSIGN_CTYPE_CODE );
00894 storeNewCharPtr( &structuring->contentDispCode,
00895 GPGMEPLUG_ENCSIGN_CDISP_CODE );
00896 storeNewCharPtr( &structuring->contentTEncCode,
00897 GPGMEPLUG_ENCSIGN_CTENC_CODE );
00898 }
00899 }
else {
00900 storeNewCharPtr( &structuring->flatTextPrefix,
00901 GPGMEPLUG_ENCSIGN_FLAT_PREFIX );
00902 storeNewCharPtr( &structuring->flatTextSeparator,
00903 GPGMEPLUG_ENCSIGN_FLAT_SEPARATOR );
00904 storeNewCharPtr( &structuring->flatTextPostfix,
00905 GPGMEPLUG_ENCSIGN_FLAT_POSTFIX );
00906 }
00907 }
00908
return bOk;
00909 }
00910
00911
00912
bool CryptPlug::decryptMessage(
const char* ciphertext,
00913
bool cipherIsBinary,
00914
int cipherLen,
00915
const char** cleartext,
00916
const char* ,
00917
int* errId,
00918
char** errTxt )
00919 {
00920 gpgme_ctx_t ctx;
00921 gpgme_error_t err;
00922 gpgme_data_t gCiphertext, gPlaintext;
00923 size_t rCLen = 0;
00924
char* rCiph = 0;
00925
bool bOk =
false;
00926
00927
if( !ciphertext )
00928
return false;
00929
00930 err = gpgme_new (&ctx);
00931 gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
00932
00933 gpgme_set_armor (ctx, cipherIsBinary ? 0 : 1);
00934
00935
00936
00937
00938
00939 gpgme_data_new_from_mem( &gCiphertext,
00940 ciphertext,
00941 cipherIsBinary
00942 ? cipherLen
00943 : strlen( ciphertext ),
00944 1 );
00945
00946 gpgme_data_new( &gPlaintext );
00947
00948 err = gpgme_op_decrypt( ctx, gCiphertext, gPlaintext );
00949
if( err ) {
00950 fprintf( stderr,
"\ngpgme_op_decrypt() returned this error code: %i\n\n", err );
00951
if( errId )
00952 *errId = err;
00953
if( errTxt ) {
00954
const char* _errTxt = gpgme_strerror( err );
00955 *errTxt = (
char*)malloc( strlen( _errTxt ) + 1 );
00956
if( *errTxt )
00957 strcpy(*errTxt, _errTxt );
00958 }
00959 }
00960
00961 gpgme_data_release( gCiphertext );
00962
00963 rCiph = gpgme_data_release_and_get_mem( gPlaintext, &rCLen );
00964
00965 *cleartext = (
char*)malloc( rCLen + 1 );
00966
if( *cleartext ) {
00967
if( rCLen ) {
00968 bOk =
true;
00969 strncpy((
char*)*cleartext, rCiph, rCLen );
00970 }
00971 ((
char*)(*cleartext))[rCLen] = 0;
00972 }
00973
00974 free( rCiph );
00975 gpgme_release( ctx );
00976
return bOk;
00977 }
00978
00979
00980
static char *
00981 trim_trailing_spaces(
char *string )
00982 {
00983
char *p, *mark;
00984
00985
for( mark = NULL, p = string; *p; p++ ) {
00986
if( isspace( *p ) ) {
00987
if( !mark )
00988 mark = p;
00989 }
00990
else
00991 mark = NULL;
00992 }
00993
if( mark )
00994 *mark =
'\0' ;
00995
00996
return string ;
00997 }
00998
00999
01000
01001
01002
static const unsigned char *
01003 parse_dn_part (CryptPlug::DnPair *array,
const unsigned char *string)
01004 {
01005
const unsigned char *s, *s1;
01006 size_t n;
01007
char *p;
01008
01009
01010
for (s = string+1; *s && *s !=
'='; s++)
01011 ;
01012
if (!*s)
01013
return NULL;
01014 n = s - string;
01015
if (!n)
01016
return NULL;
01017 p = (
char*)xmalloc (n+1);
01018
01019
01020 memcpy (p, string, n);
01021 p[n] = 0;
01022 trim_trailing_spaces ((
char*)p);
01023
01024
for (
unsigned int i = 0 ; i < numOidMaps ; ++i )
01025
if ( !strcasecmp ((
char*)p, oidmap[i].oid) ) {
01026 free( p );
01027 p = xstrdup (oidmap[i].name);
01028
break;
01029 }
01030 array->key = p;
01031 string = s + 1;
01032
01033
if (*string ==
'#')
01034 {
01035 string++;
01036
for (s=string; hexdigitp (s); s++)
01037 s++;
01038 n = s - string;
01039
if (!n || (n & 1))
01040
return NULL;
01041 n /= 2;
01042 array->value = p = (
char*)xmalloc (n+1);
01043
01044
01045
for (s1=string; n; s1 += 2, n--)
01046 *p++ = xtoi_2 (s1);
01047 *p = 0;
01048 }
01049
else
01050 {
01051
for (n=0, s=string; *s; s++)
01052 {
01053
if (*s ==
'\\')
01054 {
01055 s++;
01056
if (*s ==
',' || *s ==
'=' || *s ==
'+'
01057 || *s ==
'<' || *s ==
'>' || *s ==
'#' || *s ==
';'
01058 || *s ==
'\\' || *s ==
'\"' || *s ==
' ')
01059 n++;
01060
else if (hexdigitp (s) && hexdigitp (s+1))
01061 {
01062 s++;
01063 n++;
01064 }
01065
else
01066
return NULL;
01067 }
01068
else if (*s ==
'\"')
01069
return NULL;
01070
else if (*s ==
',' || *s ==
'=' || *s ==
'+'
01071 || *s ==
'<' || *s ==
'>' || *s ==
'#' || *s ==
';' )
01072
break;
01073
else
01074 n++;
01075 }
01076
01077 array->value = p = (
char*)xmalloc (n+1);
01078
01079
01080
for (s=string; n; s++, n--)
01081 {
01082
if (*s ==
'\\')
01083 {
01084 s++;
01085
if (hexdigitp (s))
01086 {
01087 *p++ = xtoi_2 (s);
01088 s++;
01089 }
01090
else
01091 *p++ = *s;
01092 }
01093
else
01094 *p++ = *s;
01095 }
01096 *p = 0;
01097 }
01098
return s;
01099 }
01100
01101
01102
01103
01104
01105
static CryptPlug::DnPair *
01106 parse_dn (
const unsigned char *string)
01107 {
01108
struct CryptPlug::DnPair *array;
01109 size_t arrayidx, arraysize;
01110
01111
if( !string )
01112
return NULL;
01113
01114 arraysize = 7;
01115 arrayidx = 0;
01116 array = (CryptPlug::DnPair*)xmalloc ((arraysize+1) *
sizeof *array);
01117
01118
01119
while (*string)
01120 {
01121
while (*string ==
' ')
01122 string++;
01123
if (!*string)
01124
break;
01125
if (arrayidx >= arraysize)
01126 {
01127
struct CryptPlug::DnPair *a2;
01128
01129 arraysize += 5;
01130 a2 = (CryptPlug::DnPair*)xmalloc ((arraysize+1) *
sizeof *array);
01131
for (
unsigned int i=0; i < arrayidx; i++)
01132 {
01133 a2[i].key = array[i].key;
01134 a2[i].value = array[i].value;
01135 }
01136 free (array);
01137 array = a2;
01138 }
01139 array[arrayidx].key = NULL;
01140 array[arrayidx].value = NULL;
01141 string = parse_dn_part (array+arrayidx, string);
01142 arrayidx++;
01143
if (!string)
01144
goto failure;
01145
while (*string ==
' ')
01146 string++;
01147
if (*string && *string !=
',' && *string !=
';' && *string !=
'+')
01148
goto failure;
01149
if (*string)
01150 string++;
01151 }
01152 array[arrayidx].key = NULL;
01153 array[arrayidx].value = NULL;
01154
return array;
01155
01156 failure:
01157
for (
unsigned i=0; i < arrayidx; i++)
01158 {
01159 free (array[i].key);
01160 free (array[i].value);
01161 }
01162 free (array);
01163
return NULL;
01164 }
01165
01166
static void
01167 add_dn_part(
QCString& result,
struct CryptPlug::DnPair& dnPair )
01168 {
01169
01170
QCString mappedPart( dnPair.key );
01171
for (
unsigned int i = 0 ; i < numOidMaps ; ++i ){
01172
if( !strcasecmp( dnPair.key, oidmap[i].oid ) ) {
01173 mappedPart = oidmap[i].name;
01174
break;
01175 }
01176 }
01177 result.append( mappedPart );
01178 result.append(
"=" );
01179 result.append( dnPair.value );
01180 }
01181
01182
static int
01183 add_dn_parts(
QCString& result,
struct CryptPlug::DnPair* dn,
const char* part )
01184 {
01185
int any = 0;
01186
01187
if( dn ) {
01188
for(; dn->key; ++dn ) {
01189
if( !strcmp( dn->key, part ) ) {
01190
if( any )
01191 result.append(
"," );
01192 add_dn_part( result, *dn );
01193 any = 1;
01194 }
01195 }
01196 }
01197
return any;
01198 }
01199
01200
static char*
01201 reorder_dn(
struct CryptPlug::DnPair *dn,
01202
char** attrOrder = 0,
01203
const char* unknownAttrsHandling = 0 )
01204 {
01205
struct CryptPlug::DnPair *dnOrg = dn;
01206
01207
01208
const char* defaultpart[] = {
01209
"CN",
"S",
"SN",
"GN",
"T",
"UID",
01210
"MAIL",
"EMAIL",
"MOBILE",
"TEL",
"FAX",
"STREET",
01211
"L",
"PC",
"SP",
"ST",
01212
"OU",
01213
"O",
01214
"C",
01215 NULL
01216 };
01217
const char** stdpart = attrOrder ? ((
const char**)attrOrder) : defaultpart;
01218
int any=0, any2=0, found_X_=0, i;
01219
QCString result;
01220
QCString resultUnknowns;
01221
01222
01223
if( dn ){
01224
for(; dn->key; ++dn ) {
01225
for( i = 0; stdpart[i]; ++i ) {
01226
if( !strcmp( dn->key, stdpart[i] ) ) {
01227
break;
01228 }
01229 }
01230
if( !stdpart[i] ) {
01231
if( any2 )
01232 resultUnknowns.append(
"," );
01233 add_dn_part( resultUnknowns, *dn );
01234 any2 = 1;
01235 }
01236 }
01237 dn = dnOrg;
01238 }
01239
01240
01241
if( unknownAttrsHandling &&
01242 !strcmp(unknownAttrsHandling,
"PREFIX")
01243 && *resultUnknowns ){
01244 result.append( resultUnknowns );
01245 any = 1;
01246 }
else{
01247 any = 0;
01248 }
01249
01250
01251
for( i = 0; stdpart[i]; ++i ) {
01252 dn = dnOrg;
01253
if( any ) {
01254 result.append(
"," );
01255 }
01256
if( any2 &&
01257 !strcmp(stdpart[i],
"_X_") &&
01258 unknownAttrsHandling &&
01259 !strcmp(unknownAttrsHandling,
"INFIX") ){
01260
if ( !resultUnknowns.isEmpty() ) {
01261 result.append( resultUnknowns );
01262 any = 1;
01263 }
01264 found_X_ = 1;
01265 }
else{
01266 any = add_dn_parts( result, dn, stdpart[i] );
01267 }
01268 }
01269
01270
01271
if( !unknownAttrsHandling ||
01272 !strcmp(unknownAttrsHandling,
"POSTFIX") ||
01273 ( !strcmp(unknownAttrsHandling,
"INFIX") && !found_X_ ) ){
01274
if( !resultUnknowns.isEmpty() ) {
01275
if( any ){
01276 result.append(
"," );
01277 }
01278 result.append( resultUnknowns );
01279 }
01280 }
01281
01282
char* cResult = (
char*)xmalloc( (result.length()+1)*
sizeof(
char) );
01283
if( result.isEmpty() )
01284 *cResult = 0;
01285
else
01286 strcpy( cResult, result );
01287
return cResult;
01288 }
01289
01290
struct CryptPlug::CertIterator {
01291 gpgme_ctx_t ctx;
01292
struct CertificateInfo info;
01293 };
01294
01295 CryptPlug::CertIterator*
01296 CryptPlug::startListCertificates(
const char* pattern,
int remote )
01297 {
01298 gpgme_error_t err;
01299
struct CertIterator* it;
01300
const char* patterns[] = { pattern, NULL };
01301 fprintf( stderr,
"startListCertificates( \"%s\", %d )\n", pattern, remote );
01302
01303 it = (CertIterator*)xmalloc(
sizeof(
struct CertIterator ) );
01304
01305 err = gpgme_new (&(it->ctx));
01306
01307
if( err ) {
01308 free( it );
01309
return NULL;
01310 }
01311
01312 gpgme_set_protocol (it->ctx, GPGME_PROTOCOL_CMS);
01313
if( remote ) gpgme_set_keylist_mode ( it->ctx, GPGME_KEYLIST_MODE_EXTERN );
01314
else gpgme_set_keylist_mode ( it->ctx, GPGME_KEYLIST_MODE_LOCAL );
01315 err = gpgme_op_keylist_ext_start ( it->ctx, patterns, 0, 0);
01316 memset( &(it->info), 0,
sizeof(
struct CertificateInfo ) );
01317
if( err ) {
01318 fprintf( stderr,
"gpgme_op_keylist_ext_start returned %d", err );
01319 endListCertificates( it );
01320
return NULL;
01321 }
01322
return it;
01323 }
01324
01325
01326
static void
01327 freeStringArray(
char** c )
01328 {
01329
char** _c = c;
01330
01331
while( c && *c ) {
01332
01333 free( *c );
01334 ++c;
01335 }
01336 free( _c );
01337 }
01338
01339
01340
static void
01341 freeInfo(
struct CryptPlug::CertificateInfo* info )
01342 {
01343
struct CryptPlug::DnPair* a = info->dnarray;
01344 assert( info );
01345 freeStringArray( info->userid );
01346 free( info->serial);
01347 free( info->fingerprint );
01348 free( info->issuer_org );
01349 free( info->issuer_reord );
01350 free( info->chainid );
01351 free( info->caps );
01352
while( a && a->key && a->value ) {
01353 free (a->key);
01354 free (a->value);
01355 ++a;
01356 }
01357 free (info->dnarray);
01358 memset( info, 0,
sizeof( *info ) );
01359 }
01360
01361
01362
01363
static char* make_fingerprint(
const char* fpr )
01364 {
01365
int len = strlen(fpr);
01366
int i = 0;
01367
char* result = (
char*)xmalloc( (len + len/2 + 1)*
sizeof(
char) );
01368
01369
for(; *fpr; ++fpr, ++i ) {
01370
if( i%3 == 2) {
01371 result[i] =
':'; ++i;
01372 }
01373 result[i] = *fpr;
01374 }
01375 result[i] = 0;
01376
return result;
01377 }
01378
01379
01380
static const char *
01381 capabilities_to_string (gpgme_subkey_t subkey)
01382 {
01383
static const char *
const strings[8] =
01384 {
01385
"",
01386
"c",
01387
"s",
01388
"sc",
01389
"e",
01390
"ec",
01391
"es",
01392
"esc"
01393 };
01394
return strings[(!!subkey->can_encrypt << 2)
01395 | (!!subkey->can_sign << 1)
01396 | (!!subkey->can_certify)];
01397 }
01398
01399
int
01400 CryptPlug::nextCertificate( CryptPlug::CertIterator* it,
01401 CryptPlug::CertificateInfo** result,
01402
char** attrOrder,
01403
const char* unknownAttrsHandling )
01404 {
01405 gpgme_error_t err;
01406 gpgme_key_t key;
01407
int retval = GPG_ERR_NO_ERROR;
01408 assert( it );
01409 fprintf( stderr,
"nextCertificates( %p, %p )\n", it, result );
01410 err = gpgme_op_keylist_next ( it->ctx, &key);
01411
if( !err ) {
01412
int idx;
01413
const char* s = 0;
01414
unsigned long u;
01415
char* names[MAX_GPGME_IDX+1];
01416
struct DnPair *issuer_dn, *tmp_dn;
01417 retval = err;
01418 memset( names, 0,
sizeof( names ) );
01419 freeInfo( &(it->info) );
01420
01421 std::cerr <<
"nextCertificate..." << std::endl;
01422
if ( key ) {
01423 idx = 0;
01424
for ( gpgme_user_id_t uid = key->uids ; uid && idx < MAX_GPGME_IDX ; uid = uid->next, ++idx )
01425 names[idx] = xstrdup( uid->uid );
01426 }
01427 std::cerr <<
"DEBUG: " << s <<
":" << names[0] << std::endl;
01428 it->info.userid = (
char**)xmalloc(
sizeof(
char* ) * (idx+1) );
01429 memset( it->info.userid, 0,
sizeof(
char* ) * (idx+1) );
01430 it->info.dnarray = 0;
01431
for( idx = 0; names[idx] != 0; ++idx ) {
01432
01433
struct DnPair* a = parse_dn( (
unsigned char*)names[idx] );
01434 it->info.userid[idx] = reorder_dn( a, attrOrder, unknownAttrsHandling );
01435
01436
if( idx == 0 ) {
01437 it->info.userid_0_org = names[idx];
01438 it->info.dnarray = a;
01439 }
else{
01440 free (names[idx]);
01441 names[idx] = NULL;
01442
while( a && a->key && a->value ) {
01443 free( a->key );
01444 free( a->value );
01445 ++a;
01446 }
01447 }
01448 }
01449 it->info.userid[idx] = 0;
01450
01451 s = key->issuer_serial;
01452 it->info.serial = s? xstrdup(s) : NULL;
01453
01454 s = key->subkeys ? key->subkeys->fpr : 0 ;
01455 it->info.fingerprint = make_fingerprint( s );
01456
01457 s = key->issuer_name;
01458 it->info.issuer_org = s? xstrdup(s): NULL;
01459
if( s ) {
01460 issuer_dn = tmp_dn = parse_dn( (
const unsigned char*)s );
01461
01462 it->info.issuer_reord = reorder_dn( issuer_dn, attrOrder, unknownAttrsHandling );
01463
while( tmp_dn && tmp_dn->key ) {
01464 free( tmp_dn->key );
01465 free( tmp_dn->value );
01466 ++tmp_dn;
01467 }
01468 free( issuer_dn );
01469 issuer_dn = tmp_dn = NULL;
01470 }
else {
01471 it->info.issuer_reord = NULL;
01472 }
01473 s = key->chain_id;
01474 it->info.chainid = s? xstrdup(s): NULL;
01475
01476 s = key->subkeys ? capabilities_to_string( key->subkeys ) : 0 ;
01477 it->info.caps = s? xstrdup(s) : NULL;
01478
01479 u = key->subkeys && key->subkeys->timestamp >= 0 ? key->subkeys->timestamp : 0 ;
01480 it->info.created = u;
01481
01482 u = key->subkeys && key->subkeys->expires >= 0 ? key->subkeys->expires : 0 ;
01483 it->info.expire = u;
01484
01485 u = key->secret;
01486 it->info.secret = u;
01487
01488 u = key->uids ? key->uids->invalid : 0 ;
01489 it->info.invalid = u;
01490
01491 u = key->subkeys ? key->subkeys->expired : 0 ;
01492 it->info.expired = u;
01493
01494 u = key->subkeys ? key->subkeys->disabled : 0 ;
01495 it->info.disabled = u;
01496
01497 my_gpgme_key_release (key);
01498
01499 *result = &(it->info);
01500 }
else {
01501 *result = NULL;
01502 }
01503
return retval;
01504 }
01505
01506
int
01507 CryptPlug::endListCertificates( CryptPlug::CertIterator* it )
01508 {
01509 fprintf( stderr,
"endListCertificates( %p )\n", it );
01510 assert(it);
01511 gpgme_keylist_result_t result = gpgme_op_keylist_result( it->ctx );
01512
int truncated = result && result->truncated;
01513 freeInfo( &(it->info) );
01514 gpgme_op_keylist_end(it->ctx);
01515 gpgme_release (it->ctx);
01516 free( it );
01517
return truncated;
01518 }
01519
01520 GpgME::ImportResult CryptPlug::importCertificateFromMem(
const char* data, size_t length )
01521 {
01522
using namespace GpgME;
01523
01524 std::auto_ptr<Context> context( Context::createForProtocol( mProtocol ) );
01525
if ( !context.get() )
01526
return ImportResult();
01527
01528 Data keydata( data, length,
false );
01529
if ( keydata.isNull() )
01530
return ImportResult();
01531
01532
return context->importKeys( keydata );
01533 }
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
bool CryptPlug::findCertificates(
const char* addressee,
01552
char** certificates,
01553
int* newSize,
01554
bool secretOnly,
01555
char** attrOrder,
01556
const char* unknownAttrsHandling )
01557 {
01558
#define MAXCERTS 1024
01559
01560
const char* delimiter =
"\1";
01561
const char* openBracket =
" (";
01562
const char* closeBracket =
")";
01563
01564 gpgme_ctx_t ctx;
01565 gpgme_error_t err;
01566 gpgme_key_t rKey;
01567
const char *s;
01568
const char *s2;
01569
char* dn;
01570
struct DnPair* a;
01571
int nFound = 0;
01572
int iFound = 0;
01573
int siz = 0;
01574
char* DNs[MAXCERTS];
01575
char* FPRs[MAXCERTS];
01576
01577
if( ! certificates ){
01578 fprintf( stderr,
"gpgme: findCertificates called with invalid *certificates pointer\n" );
01579
return false;
01580 }
01581
01582
if( ! newSize ){
01583 fprintf( stderr,
"gpgme: findCertificates called with invalid newSize pointer\n" );
01584
return false;
01585 }
01586
01587 *certificates = 0;
01588 *newSize = 0;
01589
01590
01591 gpgme_new (&ctx);
01592 gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
01593 err = gpgme_op_keylist_start(ctx, addressee, secretOnly ? 1 : 0);
01594
while( !err ) {
01595 err = gpgme_op_keylist_next(ctx, &rKey);
01596
if( !err ) {
01597 s = rKey && rKey->uids ? rKey->uids->uid : 0 ;
01598
if( s ) {
01599 dn = xstrdup( s );
01600 s2 = rKey && rKey->subkeys ? rKey->subkeys->fpr : 0 ;
01601
if( s2 ) {
01602
if( nFound )
01603 siz += strlen( delimiter );
01604
01605
01606
01607 a = parse_dn( (
unsigned char*)dn );
01608 free( dn );
01609 dn = reorder_dn( a, attrOrder, unknownAttrsHandling );
01610
01611
01612
01613 siz += strlen( dn );
01614 siz += strlen( openBracket );
01615 siz += strlen( s2 );
01616 siz += strlen( closeBracket );
01617 DNs[ nFound ] = dn;
01618 dn = NULL;
01619 FPRs[nFound ] = xstrdup( s2 );
01620 ++nFound;
01621
if( nFound >= MAXCERTS ) {
01622 fprintf( stderr,
01623
"gpgme: findCertificates found too many certificates (%d)\n",
01624 MAXCERTS );
01625
break;
01626 }
01627 }
01628 free (dn);
01629 }
01630 }
01631 }
01632 gpgme_op_keylist_end( ctx );
01633 gpgme_release (ctx);
01634
01635
01636
if( 0 < siz ) {
01637
01638 ++siz;
01639 *newSize = siz;
01640
01641 *certificates = (
char*)xmalloc(
sizeof(
char) * siz );
01642 memset( *certificates, 0,
sizeof(
char) * siz );
01643
01644
for (iFound=0; iFound < nFound; iFound++) {
01645
if( !iFound )
01646 strcpy(*certificates, DNs[iFound] );
01647
else {
01648 strcat(*certificates, delimiter );
01649 strcat(*certificates, DNs[iFound] );
01650 }
01651 strcat( *certificates, openBracket );
01652 strcat( *certificates, FPRs[iFound] );
01653 strcat( *certificates, closeBracket );
01654 free( DNs[ iFound ] );
01655 free( FPRs[iFound ] );
01656 }
01657 }
01658
01659
return ( 0 < nFound );
01660 }
01661
01662
01663
static gpgme_sig_stat_t
01664 sig_stat_from_status( gpgme_error_t err )
01665 {
01666
switch ( gpg_err_code(err) ) {
01667
case GPG_ERR_NO_ERROR:
01668
return GPGME_SIG_STAT_GOOD;
01669
case GPG_ERR_BAD_SIGNATURE:
01670
return GPGME_SIG_STAT_BAD;
01671
case GPG_ERR_NO_PUBKEY:
01672
return GPGME_SIG_STAT_NOKEY;
01673
case GPG_ERR_NO_DATA:
01674
return GPGME_SIG_STAT_NOSIG;
01675
case GPG_ERR_SIG_EXPIRED:
01676
return GPGME_SIG_STAT_GOOD_EXP;
01677
case GPG_ERR_KEY_EXPIRED:
01678
return GPGME_SIG_STAT_GOOD_EXPKEY;
01679
default:
01680
return GPGME_SIG_STAT_ERROR;
01681 }
01682 }
01683
01684
01685
static gpgme_sig_stat_t
01686 intersect_stati( gpgme_signature_t first )
01687 {
01688
if ( !first )
01689
return GPGME_SIG_STAT_NONE;
01690 gpgme_sig_stat_t result = sig_stat_from_status( first->status );
01691
for ( gpgme_signature_t sig = first->next ; sig ; sig = sig->next )
01692
if ( sig_stat_from_status( sig->status ) != result )
01693
return GPGME_SIG_STAT_DIFF;
01694
return result;
01695 }
01696
01697
static const char*
01698 sig_status_to_string( gpgme_sig_stat_t status )
01699 {
01700
const char *result;
01701
01702
switch (status) {
01703
case GPGME_SIG_STAT_NONE:
01704 result =
"Oops: Signature not verified";
01705
break;
01706
case GPGME_SIG_STAT_NOSIG:
01707 result =
"No signature found";
01708
break;
01709
case GPGME_SIG_STAT_GOOD:
01710 result =
"Good signature";
01711
break;
01712
case GPGME_SIG_STAT_BAD:
01713 result =
"BAD signature";
01714
break;
01715
case GPGME_SIG_STAT_NOKEY:
01716 result =
"No public key to verify the signature";
01717
break;
01718
case GPGME_SIG_STAT_ERROR:
01719 result =
"Error verifying the signature";
01720
break;
01721
case GPGME_SIG_STAT_DIFF:
01722 result =
"Different results for signatures";
01723
break;
01724
default:
01725 result =
"Error: Unknown status";
01726
break;
01727 }
01728
01729
return result;
01730 }
01731
01732
01733
01734
static
01735
void obtain_signature_information( gpgme_ctx_t ctx,
01736 gpgme_sig_stat_t & overallStatus,
01737
struct CryptPlug::SignatureMetaData* sigmeta,
01738
char** attrOrder,
01739
const char* unknownAttrsHandling,
01740
bool * signatureFound=0 )
01741 {
01742 gpgme_error_t err;
01743
unsigned long sumGPGME;
01744 SigStatusFlags sumPlug;
01745
struct CryptPlug::DnPair* a;
01746
int sig_idx=0;
01747
01748 assert( ctx );
01749 assert( sigmeta );
01750
01751 sigmeta->extended_info = 0;
01752 gpgme_verify_result_t result = gpgme_op_verify_result( ctx );
01753
if ( !result )
01754
return;
01755
for ( gpgme_signature_t signature = result->signatures ; signature ; signature = signature->next, ++sig_idx ) {
01756
void* alloc_return = realloc( sigmeta->extended_info,
01757
sizeof( CryptPlug::SignatureMetaDataExtendedInfo )
01758 * ( sig_idx + 1 ) );
01759
if ( !alloc_return )
01760
break;
01761 sigmeta->extended_info = (CryptPlug::SignatureMetaDataExtendedInfo*)alloc_return;
01762
01763
01764 CryptPlug::SignatureMetaDataExtendedInfo & this_info = sigmeta->extended_info[sig_idx];
01765
01766
01767 memset( &this_info, 0,
sizeof (CryptPlug::SignatureMetaDataExtendedInfo) );
01768
01769
01770
if ( signature->timestamp ) {
01771 this_info.creation_time = (tm*)malloc(
sizeof(
struct tm ) );
01772
if ( this_info.creation_time ) {
01773
struct tm * ctime_val = localtime( (time_t*)&signature->timestamp );
01774 memcpy( this_info.creation_time,
01775 ctime_val,
sizeof(
struct tm ) );
01776 }
01777 }
01778
01779
01780 sumGPGME = signature->summary;
01781 fprintf( stderr,
"gpgmeplug checkMessageSignature status flags: %lX\n", sumGPGME );
01782
01783 sumPlug = 0;
01784
#define convert(X) if ( sumGPGME & GPGME_SIGSUM_##X ) sumPlug |= SigStat_##X
01785
convert(VALID);
01786 convert(GREEN);
01787 convert(RED);
01788 convert(KEY_REVOKED);
01789 convert(KEY_EXPIRED);
01790 convert(SIG_EXPIRED);
01791 convert(KEY_MISSING);
01792 convert(CRL_MISSING);
01793 convert(CRL_TOO_OLD);
01794 convert(BAD_POLICY);
01795 convert(SYS_ERROR);
01796
#undef convert
01797
if( sumGPGME && !sumPlug )
01798 sumPlug = SigStat_NUMERICAL_CODE | sumGPGME;
01799 this_info.sigStatusFlags = sumPlug;
01800
01801
01802
if ( signature->fpr )
01803 storeNewCharPtr( &this_info.fingerprint, signature->fpr );
01804
01805
01806 this_info.validity = GPGME_VALIDITY_UNKNOWN;
01807
01808
01809 gpgme_key_t key = 0;
01810
01811
01812 err = gpgme_get_sig_key (ctx, sig_idx, &key);
01813
01814
if ( !err && key ) {
01815
const char* attr_string;
01816
unsigned long attr_ulong;
01817
01818
01819 attr_string = key->subkeys ? key->subkeys->keyid : 0 ;
01820
if ( attr_string )
01821 storeNewCharPtr( &this_info.keyid, attr_string );
01822
01823
01824 attr_string = key->subkeys ? gpgme_pubkey_algo_name( key->subkeys->pubkey_algo ) : 0 ;
01825
if (attr_string != 0)
01826 storeNewCharPtr( &this_info.algo, attr_string );
01827 attr_ulong = key->subkeys ? key->subkeys->pubkey_algo : 0 ;
01828 this_info.algo_num = attr_ulong;
01829
01830
01831 attr_ulong = key->uids ? key->uids->validity : 0 ;
01832 this_info.validity = attr_ulong;
01833
01834
01835
01836
01837 attr_string = key->uids ? key->uids->uid : 0 ;
01838
if (attr_string != 0) {
01839 a = parse_dn( (
const unsigned char*)attr_string );
01840 this_info.userid = reorder_dn( a, attrOrder, unknownAttrsHandling );
01841 }
01842
01843 attr_ulong = 0;
01844 this_info.userid_num = attr_ulong;
01845
01846
01847 this_info.keylen = key->subkeys ? key->subkeys->length : 0 ;
01848
01849
01850 attr_ulong = key->subkeys ? key->subkeys->timestamp : 0 ;
01851 this_info.key_created = attr_ulong;
01852
01853
01854 attr_ulong = key->subkeys ? key->subkeys->expires : 0 ;
01855 this_info.key_expires = attr_ulong;
01856
01857
01858 attr_string = key->uids ? key->uids->name : 0 ;
01859
if (attr_string != 0) {
01860 a = parse_dn( (
const unsigned char*)attr_string );
01861 this_info.name = reorder_dn( a, attrOrder, unknownAttrsHandling );
01862 }
01863
01864
01865 this_info.emailCount = 0;
01866 this_info.emailList = 0;
01867
for ( gpgme_user_id_t uid = key->uids ; uid ; uid = uid->next ) {
01868 attr_string = uid->email;
01869
if ( attr_string && *attr_string) {
01870 fprintf( stderr,
"gpgmeplug checkMessageSignature found email: %s\n", attr_string );
01871
if( !this_info.emailCount )
01872 alloc_return = malloc(
sizeof(
char*) );
01873
else
01874 alloc_return = realloc( this_info.emailList,
01875
sizeof(
char*)
01876 * (this_info.emailCount + 1) );
01877
if( alloc_return ) {
01878 this_info.emailList = (
char**)alloc_return;
01879 storeNewCharPtr( &( this_info.emailList[ this_info.emailCount ] ),
01880 attr_string );
01881 ++this_info.emailCount;
01882 }
01883 }
01884 }
01885
if( !this_info.emailCount )
01886 fprintf( stderr,
"gpgmeplug checkMessageSignature found NO EMAIL\n" );
01887
01888
01889 attr_string = key->uids ? key->uids->comment : 0 ;
01890
if (attr_string != 0)
01891 storeNewCharPtr( &this_info.comment, attr_string );
01892 }
01893
01894 gpgme_sig_stat_t status = sig_stat_from_status( signature->status );
01895
const char* sig_status = sig_status_to_string( status );
01896 storeNewCharPtr( &this_info.status_text, sig_status );
01897 }
01898 sigmeta->extended_info_count = sig_idx;
01899 overallStatus = intersect_stati( result->signatures );
01900 sigmeta->status_code = overallStatus;
01901 storeNewCharPtr( &sigmeta->status, sig_status_to_string( overallStatus ) );
01902
if ( signatureFound )
01903 *signatureFound = ( overallStatus != GPGME_SIG_STAT_NONE );
01904 }
01905
01906
01907
bool CryptPlug::checkMessageSignature(
char** cleartext,
01908
const char* signaturetext,
01909
bool signatureIsBinary,
01910
int signatureLen,
01911
struct CryptPlug::SignatureMetaData* sigmeta,
01912
char** attrOrder,
01913
const char* unknownAttrsHandling )
01914 {
01915 gpgme_ctx_t ctx;
01916 gpgme_sig_stat_t status = GPGME_SIG_STAT_NONE;
01917 gpgme_data_t datapart, sigpart;
01918
char* rClear = 0;
01919 size_t clearLen;
01920
bool isOpaqueSigned;
01921
01922
if( !cleartext ) {
01923
if( sigmeta )
01924 storeNewCharPtr( &sigmeta->status,
01925 __GPGMEPLUG_ERROR_CLEARTEXT_IS_ZERO );
01926
01927
return false;
01928 }
01929
01930 isOpaqueSigned = !*cleartext;
01931
01932 gpgme_new( &ctx );
01933 gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
01934 gpgme_set_armor (ctx, signatureIsBinary ? 0 : 1);
01935
01936
01937
if( isOpaqueSigned )
01938 gpgme_data_new( &datapart );
01939
else
01940 gpgme_data_new_from_mem( &datapart, *cleartext,
01941 strlen( *cleartext ), 1 );
01942
01943 gpgme_data_new_from_mem( &sigpart,
01944 signaturetext,
01945 signatureIsBinary
01946 ? signatureLen
01947 : strlen( signaturetext ),
01948 1 );
01949
01950
if ( isOpaqueSigned )
01951 gpgme_op_verify( ctx, sigpart, 0, datapart );
01952
else
01953 gpgme_op_verify( ctx, sigpart, datapart, 0 );
01954
01955
if( isOpaqueSigned ) {
01956 rClear = gpgme_data_release_and_get_mem( datapart, &clearLen );
01957 *cleartext = (
char*)malloc( clearLen + 1 );
01958
if( *cleartext ) {
01959
if( clearLen )
01960 strncpy(*cleartext, rClear, clearLen );
01961 (*cleartext)[clearLen] =
'\0';
01962 }
01963 free( rClear );
01964 }
01965
else
01966 gpgme_data_release( datapart );
01967
01968 gpgme_data_release( sigpart );
01969
01970 obtain_signature_information( ctx, status, sigmeta,
01971 attrOrder, unknownAttrsHandling );
01972
01973 gpgme_release( ctx );
01974
return ( status == GPGME_SIG_STAT_GOOD );
01975 }
01976
01977
01978
bool CryptPlug::decryptAndCheckMessage(
const char* ciphertext,
01979
bool cipherIsBinary,
01980
int cipherLen,
01981
const char** cleartext,
01982
const char* ,
01983
bool* signatureFound,
01984
struct CryptPlug::SignatureMetaData* sigmeta,
01985
int* errId,
01986
char** errTxt,
01987
char** attrOrder,
01988
const char* unknownAttrsHandling )
01989 {
01990 gpgme_ctx_t ctx;
01991 gpgme_error_t err;
01992 gpgme_data_t gCiphertext, gPlaintext;
01993 gpgme_sig_stat_t sigstatus = GPGME_SIG_STAT_NONE;
01994 size_t rCLen = 0;
01995
char* rCiph = 0;
01996
bool bOk =
false;
01997
01998
if( !ciphertext )
01999
return false;
02000
02001 err = gpgme_new (&ctx);
02002 gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
02003
02004 gpgme_set_armor (ctx, cipherIsBinary ? 0 : 1);
02005
02006
02007
02008
02009
02010 gpgme_data_new_from_mem( &gCiphertext,
02011 ciphertext,
02012 cipherIsBinary
02013 ? cipherLen
02014 : strlen( ciphertext ),
02015 1 );
02016
02017 gpgme_data_new( &gPlaintext );
02018
02019 err = gpgme_op_decrypt_verify( ctx, gCiphertext, gPlaintext );
02020 gpgme_data_release( gCiphertext );
02021
if( err ) {
02022 fprintf( stderr,
"\ngpgme_op_decrypt_verify() returned this error code: %i\n\n", err );
02023
if( errId )
02024 *errId = err;
02025
if( errTxt ) {
02026
const char* _errTxt = gpgme_strerror( err );
02027 *errTxt = (
char*)malloc( strlen( _errTxt ) + 1 );
02028
if( *errTxt )
02029 strcpy(*errTxt, _errTxt );
02030 }
02031 gpgme_data_release( gPlaintext );
02032 gpgme_release( ctx );
02033
return bOk;
02034 }
02035
02036 rCiph = gpgme_data_release_and_get_mem( gPlaintext, &rCLen );
02037
02038 *cleartext = (
char*)malloc( rCLen + 1 );
02039
if( *cleartext ) {
02040
if( rCLen ) {
02041 bOk =
true;
02042 strncpy((
char*)*cleartext, rCiph, rCLen );
02043 }
02044 ((
char*)(*cleartext))[rCLen] = 0;
02045 }
02046 free( rCiph );
02047
02048 obtain_signature_information( ctx, sigstatus, sigmeta,
02049 attrOrder, unknownAttrsHandling,
02050 signatureFound );
02051
02052 gpgme_release( ctx );
02053
return bOk;
02054 }
02055