Corrected (for a second time) code status error from previous wrong CVS comits
[gpgme.git] / gpgmeplug / gpgmeplug.c
1 /* -*- Mode: C -*-
2
3   $Id$
4
5   GPGMEPLUG - an GPGME based cryptography plug-in following
6               the common CRYPTPLUG specification.
7
8   Copyright (C) 2001 by Klarälvdalens Datakonsult AB
9
10   GPGMEPLUG is free software; you can redistribute it and/or modify
11   it under the terms of GNU General Public License as published by
12   the Free Software Foundation; version 2 of the License.
13
14   GPGMEPLUG is distributed in the hope that it will be useful,
15   it under the terms of GNU General Public License as published by
16   the Free Software Foundation; version 2 of the License
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20
21   You should have received a copy of the GNU General Public License
22   along with this program; if not, write to the Free Software
23   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
24 */
25
26
27
28 /*! \file gpgmeplug.c
29     \brief GPGME implementation of CRYPTPLUG following the
30     specification located in common API header cryptplug.h.
31
32     CRYPTPLUG is an independent cryptography plug-in API
33     developed for Sphinx-enabeling KMail and Mutt.
34
35     CRYPTPLUG was designed for the Aegypten project, but it may
36     be used by 3rd party developers as well to design pluggable
37     crypto backends for the above mentioned MUAs.
38
39     \note All string parameters appearing in this API are to be
40     interpreted as UTF-8 encoded.
41
42     \see cryptplug.h
43 */
44
45 #ifdef HAVE_CONFIG_H
46 #include <config.h>
47 #endif
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <assert.h>
52 #include <errno.h>
53 #include <time.h>
54
55 #include "gpgme.h"
56 #ifndef GPGMEPLUG_PROTOCOL
57 #define GPGMEPLUG_PROTOCOL GPGME_PROTOCOL_OpenPGP
58 #endif
59
60 #include "cryptplug.h"
61
62
63 typedef struct {
64   const char*             signatureKeyCertificate;
65   SignatureAlgorithm      signatureAlgorithm;
66   SendCertificates        sendCertificates;
67   SignEmail               signEmail;
68   bool                    saveSentSignatures;
69   bool                    warnNoCertificate;
70   PinRequests             numPINRequests;
71   bool                    checkSignatureCertificatePathToRoot;
72   bool                    signatureUseCRLs;
73   EncryptionAlgorithm     encryptionAlgorithm;
74   EncryptEmail            encryptEmail;
75   bool                    saveMessagesEncrypted;
76   bool                    checkEncryptionCertificatePathToRoot;
77   bool                    encryptionUseCRLs;
78   bool                    encryptionCRLExpiryNearWarning;
79   int                     encryptionCRLNearExpiryInterval;
80   struct DirectoryServer *directoryServers;
81   unsigned int            numDirectoryServers;
82   CertificateSource       certificateSource;
83   CertificateSource       cRLSource;
84   bool                    warnSendUnsigned;
85   int                     numPINRequestsInterval;
86   bool                    signatureCertificateExpiryNearWarning;
87   int                     signatureCertificateExpiryNearInterval;
88   bool                    cACertificateExpiryNearWarning;
89   int                     cACertificateExpiryNearInterval;
90   bool                    rootCertificateExpiryNearWarning;
91   int                     rootCertificateExpiryNearInterval;
92   bool                    warnSendUnencrypted;
93   bool                    checkCertificatePath;
94   bool                    receiverCertificateExpiryNearWarning;
95   int                     receiverCertificateExpiryNearWarningInterval;
96   bool                    certificateInChainExpiryNearWarning;
97   int                     certificateInChainExpiryNearWarningInterval;
98   bool                    receiverEmailAddressNotInCertificateWarning;
99 } Config;
100
101
102 Config config;
103
104
105
106
107 /*
108   temporary code!!
109
110   will be removed!!
111
112   asking for passphrase will be handeked via gpg-agent!!
113 */
114 static char tmpPassphrase[1024];
115 struct passphrase_cb_info_s {
116     GpgmeCtx c;
117     int did_it;
118 };
119 static const char *
120 passphrase_cb (void *opaque, const char *desc, void *r_hd)
121 {
122     return tmpPassphrase;
123 }
124
125
126
127
128
129 #define NEAR_EXPIRY 14
130
131 bool initialize()
132 {
133   config.signatureKeyCertificate              = "";
134   config.signatureAlgorithm                   = SignAlg_SHA1;
135   config.sendCertificates                     = SendCert_SendChainWithRoot;
136   config.signEmail                            = SignEmail_SignAll;
137   config.saveSentSignatures                   = true;
138   config.warnNoCertificate                    = true;
139   config.numPINRequests                       = PinRequest_Always;
140   config.checkSignatureCertificatePathToRoot  = true;
141   config.signatureUseCRLs                     = true;
142   config.encryptionAlgorithm                  = EncryptAlg_RSA;
143   config.encryptEmail                         = EncryptEmail_Ask;
144   config.saveMessagesEncrypted                = true;
145   config.checkEncryptionCertificatePathToRoot = true;
146   config.encryptionUseCRLs                    = true;
147   config.encryptionCRLExpiryNearWarning       = true;
148   config.encryptionCRLNearExpiryInterval      = NEAR_EXPIRY;
149   config.directoryServers                     = NULL;
150   config.numDirectoryServers                  = 0;
151   config.certificateSource                    = CertSrc_Server;
152   config.cRLSource                            = CertSrc_Server;
153   config.warnSendUnsigned                             = true;
154   config.numPINRequestsInterval                       = NEAR_EXPIRY;
155   config.signatureCertificateExpiryNearWarning        = true;
156   config.signatureCertificateExpiryNearInterval       = NEAR_EXPIRY;
157   config.cACertificateExpiryNearWarning               = true;
158   config.cACertificateExpiryNearInterval              = NEAR_EXPIRY;
159   config.rootCertificateExpiryNearWarning             = true;
160   config.rootCertificateExpiryNearInterval            = NEAR_EXPIRY;
161   config.warnSendUnencrypted                          = false;
162   config.checkCertificatePath                         = true;
163   config.receiverCertificateExpiryNearWarning         = true;
164   config.receiverCertificateExpiryNearWarningInterval = NEAR_EXPIRY;
165   config.certificateInChainExpiryNearWarning          = true;
166   config.certificateInChainExpiryNearWarningInterval  = NEAR_EXPIRY;
167   config.receiverEmailAddressNotInCertificateWarning  = true;
168
169   return true;
170 };
171
172
173 void deinitialize()
174 {
175   unsigned int i;
176   for( i = 0; i < config.numDirectoryServers; ++i ) {
177     free( (char *)config.directoryServers[i].servername );
178     free( (char *)config.directoryServers[i].description );
179   }
180   free( config.directoryServers );
181 }
182
183
184 bool hasFeature( Feature flag )
185 {
186   switch ( flag ) {
187     case CryptPlugFeat_SignMessages:              return true;
188     case CryptPlugFeat_VerifySignatures:          return true;
189     case CryptPlugFeat_EncryptMessages:           return true;
190     case CryptPlugFeat_DecryptMessages:           return true;
191     // undefined or not yet implemented:
192     case CryptPlugFeat_undef:                     return false;
193     default:                                      return false;
194   }
195 }
196
197
198 void unsafeStationery( void** pixmap, const char** menutext, char* accel,
199           const char** tooltip, const char** statusbartext ){}
200
201 void signedStationery( void** pixmap, const char** menutext, char* accel,
202           const char** tooltip, const char** statusbartext ){}
203
204 void encryptedStationery( void** pixmap, const char**
205           menutext, char* accel,
206           const char** tooltip, const char** statusbartext ){}
207
208 void signedEncryptedStationery( void** pixmap, const char**
209           menutext, char* accel,
210           const char** tooltip, const char** statusbartext ){}
211
212 const char* signatureConfigurationDialog(){ return 0; }
213
214 const char* signatureKeySelectionDialog(){ return 0; }
215
216 const char* signatureAlgorithmDialog(){ return 0; }
217
218 const char* signatureHandlingDialog(){ return 0; }
219
220 void setSignatureKeyCertificate( const char* certificate )
221 {
222   config.signatureKeyCertificate = certificate;
223 }
224
225 const char* signatureKeyCertificate()
226 {
227   return config.signatureKeyCertificate;
228 }
229
230 void setSignatureAlgorithm( SignatureAlgorithm sigAlg )
231 {
232   config.signatureAlgorithm = sigAlg;
233 }
234
235 SignatureAlgorithm signatureAlgorithm()
236 {
237   return config.signatureAlgorithm;
238 }
239
240 void setSendCertificates( SendCertificates sendCert )
241 {
242   config.sendCertificates = sendCert;
243 }
244
245 SendCertificates sendCertificates()
246 {
247   return config.sendCertificates;
248 }
249
250 void setSignEmail( SignEmail signMail )
251 {
252   config.signEmail = signMail;
253 }
254
255 SignEmail signEmail()
256 {
257   return config.signEmail;
258 }
259
260
261
262
263
264 void setWarnSendUnsigned( bool flag )
265 {
266   config.warnSendUnsigned = flag;
267 }
268
269 bool warnSendUnsigned()
270 {
271   return config.warnSendUnsigned;
272 }
273
274
275
276
277
278
279 void setSaveSentSignatures( bool flag )
280 {
281   config.saveSentSignatures = flag;
282 }
283
284 bool saveSentSignatures()
285 {
286   return config.saveSentSignatures;
287 }
288
289 void setWarnNoCertificate( bool flag )
290 {
291   config.warnNoCertificate = flag;
292 }
293
294 bool warnNoCertificate()
295 {
296   return config.warnNoCertificate;
297 }
298
299 void setNumPINRequests( PinRequests reqMode )
300 {
301   config.numPINRequests = reqMode;
302 }
303
304 PinRequests numPINRequests()
305 {
306   return config.numPINRequests;
307 }
308
309
310
311
312
313 void setNumPINRequestsInterval( int interval )
314 {
315   config.numPINRequestsInterval = interval;
316 }
317
318 int numPINRequestsInterval()
319 {
320   return config.numPINRequestsInterval;
321 }
322
323
324
325
326
327
328
329 void setCheckSignatureCertificatePathToRoot( bool flag )
330 {
331   config.checkSignatureCertificatePathToRoot = flag;
332 }
333
334 bool checkSignatureCertificatePathToRoot()
335 {
336   return config.checkSignatureCertificatePathToRoot;
337 }
338
339 void setSignatureUseCRLs( bool flag )
340 {
341   config.signatureUseCRLs = flag;
342 }
343
344 bool signatureUseCRLs()
345 {
346   return config.signatureUseCRLs;
347 }
348
349
350
351
352
353
354 void setSignatureCertificateExpiryNearWarning( bool flag )
355 {
356   config.signatureCertificateExpiryNearWarning = flag;
357 }
358
359 bool signatureCertificateExpiryNearWarning( void )
360 {
361   return config.signatureCertificateExpiryNearWarning;
362 }
363
364 void setSignatureCertificateExpiryNearInterval( int interval )
365 {
366   config.signatureCertificateExpiryNearInterval = interval;
367 }
368
369 int signatureCertificateExpiryNearInterval( void )
370 {
371   return config.signatureCertificateExpiryNearInterval;
372 }
373
374 void setCACertificateExpiryNearWarning( bool flag )
375 {
376   config.cACertificateExpiryNearWarning = flag;
377 }
378
379 bool caCertificateExpiryNearWarning( void )
380 {
381   return config.cACertificateExpiryNearWarning;
382 }
383
384 void setCACertificateExpiryNearInterval( int interval )
385 {
386   config.cACertificateExpiryNearInterval = interval;
387 }
388
389 int caCertificateExpiryNearInterval( void )
390 {
391   return config.cACertificateExpiryNearInterval;
392 }
393
394 void setRootCertificateExpiryNearWarning( bool flag )
395 {
396   config.rootCertificateExpiryNearWarning = flag;
397 }
398
399 bool rootCertificateExpiryNearWarning( void )
400 {
401   return config.rootCertificateExpiryNearWarning;
402 }
403
404 void setRootCertificateExpiryNearInterval( int interval )
405 {
406   config.rootCertificateExpiryNearInterval = interval;
407 }
408
409 int rootCertificateExpiryNearInterval( void )
410 {
411   return config.rootCertificateExpiryNearInterval;
412 }
413
414
415
416
417
418
419
420
421 const char* encryptionConfigurationDialog(){ return 0; }
422
423 const char* encryptionAlgorithmDialog(){ return 0; }
424
425 const char* encryptionHandlingDialog(){ return 0; }
426
427 const char* encryptionReceiverDialog(){ return 0; }
428
429 void setEncryptionAlgorithm( EncryptionAlgorithm cryptAlg )
430 {
431   config.encryptionAlgorithm = cryptAlg;
432 }
433
434 EncryptionAlgorithm encryptionAlgorithm()
435 {
436   return config.encryptionAlgorithm;
437 }
438
439 void setEncryptEmail( EncryptEmail cryptMode )
440 {
441   config.encryptEmail = cryptMode;
442 }
443
444 EncryptEmail encryptEmail()
445 {
446   return config.encryptEmail;
447 }
448
449
450
451
452
453
454 void setWarnSendUnencrypted( bool flag )
455 {
456   config.warnSendUnencrypted = flag;
457 }
458
459 bool warnSendUnencrypted()
460 {
461   return config.warnSendUnencrypted;
462 }
463
464
465
466
467
468
469
470
471
472 void setSaveMessagesEncrypted( bool flag )
473 {
474   config.saveMessagesEncrypted = flag;
475 }
476
477 bool saveMessagesEncrypted()
478 {
479   return config.saveMessagesEncrypted;
480 }
481
482
483
484
485
486
487
488 void setCheckCertificatePath( bool flag )
489 {
490   config.checkCertificatePath = flag;
491 }
492
493 bool checkCertificatePath()
494 {
495   return config.checkCertificatePath;
496 }
497
498
499
500
501
502
503
504
505 void setCheckEncryptionCertificatePathToRoot( bool flag )
506 {
507   config.checkEncryptionCertificatePathToRoot = flag;
508 }
509
510 bool checkEncryptionCertificatePathToRoot()
511 {
512   return config.checkEncryptionCertificatePathToRoot;
513 }
514
515
516
517
518
519
520
521 void setReceiverCertificateExpiryNearWarning( bool flag )
522 {
523   config.receiverCertificateExpiryNearWarning = flag;
524 }
525
526 bool receiverCertificateExpiryNearWarning()
527 {
528   return config.receiverCertificateExpiryNearWarning;
529 }
530
531 void setReceiverCertificateExpiryNearWarningInterval( int interval )
532 {
533   config.receiverCertificateExpiryNearWarningInterval = interval;
534 }
535
536 int receiverCertificateExpiryNearWarningInterval()
537 {
538   return config.receiverCertificateExpiryNearWarningInterval;
539 }
540
541 void setCertificateInChainExpiryNearWarning( bool flag )
542 {
543   config.certificateInChainExpiryNearWarning = flag;
544 }
545
546 bool certificateInChainExpiryNearWarning()
547 {
548   return config.certificateInChainExpiryNearWarning;
549 }
550
551 void setCertificateInChainExpiryNearWarningInterval( int interval )
552 {
553   config.certificateInChainExpiryNearWarningInterval = interval;
554 }
555
556 int certificateInChainExpiryNearWarningInterval()
557 {
558   return config.certificateInChainExpiryNearWarningInterval;
559 }
560
561 void setReceiverEmailAddressNotInCertificateWarning( bool flag )
562 {
563   config.receiverEmailAddressNotInCertificateWarning = flag;
564 }
565
566 bool receiverEmailAddressNotInCertificateWarning()
567 {
568   return config.receiverEmailAddressNotInCertificateWarning;
569 }
570
571
572
573
574
575
576
577
578 void setEncryptionUseCRLs( bool flag )
579 {
580   config.encryptionUseCRLs = flag;
581 }
582
583 bool encryptionUseCRLs()
584 {
585   return config.encryptionUseCRLs;
586 }
587
588 void setEncryptionCRLExpiryNearWarning( bool flag )
589 {
590   config.encryptionCRLExpiryNearWarning = flag;
591 }
592
593 bool encryptionCRLExpiryNearWarning()
594 {
595   return config.encryptionCRLExpiryNearWarning;
596 }
597
598 void setEncryptionCRLNearExpiryInterval( int interval )
599 {
600   config.encryptionCRLNearExpiryInterval = interval;
601 }
602
603 int encryptionCRLNearExpiryInterval()
604 {
605   return config.encryptionCRLNearExpiryInterval;
606 }
607
608
609 const char* directoryServiceConfigurationDialog(){ return 0; }
610
611 void appendDirectoryServer( const char* servername,
612                             int         port,
613                             const char* description )
614 {
615   struct DirectoryServer *newServers = NULL;
616   newServers = realloc( config.directoryServers,
617                         (1+config.numDirectoryServers) * sizeof *newServers );
618   if( newServers ) {
619     config.directoryServers = newServers;
620     newServers[ config.numDirectoryServers ].servername =
621       malloc( 1+strlen( servername ) );
622     if( newServers[ config.numDirectoryServers ].servername ) {
623       strcpy( (char *)newServers[ config.numDirectoryServers ].servername,
624         servername );
625       newServers[ config.numDirectoryServers ].description =
626         malloc( 1+strlen(  description ) );
627       if( newServers[ config.numDirectoryServers ].description ) {
628         strcpy( (char *)newServers[ config.numDirectoryServers ].description,
629           description );
630         newServers[ config.numDirectoryServers ].port = port;
631         config.numDirectoryServers += 1;
632       }
633     }
634   }
635 }
636
637 void setDirectoryServers( struct DirectoryServer server[], unsigned int size )
638 {
639   unsigned int i;
640   int oldSize = config.numDirectoryServers;
641   struct DirectoryServer *newServers = NULL;
642   newServers = calloc ( size, sizeof *newServers );
643   if( newServers ) {
644     for( i=0; i < oldSize; ++i ) {
645       free( (char *)config.directoryServers[i].servername );
646       free( (char *)config.directoryServers[i].description );
647     }
648     free( config.directoryServers );
649     for( i=0; i < size; ++i ) {
650       newServers[ i ].servername = malloc( 1+strlen( server[i].servername ) );
651       if( newServers[ i ].servername ) {
652         strcpy( (char *)newServers[ i ].servername, server[i].servername );
653         newServers[ i ].description = malloc( 1+strlen( server[i].description ) );
654         if( newServers[ i ].description ) {
655           strcpy( (char *)newServers[ i ].description, server[i].description );
656           newServers[ i ].port = server[i].port;
657         }
658       }
659     }
660     config.directoryServers = newServers;
661     config.numDirectoryServers = size;
662   }
663 }
664
665 struct DirectoryServer * directoryServers( int* numServers )
666 {
667   if( numServers )
668     *numServers = config.numDirectoryServers;
669   return config.directoryServers;
670 };
671
672 void setCertificateSource( CertificateSource source )
673 {
674   config.certificateSource = source;
675 }
676
677 CertificateSource certificateSource()
678 {
679   return config.certificateSource;
680 }
681
682 void setCRLSource( CertificateSource source )
683 {
684   config.cRLSource = source;
685 }
686
687 CertificateSource crlSource()
688 {
689   return config.cRLSource;
690 }
691
692
693 bool certificateValidity( const char* certificate,
694                           int* level ){ return true; }
695
696
697 bool signMessage( const char*  cleartext,
698                   const char** ciphertext,
699                   const char*  certificate )
700 {
701   GpgmeCtx ctx;
702   GpgmeError err;
703   GpgmeData data,  sig;
704   size_t rSLen = 0;
705   char*  rSig  = 0;
706   bool   bOk   = false;
707
708
709
710 /*
711   temporary code!!
712
713   will be removed!!
714
715   asking for passphrase will be handeked via gpg-agent!!
716 */
717   struct passphrase_cb_info_s info;
718
719
720
721
722
723   if( !ciphertext )
724     return false;
725
726   err = gpgme_new (&ctx);
727   gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
728
729
730
731
732
733
734 /*
735   temporary code!!
736
737   will be removed!!
738
739   asking for passphrase will be handeked via gpg-agent!!
740 */
741   if (!getenv("GPG_AGENT_INFO")) {
742       info.c = ctx;
743       gpgme_set_passphrase_cb (ctx, passphrase_cb, &info);
744   }
745   strcpy( tmpPassphrase, certificate );
746
747
748
749
750
751   gpgme_set_armor (ctx, 1);
752   gpgme_set_textmode (ctx, 1);
753
754   gpgme_data_new_from_mem (&data, cleartext,
755                             1+strlen( cleartext ), 1 );
756   gpgme_data_new ( &sig );
757   err = gpgme_op_sign (ctx, data, sig, GPGME_SIG_MODE_DETACH );
758
759   if (!err) {
760     rSig  = gpgme_data_release_and_get_mem( sig,  &rSLen );
761     *ciphertext = malloc( rSLen + 1 );
762     if( *ciphertext ) {
763       if( rSLen ) {
764         bOk = true;
765         strncpy((char*)*ciphertext, rSig, rSLen );
766       }
767       ((char*)(*ciphertext))[rSLen] = '\0';
768     }
769     free( rSig );
770   }
771   else {
772     gpgme_data_release( sig );
773     *ciphertext = 0;
774     // hier fehlt eine Fehlerbehandlung, falls das
775     // Signieren schiefging
776   }
777   gpgme_data_release( data );
778   gpgme_release (ctx);
779
780   return bOk;
781 }
782
783
784 static const char*
785 sig_status_to_string( GpgmeSigStat status )
786 {
787     const char *result;
788
789     switch (status) {
790       case GPGME_SIG_STAT_NONE:
791         result = "Oops: Signature not verified";
792         break;
793       case GPGME_SIG_STAT_NOSIG:
794         result = "No signature found";
795         break;
796       case GPGME_SIG_STAT_GOOD:
797         result = "Good signature";
798         break;
799       case GPGME_SIG_STAT_BAD:
800         result = "BAD signature";
801         break;
802       case GPGME_SIG_STAT_NOKEY:
803         result = "No public key to verify the signature";
804         break;
805       case GPGME_SIG_STAT_ERROR:
806         result = "Error verifying the signature";
807         break;
808       case GPGME_SIG_STAT_DIFF:
809         result = "Different results for signatures";
810         break;
811       default:
812         result = "Error: Unknown status";
813         break;
814     }
815
816     return result;
817 }
818
819
820 bool checkMessageSignature( const char* ciphertext,
821                             const char* signaturetext,
822                             struct SignatureMetaData* sigmeta )
823 {
824     GpgmeCtx ctx;
825     GpgmeSigStat status;
826     GpgmeData datapart, sigpart;
827     GpgmeError err;
828     GpgmeKey key;
829     time_t created;
830     int sig_idx = 0;
831     const char* statusStr;
832     const char* fpr;
833
834     gpgme_new( &ctx );
835     gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
836     gpgme_data_new_from_mem( &datapart, ciphertext,
837                              1+strlen( ciphertext ), 1 );
838     gpgme_data_new_from_mem( &sigpart, signaturetext,
839                              1+strlen( signaturetext ), 1 );
840
841     gpgme_op_verify( ctx, sigpart, datapart, &status );
842     gpgme_data_release( datapart );
843     gpgme_data_release( sigpart );
844
845     /* Provide information in the sigmeta struct */
846     /* the status string */
847     statusStr = sig_status_to_string( status );
848     sigmeta->status = malloc( strlen( statusStr ) + 1 );
849     if( sigmeta->status ) {
850         strcpy( sigmeta->status, statusStr );
851         sigmeta->status[strlen( statusStr )] = '\0';
852     } else
853         ; // nothing to do, is already 0
854
855     // Extended information for any number of signatures.
856     fpr = gpgme_get_sig_status( ctx, sig_idx, &status, &created );
857     sigmeta->extended_info = 0;
858     while( fpr != NULL ) {
859         struct tm* ctime_val;
860         const char* sig_status;
861
862         void* realloc_return = realloc( sigmeta->extended_info,
863                                         sizeof( struct SignatureMetaDataExtendedInfo ) * ( sig_idx + 1 ) );
864         if( realloc_return ) {
865             sigmeta->extended_info = realloc_return;
866             // the creation time
867             sigmeta->extended_info[sig_idx].creation_time = malloc( sizeof( struct tm ) );
868             if( sigmeta->extended_info[sig_idx].creation_time ) {
869                 ctime_val = localtime( &created );
870                 memcpy( sigmeta->extended_info[sig_idx].creation_time,
871                         ctime_val, sizeof( struct tm ) );
872             }
873
874             err = gpgme_get_sig_key (ctx, sig_idx, &key);
875             sig_status = sig_status_to_string( status );
876             sigmeta->extended_info[sig_idx].status_text = malloc( strlen( sig_status ) + 1 );
877             if( sigmeta->extended_info[sig_idx].status_text ) {
878                 strcpy( sigmeta->extended_info[sig_idx].status_text,
879                     sig_status );
880                 sigmeta->extended_info[sig_idx].status_text[strlen( sig_status )] = '\0';
881             }
882
883             sigmeta->extended_info[sig_idx].fingerprint = malloc( strlen( fpr ) + 1 );
884             if( sigmeta->extended_info[sig_idx].fingerprint ) {
885                 strcpy( sigmeta->extended_info[sig_idx].fingerprint, fpr );
886                 sigmeta->extended_info[sig_idx].fingerprint[strlen( fpr )] = '\0';
887             }
888         } else
889             break; // if allocation fails once, it isn't likely to
890                    // succeed the next time either
891
892         fpr = gpgme_get_sig_status (ctx, ++sig_idx, &status, &created);
893     }
894     sigmeta->extended_info_count = sig_idx;
895     sigmeta->nota_xml = gpgme_get_notation( ctx );
896     sigmeta->status_code = status;
897
898     gpgme_release( ctx );
899     return ( status == GPGME_SIG_STAT_GOOD );
900 }
901
902 bool storeCertificatesFromMessage(
903         const char* ciphertext ){ return true; }
904
905
906 bool encryptMessage( const char* cleartext,
907                      const char** ciphertext,
908                      const char* addressee )
909 {
910   GpgmeCtx ctx;
911   GpgmeError err;
912   GpgmeData gCiphertext, gPlaintext;
913   GpgmeRecipients rset;
914   size_t rCLen = 0;
915   char*  rCiph = 0;
916   bool   bOk   = false;
917
918   gpgme_new (&ctx);
919   gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
920
921   gpgme_set_armor (ctx, 1);
922   gpgme_set_textmode (ctx, 1);
923
924   gpgme_data_new_from_mem (&gPlaintext, cleartext,
925                             1+strlen( cleartext ), 1 );
926   err = gpgme_data_new ( &gCiphertext );
927
928   gpgme_recipients_new (&rset);
929   gpgme_recipients_add_name (rset, addressee);
930
931   err = gpgme_op_encrypt (ctx, rset, gPlaintext, gCiphertext );
932   gpgme_recipients_release (rset);
933   gpgme_data_release (gPlaintext);
934
935   if( !err ) {
936     rCiph = gpgme_data_release_and_get_mem( gCiphertext,  &rCLen );
937     *ciphertext = malloc( rCLen + 1 );
938     if( *ciphertext ) {
939       if( rCLen ) {
940         bOk = true;
941         strncpy((char*)*ciphertext, rCiph, rCLen );
942       }
943       ((char*)(*ciphertext))[rCLen] = 0;
944     }
945     free( rCiph );
946   }
947   else {
948     gpgme_data_release ( gCiphertext );
949     *ciphertext = 0;
950     // hier fehlt eine Fehlerbehandlung: fuer einen Recipient nur ein
951     // untrusted key (oder gar keiner) gefunden wurde, verweigert gpg
952     // das signieren.
953   }
954   
955   gpgme_release (ctx);
956
957   return bOk;
958 }
959
960
961 bool encryptAndSignMessage( const char* cleartext,
962           const char** ciphertext, const char* certificate,
963           struct SignatureMetaData* sigmeta ){ return true; }
964
965 bool decryptMessage( const char* ciphertext,
966                      const char** cleartext,
967                      const char* certificate )
968 {
969     GpgmeCtx ctx;
970     GpgmeData gCiphertext, gPlaintext;
971     size_t rCLen;
972     char*  rCiph = 0;
973     bool bOk = false;
974
975
976
977 /*
978   temporary code!!
979
980   will be removed!!
981
982   asking for passphrase will be handeked via gpg-agent!!
983 */
984   struct passphrase_cb_info_s info;
985
986
987 /*
988   temporary code!!
989
990   will be removed!!
991
992   asking for passphrase will be handeked via gpg-agent!!
993 */
994   if (!getenv("GPG_AGENT_INFO")) {
995       info.c = ctx;
996       gpgme_set_passphrase_cb (ctx, passphrase_cb, &info);
997   }
998   strcpy( tmpPassphrase, certificate );
999
1000
1001
1002     gpgme_new( &ctx );
1003     gpgme_data_new_from_mem( &gCiphertext, ciphertext,
1004                              1+strlen( ciphertext ), 1 );
1005     gpgme_data_new( &gPlaintext );
1006
1007     gpgme_op_decrypt( ctx, gCiphertext, gPlaintext );
1008     gpgme_data_release( gCiphertext );
1009
1010     rCiph = gpgme_data_release_and_get_mem( gPlaintext,  &rCLen );
1011
1012     *cleartext = malloc( rCLen + 1 );
1013     if( *cleartext ) {
1014         if( rCLen ) {
1015             bOk = true;
1016             strncpy((char*)*cleartext, rCiph, rCLen );
1017         }
1018         ((char*)(*cleartext))[rCLen] = 0;
1019     }
1020
1021     free( rCiph );
1022     gpgme_release( ctx );
1023     return bOk;
1024 }
1025
1026 bool decryptAndCheckMessage( const char* ciphertext,
1027           const char** cleartext, const char* certificate,
1028           struct SignatureMetaData* sigmeta ){ return true; }
1029
1030
1031 const char* requestCertificateDialog(){ return 0; }
1032
1033 bool requestDecentralCertificate( const char* name, const char*
1034           email, const char* organization, const char* department,
1035           const char* ca_address ){ return true; }
1036
1037 bool requestCentralCertificateAndPSE( const char* name,
1038           const char* email, const char* organization, const char* department,
1039           const char* ca_address ){ return true; }
1040
1041 bool createPSE(){ return true; }
1042
1043 bool registerCertificate( const char* certificate ){ return true; }
1044
1045 bool requestCertificateProlongation( const char* certificate,
1046                                      const char* ca_address ){ return true; }
1047
1048 const char* certificateChain(){ return 0; }
1049
1050 bool deleteCertificate( const char* certificate ){ return true; }
1051
1052 bool archiveCertificate( const char* certificate ){ return true; }
1053
1054
1055 const char* displayCRL(){ return 0; }
1056
1057 void updateCRL(){}