1136bc72bd76a4f866edba582551f1112f1be570
[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;
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   gpgme_op_sign (ctx, data, sig, GPGME_SIG_MODE_DETACH );
758
759   rSig  = gpgme_data_release_and_get_mem( sig,  &rSLen );
760   gpgme_data_release( data );
761
762   *ciphertext = malloc( rSLen + 1 );
763   if( *ciphertext ) {
764     if( rSLen ) {
765       bOk = true;
766       strncpy((char*)*ciphertext, rSig, rSLen );
767     }
768     ((char*)(*ciphertext))[rSLen] = '\0';
769   }
770
771   free( rSig );
772   gpgme_release (ctx);
773
774   return bOk;
775 }
776
777
778 static const char*
779 sig_status_to_string( GpgmeSigStat status )
780 {
781     const char *result;
782
783     switch (status) {
784       case GPGME_SIG_STAT_NONE:
785         result = "Oops: Signature not verified";
786         break;
787       case GPGME_SIG_STAT_NOSIG:
788         result = "No signature found";
789         break;
790       case GPGME_SIG_STAT_GOOD:
791         result = "Good signature";
792         break;
793       case GPGME_SIG_STAT_BAD:
794         result = "BAD signature";
795         break;
796       case GPGME_SIG_STAT_NOKEY:
797         result = "No public key to verify the signature";
798         break;
799       case GPGME_SIG_STAT_ERROR:
800         result = "Error verifying the signature";
801         break;
802       case GPGME_SIG_STAT_DIFF:
803         result = "Different results for signatures";
804         break;
805       default:
806         result = "Error: Unknown status";
807         break;
808     }
809
810     return result;
811 }
812
813
814 bool checkMessageSignature( const char* ciphertext,
815                             const char* signaturetext,
816                             struct SignatureMetaData* sigmeta )
817 {
818     GpgmeCtx ctx;
819     GpgmeSigStat status;
820     GpgmeData datapart, sigpart;
821     GpgmeError err;
822     GpgmeKey key;
823     time_t created;
824     int sig_idx = 0;
825     const char* statusStr;
826     const char* fpr;
827
828     gpgme_new( &ctx );
829     gpgme_data_new_from_mem( &datapart, ciphertext,
830                              1+strlen( ciphertext ), 1 );
831     gpgme_data_new_from_mem( &sigpart, signaturetext,
832                              1+strlen( signaturetext ), 1 );
833
834     gpgme_op_verify( ctx, sigpart, datapart, &status );
835     gpgme_data_release( datapart );
836     gpgme_data_release( sigpart );
837
838     /* Provide information in the sigmeta struct */
839     /* the status string */
840     statusStr = sig_status_to_string( status );
841     sigmeta->status = malloc( strlen( statusStr ) + 1 );
842     if( sigmeta->status ) {
843         strcpy( sigmeta->status, statusStr );
844         sigmeta->status[strlen( statusStr )] = '\0';
845     } else
846         ; // nothing to do, is already 0
847
848     // Extended information for any number of signatures.
849     fpr = gpgme_get_sig_status( ctx, sig_idx, &status, &created );
850     sigmeta->extended_info = 0;
851     while( fpr != NULL ) {
852         struct tm* ctime_val;
853         const char* sig_status;
854
855         void* realloc_return = realloc( sigmeta->extended_info,
856                                         sizeof( struct SignatureMetaDataExtendedInfo ) * ( sig_idx + 1 ) );
857         if( realloc_return ) {
858             sigmeta->extended_info = realloc_return;
859             // the creation time
860             sigmeta->extended_info[sig_idx].creation_time = malloc( sizeof( struct tm ) );
861             if( sigmeta->extended_info[sig_idx].creation_time ) {
862                 ctime_val = localtime( &created );
863                 memcpy( sigmeta->extended_info[sig_idx].creation_time,
864                         ctime_val, sizeof( struct tm ) );
865             }
866
867             err = gpgme_get_sig_key (ctx, sig_idx, &key);
868             sig_status = sig_status_to_string( status );
869             sigmeta->extended_info[sig_idx].status_text = malloc( strlen( sig_status ) + 1 );
870             if( sigmeta->extended_info[sig_idx].status_text ) {
871                 strcpy( sigmeta->extended_info[sig_idx].status_text,
872                     sig_status );
873                 sigmeta->extended_info[sig_idx].status_text[strlen( sig_status )] = '\0';
874             }
875
876             sigmeta->extended_info[sig_idx].fingerprint = malloc( strlen( fpr ) + 1 );
877             if( sigmeta->extended_info[sig_idx].fingerprint ) {
878                 strcpy( sigmeta->extended_info[sig_idx].fingerprint, fpr );
879                 sigmeta->extended_info[sig_idx].fingerprint[strlen( fpr )] = '\0';
880             }
881         } else
882             break; // if allocation fails once, it isn't likely to
883                    // succeed the next time either
884         
885         fpr = gpgme_get_sig_status (ctx, ++sig_idx, &status, &created);
886     }
887     sigmeta->extended_info_count = sig_idx;
888     sigmeta->nota_xml = gpgme_get_notation( ctx );
889     sigmeta->status_code = status;
890
891     gpgme_release( ctx );
892     return ( status == GPGME_SIG_STAT_GOOD );
893 }
894
895 bool storeCertificatesFromMessage(
896         const char* ciphertext ){ return true; }
897
898
899 bool encryptMessage( const char* cleartext,
900                      const char** ciphertext,
901                      const char* addressee )
902 {
903   GpgmeCtx ctx;
904   GpgmeError err;
905   GpgmeData gCiphertext, gPlaintext;
906   GpgmeRecipients rset;
907   size_t rCLen;
908   char*  rCiph = 0;
909   bool   bOk   = false;
910
911   gpgme_new (&ctx);
912   gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
913
914   gpgme_set_armor (ctx, 1);
915   gpgme_set_textmode (ctx, 1);
916
917   gpgme_data_new_from_mem (&gPlaintext, cleartext,
918                             1+strlen( cleartext ), 1 );
919   err = gpgme_data_new ( &gCiphertext );
920
921   gpgme_recipients_new (&rset);
922   gpgme_recipients_add_name (rset, addressee);
923
924   gpgme_op_encrypt (ctx, rset, gPlaintext, gCiphertext );
925   gpgme_data_release (gPlaintext);
926   gpgme_recipients_release (rset);
927
928   rCiph = gpgme_data_release_and_get_mem( gCiphertext,  &rCLen );
929
930   *ciphertext = malloc( rCLen + 1 );
931   if( *ciphertext ) {
932     if( rCLen ) {
933       bOk = true;
934       strncpy((char*)*ciphertext, rCiph, rCLen );
935     }
936     ((char*)(*ciphertext))[rCLen] = 0;
937   }
938
939   free( rCiph );
940   gpgme_release (ctx);
941
942   return bOk;
943 }
944
945
946 bool encryptAndSignMessage( const char* cleartext,
947           const char** ciphertext, const char* certificate,
948           struct SignatureMetaData* sigmeta ){ return true; }
949
950 bool decryptMessage( const char* ciphertext, const
951           char** cleartext, const char* certificate ){ return true; }
952
953 bool decryptAndCheckMessage( const char* ciphertext,
954           const char** cleartext, const char* certificate,
955           struct SignatureMetaData* sigmeta ){ return true; }
956
957
958 const char* requestCertificateDialog(){ return 0; }
959
960 bool requestDecentralCertificate( const char* name, const char*
961           email, const char* organization, const char* department,
962           const char* ca_address ){ return true; }
963
964 bool requestCentralCertificateAndPSE( const char* name,
965           const char* email, const char* organization, const char* department,
966           const char* ca_address ){ return true; }
967
968 bool createPSE(){ return true; }
969
970 bool registerCertificate( const char* certificate ){ return true; }
971
972 bool requestCertificateProlongation( const char* certificate,
973                                      const char* ca_address ){ return true; }
974
975 const char* certificateChain(){ return 0; }
976
977 bool deleteCertificate( const char* certificate ){ return true; }
978
979 bool archiveCertificate( const char* certificate ){ return true; }
980
981
982 const char* displayCRL(){ return 0; }
983
984 void updateCRL(){}