More feature selectors
[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 <string.h>
50 #include <assert.h>
51 #include <errno.h>
52 #include <time.h>
53 #include <ctype.h>
54
55 #ifndef BUG_URL
56 #define BUG_URL "http:://www.gnupg.org/aegypten/"
57 #endif
58
59 #include "gpgme.h"
60 #ifndef GPGMEPLUG_PROTOCOL
61 #define GPGMEPLUG_PROTOCOL GPGME_PROTOCOL_OpenPGP
62 #endif
63
64 // definitions for signing
65 #ifndef GPGMEPLUG_SIGN_MAKE_MIME_OBJECT
66 #define GPGMEPLUG_SIGN_INCLUDE_CLEARTEXT true
67 #define GPGMEPLUG_SIGN_MAKE_MIME_OBJECT  true
68 #define GPGMEPLUG_SIGN_MAKE_MULTI_MIME   true
69 #define GPGMEPLUG_SIGN_CTYPE_MAIN        "multipart/signed;protocol=application/pgp-signature;micalg=pgp-sha1"
70 #define GPGMEPLUG_SIGN_CDISP_MAIN        ""
71 #define GPGMEPLUG_SIGN_CTENC_MAIN        ""
72 #define GPGMEPLUG_SIGN_CTYPE_VERSION     ""
73 #define GPGMEPLUG_SIGN_CDISP_VERSION     ""
74 #define GPGMEPLUG_SIGN_CTENC_VERSION     ""
75 #define GPGMEPLUG_SIGN_BTEXT_VERSION     ""
76 #define GPGMEPLUG_SIGN_CTYPE_CODE        "application/pgp-signature"
77 #define GPGMEPLUG_SIGN_CDISP_CODE        ""
78 #define GPGMEPLUG_SIGN_CTENC_CODE        ""
79 #define GPGMEPLUG_SIGN_FLAT_PREFIX       ""
80 #define GPGMEPLUG_SIGN_FLAT_SEPARATOR    ""
81 #define GPGMEPLUG_SIGN_FLAT_POSTFIX      ""
82 #endif
83 // definitions for encoding
84 #ifndef GPGMEPLUG_ENC_MAKE_MIME_OBJECT
85 #define GPGMEPLUG_ENC_INCLUDE_CLEARTEXT  false
86 #define GPGMEPLUG_ENC_MAKE_MIME_OBJECT   true
87 #define GPGMEPLUG_ENC_MAKE_MULTI_MIME    true
88 #define GPGMEPLUG_ENC_CTYPE_MAIN         "multipart/encrypted; protocol=application/pgp-encrypted"
89 #define GPGMEPLUG_ENC_CDISP_MAIN         ""
90 #define GPGMEPLUG_ENC_CTENC_MAIN         ""
91 #define GPGMEPLUG_ENC_CTYPE_VERSION      "application/pgp-encrypted"
92 #define GPGMEPLUG_ENC_CDISP_VERSION      "attachment"
93 #define GPGMEPLUG_ENC_CTENC_VERSION      ""
94 #define GPGMEPLUG_ENC_BTEXT_VERSION      "Version: 1"
95 #define GPGMEPLUG_ENC_CTYPE_CODE         "application/octet-stream"
96 #define GPGMEPLUG_ENC_CDISP_CODE         "inline; filename=\"msg.asc\""
97 #define GPGMEPLUG_ENC_CTENC_CODE         ""
98 #define GPGMEPLUG_ENC_FLAT_PREFIX        ""
99 #define GPGMEPLUG_ENC_FLAT_SEPARATOR     ""
100 #define GPGMEPLUG_ENC_FLAT_POSTFIX       ""
101 #endif
102 // Note: The following specification will result in
103 //       function encryptAndSignMessage() producing
104 //       _empty_ mails.
105 //       This must be changed as soon as our plugin
106 //       is supporting the encryptAndSignMessage() function.
107 #ifndef GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT
108 #define GPGMEPLUG_ENCSIGN_INCLUDE_CLEARTEXT false
109 #define GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT  false
110 #define GPGMEPLUG_ENCSIGN_MAKE_MULTI_MIME   false
111 #define GPGMEPLUG_ENCSIGN_CTYPE_MAIN        ""
112 #define GPGMEPLUG_ENCSIGN_CDISP_MAIN        ""
113 #define GPGMEPLUG_ENCSIGN_CTENC_MAIN        ""
114 #define GPGMEPLUG_ENCSIGN_CTYPE_VERSION     ""
115 #define GPGMEPLUG_ENCSIGN_CDISP_VERSION     ""
116 #define GPGMEPLUG_ENCSIGN_CTENC_VERSION     ""
117 #define GPGMEPLUG_ENCSIGN_BTEXT_VERSION     ""
118 #define GPGMEPLUG_ENCSIGN_CTYPE_CODE        ""
119 #define GPGMEPLUG_ENCSIGN_CDISP_CODE        ""
120 #define GPGMEPLUG_ENCSIGN_CTENC_CODE        ""
121 #define GPGMEPLUG_ENCSIGN_FLAT_PREFIX       ""
122 #define GPGMEPLUG_ENCSIGN_FLAT_SEPARATOR    ""
123 #define GPGMEPLUG_ENCSIGN_FLAT_POSTFIX      ""
124 #endif
125
126 #include "cryptplug.h"
127
128
129 typedef struct {
130   const char*             bugURL;
131   const char*             signatureKeyCertificate;
132   SignatureAlgorithm      signatureAlgorithm;
133   SendCertificates        sendCertificates;
134   SignEmail               signEmail;
135   bool                    saveSentSignatures;
136   bool                    warnNoCertificate;
137   PinRequests             numPINRequests;
138   bool                    checkSignatureCertificatePathToRoot;
139   bool                    signatureUseCRLs;
140   EncryptionAlgorithm     encryptionAlgorithm;
141   EncryptEmail            encryptEmail;
142   bool                    saveMessagesEncrypted;
143   bool                    checkEncryptionCertificatePathToRoot;
144   bool                    encryptionUseCRLs;
145   bool                    encryptionCRLExpiryNearWarning;
146   int                     encryptionCRLNearExpiryInterval;
147   struct DirectoryServer *directoryServers;
148   unsigned int            numDirectoryServers;
149   CertificateSource       certificateSource;
150   CertificateSource       cRLSource;
151   bool                    warnSendUnsigned;
152   int                     numPINRequestsInterval;
153   bool                    signatureCertificateExpiryNearWarning;
154   int                     signatureCertificateExpiryNearInterval;
155   bool                    cACertificateExpiryNearWarning;
156   int                     cACertificateExpiryNearInterval;
157   bool                    rootCertificateExpiryNearWarning;
158   int                     rootCertificateExpiryNearInterval;
159   bool                    warnSendUnencrypted;
160   bool                    checkCertificatePath;
161   bool                    receiverCertificateExpiryNearWarning;
162   int                     receiverCertificateExpiryNearWarningInterval;
163   bool                    certificateInChainExpiryNearWarning;
164   int                     certificateInChainExpiryNearWarningInterval;
165   bool                    receiverEmailAddressNotInCertificateWarning;
166 } Config;
167
168
169 Config config;
170
171 #define NEAR_EXPIRY 14
172
173 bool initialize()
174 {
175   config.bugURL                               = malloc( strlen( BUG_URL ) + 1 );
176   strcpy( (char* )config.bugURL,                BUG_URL );
177   config.signatureKeyCertificate              = malloc( 1 );
178   strcpy( (char* )config.signatureKeyCertificate, "" );
179   config.signatureAlgorithm                   = SignAlg_SHA1;
180   config.sendCertificates                     = SendCert_SendChainWithRoot;
181   config.signEmail                            = SignEmail_SignAll;
182   config.saveSentSignatures                   = true;
183   config.warnNoCertificate                    = true;
184   config.numPINRequests                       = PinRequest_Always;
185   config.checkSignatureCertificatePathToRoot  = true;
186   config.signatureUseCRLs                     = true;
187   config.encryptionAlgorithm                  = EncryptAlg_RSA;
188   config.encryptEmail                         = EncryptEmail_Ask;
189   config.saveMessagesEncrypted                = true;
190   config.checkEncryptionCertificatePathToRoot = true;
191   config.encryptionUseCRLs                    = true;
192   config.encryptionCRLExpiryNearWarning       = true;
193   config.encryptionCRLNearExpiryInterval      = NEAR_EXPIRY;
194   config.directoryServers                     = NULL;
195   config.numDirectoryServers                  = 0;
196   config.certificateSource                    = CertSrc_Server;
197   config.cRLSource                            = CertSrc_Server;
198   config.warnSendUnsigned                             = true;
199   config.numPINRequestsInterval                       = NEAR_EXPIRY;
200   config.signatureCertificateExpiryNearWarning        = true;
201   config.signatureCertificateExpiryNearInterval       = NEAR_EXPIRY;
202   config.cACertificateExpiryNearWarning               = true;
203   config.cACertificateExpiryNearInterval              = NEAR_EXPIRY;
204   config.rootCertificateExpiryNearWarning             = true;
205   config.rootCertificateExpiryNearInterval            = NEAR_EXPIRY;
206   config.warnSendUnencrypted                          = false;
207   config.checkCertificatePath                         = true;
208   config.receiverCertificateExpiryNearWarning         = true;
209   config.receiverCertificateExpiryNearWarningInterval = NEAR_EXPIRY;
210   config.certificateInChainExpiryNearWarning          = true;
211   config.certificateInChainExpiryNearWarningInterval  = NEAR_EXPIRY;
212   config.receiverEmailAddressNotInCertificateWarning  = true;
213
214   return true;
215 };
216
217
218 void deinitialize()
219 {
220   unsigned int i;
221   for( i = 0; i < config.numDirectoryServers; ++i ) {
222     free( (char *)config.directoryServers[i].servername );
223     free( (char *)config.directoryServers[i].description );
224   }
225   free( config.directoryServers );
226 }
227
228
229 bool hasFeature( Feature flag )
230 {
231     // our own plugins are supposed to support everything
232   switch ( flag ) {
233   case Feature_SignMessages:              return true;
234   case Feature_VerifySignatures:          return true;
235   case Feature_EncryptMessages:           return true;
236   case Feature_DecryptMessages:           return true;
237   case Feature_SendCertificates:          return true;
238   case Feature_WarnSignCertificateExpiry: return true;
239   case Feature_WarnSignEmailNotInCertificate: return true;
240   case Feature_PinEntrySettings:          return true;
241   case Feature_StoreMessagesWithSigs:     return true;
242   case Feature_EncryptionCRLs:            return true;
243   case Feature_WarnEncryptCertificateExpiry: return true;
244   case Feature_WarnEncryptEmailNotInCertificate: return true;
245   case Feature_StoreMessagesEncrypted:    return true;
246   case Feature_CheckCertificatePath:      return true;
247   case Feature_CertificateDirectoryService: return true;
248   case Feature_CRLDirectoryService:       return true;
249       // undefined or not yet implemented:
250   case Feature_undef:                     return false;
251   default:                                      return false;
252   }
253 }
254
255
256 const char* bugURL(){ return config.bugURL; }
257
258
259 void unsafeStationery( void** pixmap, const char** menutext, char* accel,
260           const char** tooltip, const char** statusbartext ){}
261
262 void signedStationery( void** pixmap, const char** menutext, char* accel,
263           const char** tooltip, const char** statusbartext ){}
264
265 void encryptedStationery( void** pixmap, const char**
266           menutext, char* accel,
267           const char** tooltip, const char** statusbartext ){}
268
269 void signedEncryptedStationery( void** pixmap, const char**
270           menutext, char* accel,
271           const char** tooltip, const char** statusbartext ){}
272
273 const char* signatureConfigurationDialog(){ return 0; }
274
275 const char* signatureKeySelectionDialog(){ return 0; }
276
277 const char* signatureAlgorithmDialog(){ return 0; }
278
279 const char* signatureHandlingDialog(){ return 0; }
280
281 void setSignatureKeyCertificate( const char* certificate )
282 {
283   config.signatureKeyCertificate = certificate;
284 }
285
286 const char* signatureKeyCertificate()
287 {
288   return config.signatureKeyCertificate;
289 }
290
291 void setSignatureAlgorithm( SignatureAlgorithm sigAlg )
292 {
293   config.signatureAlgorithm = sigAlg;
294 }
295
296 SignatureAlgorithm signatureAlgorithm()
297 {
298   return config.signatureAlgorithm;
299 }
300
301 void setSendCertificates( SendCertificates sendCert )
302 {
303   config.sendCertificates = sendCert;
304 }
305
306 SendCertificates sendCertificates()
307 {
308   return config.sendCertificates;
309 }
310
311 void setSignEmail( SignEmail signMail )
312 {
313   config.signEmail = signMail;
314 }
315
316 SignEmail signEmail()
317 {
318   return config.signEmail;
319 }
320
321
322
323
324
325 void setWarnSendUnsigned( bool flag )
326 {
327   config.warnSendUnsigned = flag;
328 }
329
330 bool warnSendUnsigned()
331 {
332   return config.warnSendUnsigned;
333 }
334
335
336
337
338
339
340 void setSaveSentSignatures( bool flag )
341 {
342   config.saveSentSignatures = flag;
343 }
344
345 bool saveSentSignatures()
346 {
347   return config.saveSentSignatures;
348 }
349
350 void setWarnNoCertificate( bool flag )
351 {
352   config.warnNoCertificate = flag;
353 }
354
355 bool warnNoCertificate()
356 {
357   return config.warnNoCertificate;
358 }
359
360
361 bool isEmailInCertificate( const char* email, const char* certificate )
362 {
363     /* PENDING(g10) this function should return true if the email
364        address passed as the first parameter is contained in the
365        certificate passed as the second parameter, and false
366        otherwise. This is used to alert the user if his own email
367        address is not contained in the certificate he uses for
368        signing.
369        Note that the parameter email can be anything that is allowed
370        in a From: line.
371        Another note: OK, OK, we'll handle that in the MUA. You can
372        assume that you only get the email address.
373     */
374     return false; // dummy
375 }
376
377
378 void setNumPINRequests( PinRequests reqMode )
379 {
380   config.numPINRequests = reqMode;
381
382   /* PENDING(g10) Put this value into gpg and make it ask for the pin
383      according to this. Note that there is also
384      setNumPINRequestsInterval() which is only used if reqMode ==
385      PinRequest_AfterMinutes.
386   */
387 }
388
389 PinRequests numPINRequests()
390 {
391   return config.numPINRequests;
392 }
393
394
395
396 void setNumPINRequestsInterval( int interval )
397 {
398   config.numPINRequestsInterval = interval;
399
400   /* PENDING(g10) Put this value into gpg and make it ask for the pin
401      according to this. Note that this should only be used if
402      config.numPINRequests (set with setNumPINRequests()) has the
403      value PinRequest_AfterMinutes.
404   */
405 }
406
407 int numPINRequestsInterval()
408 {
409   return config.numPINRequestsInterval;
410 }
411
412
413
414 void setCheckSignatureCertificatePathToRoot( bool flag )
415 {
416   config.checkSignatureCertificatePathToRoot = flag;
417 }
418
419 bool checkSignatureCertificatePathToRoot()
420 {
421   return config.checkSignatureCertificatePathToRoot;
422 }
423
424 void setSignatureUseCRLs( bool flag )
425 {
426   config.signatureUseCRLs = flag;
427 }
428
429 bool signatureUseCRLs()
430 {
431   return config.signatureUseCRLs;
432 }
433
434
435
436
437
438
439 void setSignatureCertificateExpiryNearWarning( bool flag )
440 {
441   config.signatureCertificateExpiryNearWarning = flag;
442 }
443
444 bool signatureCertificateExpiryNearWarning( void )
445 {
446   return config.signatureCertificateExpiryNearWarning;
447 }
448
449
450 int signatureCertificateDaysLeftToExpiry( const char* certificate )
451 {
452     /* PENDING(g10)
453        Please return the number of days that are left until the
454        certificate specified in the parameter certificate expires.
455     */
456     return 10; // dummy that triggers a warning in the MUA
457 }
458
459
460 void setSignatureCertificateExpiryNearInterval( int interval )
461 {
462   config.signatureCertificateExpiryNearInterval = interval;
463 }
464
465 int signatureCertificateExpiryNearInterval( void )
466 {
467   return config.signatureCertificateExpiryNearInterval;
468 }
469
470 void setCACertificateExpiryNearWarning( bool flag )
471 {
472   config.cACertificateExpiryNearWarning = flag;
473 }
474
475 bool caCertificateExpiryNearWarning( void )
476 {
477   return config.cACertificateExpiryNearWarning;
478 }
479
480 int caCertificateDaysLeftToExpiry( const char* certificate )
481 {
482     /* PENDING(g10)
483        Please return the number of days that are left until the
484        CA certificate for the certificate specified in the parameter
485        certificate expires.
486     */
487     return 10; // dummy that triggers a warning in the MUA
488 }
489
490 void setCACertificateExpiryNearInterval( int interval )
491 {
492   config.cACertificateExpiryNearInterval = interval;
493 }
494
495 int caCertificateExpiryNearInterval( void )
496 {
497   return config.cACertificateExpiryNearInterval;
498 }
499
500 void setRootCertificateExpiryNearWarning( bool flag )
501 {
502   config.rootCertificateExpiryNearWarning = flag;
503 }
504
505 bool rootCertificateExpiryNearWarning( void )
506 {
507   return config.rootCertificateExpiryNearWarning;
508 }
509
510 int rootCertificateDaysLeftToExpiry( const char* certificate )
511 {
512     /* PENDING(g10)
513        Please return the number of days that are left until the
514        root certificate for the certificate specified in the parameter
515        certificate expires.
516     */
517     return 10; // dummy that triggers a warning in the MUA
518 }
519
520
521 void setRootCertificateExpiryNearInterval( int interval )
522 {
523   config.rootCertificateExpiryNearInterval = interval;
524 }
525
526 int rootCertificateExpiryNearInterval( void )
527 {
528   return config.rootCertificateExpiryNearInterval;
529 }
530
531
532
533
534
535
536
537
538 const char* encryptionConfigurationDialog(){ return 0; }
539
540 const char* encryptionAlgorithmDialog(){ return 0; }
541
542 const char* encryptionHandlingDialog(){ return 0; }
543
544 const char* encryptionReceiverDialog(){ return 0; }
545
546 void setEncryptionAlgorithm( EncryptionAlgorithm cryptAlg )
547 {
548   config.encryptionAlgorithm = cryptAlg;
549 }
550
551 EncryptionAlgorithm encryptionAlgorithm()
552 {
553   return config.encryptionAlgorithm;
554 }
555
556 void setEncryptEmail( EncryptEmail cryptMode )
557 {
558   config.encryptEmail = cryptMode;
559 }
560
561 EncryptEmail encryptEmail()
562 {
563   return config.encryptEmail;
564 }
565
566
567
568
569
570
571 void setWarnSendUnencrypted( bool flag )
572 {
573   config.warnSendUnencrypted = flag;
574 }
575
576 bool warnSendUnencrypted()
577 {
578   return config.warnSendUnencrypted;
579 }
580
581
582
583
584
585
586
587
588
589 void setSaveMessagesEncrypted( bool flag )
590 {
591   config.saveMessagesEncrypted = flag;
592 }
593
594 bool saveMessagesEncrypted()
595 {
596   return config.saveMessagesEncrypted;
597 }
598
599
600
601
602
603
604
605 void setCheckCertificatePath( bool flag )
606 {
607   config.checkCertificatePath = flag;
608 }
609
610 bool checkCertificatePath()
611 {
612   return config.checkCertificatePath;
613 }
614
615
616
617
618
619
620
621
622 void setCheckEncryptionCertificatePathToRoot( bool flag )
623 {
624   config.checkEncryptionCertificatePathToRoot = flag;
625 }
626
627 bool checkEncryptionCertificatePathToRoot()
628 {
629   return config.checkEncryptionCertificatePathToRoot;
630 }
631
632
633
634
635
636
637
638 void setReceiverCertificateExpiryNearWarning( bool flag )
639 {
640   config.receiverCertificateExpiryNearWarning = flag;
641 }
642
643 bool receiverCertificateExpiryNearWarning()
644 {
645   return config.receiverCertificateExpiryNearWarning;
646 }
647
648
649 int receiverCertificateDaysLeftToExpiry( const char* certificate )
650 {
651     /* PENDING(g10)
652        Please return the number of days that are left until the
653        certificate specified in the parameter certificate expires.
654     */
655     return 10; // dummy that triggers a warning in the MUA
656 }
657
658
659 void setReceiverCertificateExpiryNearWarningInterval( int interval )
660 {
661   config.receiverCertificateExpiryNearWarningInterval = interval;
662 }
663
664 int receiverCertificateExpiryNearWarningInterval()
665 {
666   return config.receiverCertificateExpiryNearWarningInterval;
667 }
668
669 void setCertificateInChainExpiryNearWarning( bool flag )
670 {
671   config.certificateInChainExpiryNearWarning = flag;
672 }
673
674 bool certificateInChainExpiryNearWarning()
675 {
676   return config.certificateInChainExpiryNearWarning;
677 }
678
679
680 int certificateInChainDaysLeftToExpiry( const char* certificate )
681 {
682     /* PENDING(g10)
683        Please return the number of days that are left until the
684        the first certificate in the chain of the specified certificate
685        expires.
686     */
687     return 10; // dummy that triggers a warning in the MUA
688 }
689
690
691 void setCertificateInChainExpiryNearWarningInterval( int interval )
692 {
693   config.certificateInChainExpiryNearWarningInterval = interval;
694 }
695
696 int certificateInChainExpiryNearWarningInterval()
697 {
698   return config.certificateInChainExpiryNearWarningInterval;
699 }
700
701 void setReceiverEmailAddressNotInCertificateWarning( bool flag )
702 {
703   config.receiverEmailAddressNotInCertificateWarning = flag;
704 }
705
706 bool receiverEmailAddressNotInCertificateWarning()
707 {
708   return config.receiverEmailAddressNotInCertificateWarning;
709 }
710
711
712
713
714
715
716
717
718 void setEncryptionUseCRLs( bool flag )
719 {
720   config.encryptionUseCRLs = flag;
721
722   /* PENDING(g10) Store this setting in gpgme and use it. If true,
723      every certificate used for encryption should be checked against
724      applicable CRLs.
725   */
726 }
727
728 bool encryptionUseCRLs()
729 {
730   return config.encryptionUseCRLs;
731 }
732
733
734 int encryptionCRLsDaysLeftToExpiry()
735 {
736     /* PENDING(g10)
737        Please return the number of days that are left until the
738        CRL used for encryption expires.
739     */
740     return 10; // dummy that triggers a warning in the MUA
741 }
742
743 void setEncryptionCRLExpiryNearWarning( bool flag )
744 {
745   config.encryptionCRLExpiryNearWarning = flag;
746 }
747
748 bool encryptionCRLExpiryNearWarning()
749 {
750   return config.encryptionCRLExpiryNearWarning;
751 }
752
753 void setEncryptionCRLNearExpiryInterval( int interval )
754 {
755   config.encryptionCRLNearExpiryInterval = interval;
756 }
757
758 int encryptionCRLNearExpiryInterval()
759 {
760   return config.encryptionCRLNearExpiryInterval;
761 }
762
763
764 const char* directoryServiceConfigurationDialog(){ return 0; }
765
766 void appendDirectoryServer( const char* servername,
767                             int         port,
768                             const char* description )
769 {
770   struct DirectoryServer *newServers = NULL;
771   newServers = realloc( config.directoryServers,
772                         (1+config.numDirectoryServers) * sizeof *newServers );
773   if( newServers ) {
774     config.directoryServers = newServers;
775     newServers[ config.numDirectoryServers ].servername =
776       malloc( 1+strlen( servername ) );
777     if( newServers[ config.numDirectoryServers ].servername ) {
778       strcpy( (char *)newServers[ config.numDirectoryServers ].servername,
779         servername );
780       newServers[ config.numDirectoryServers ].description =
781         malloc( 1+strlen(  description ) );
782       if( newServers[ config.numDirectoryServers ].description ) {
783         strcpy( (char *)newServers[ config.numDirectoryServers ].description,
784           description );
785         newServers[ config.numDirectoryServers ].port = port;
786         config.numDirectoryServers += 1;
787       }
788     }
789   }
790 }
791
792 void setDirectoryServers( struct DirectoryServer server[], unsigned int size )
793 {
794   unsigned int i;
795   int oldSize = config.numDirectoryServers;
796   struct DirectoryServer *newServers = NULL;
797   newServers = calloc ( size, sizeof *newServers );
798   if( newServers ) {
799     for( i=0; i < oldSize; ++i ) {
800       free( (char *)config.directoryServers[i].servername );
801       free( (char *)config.directoryServers[i].description );
802     }
803     free( config.directoryServers );
804     for( i=0; i < size; ++i ) {
805       newServers[ i ].servername = malloc( 1+strlen( server[i].servername ) );
806       if( newServers[ i ].servername ) {
807         strcpy( (char *)newServers[ i ].servername, server[i].servername );
808         newServers[ i ].description = malloc( 1+strlen( server[i].description ) );
809         if( newServers[ i ].description ) {
810           strcpy( (char *)newServers[ i ].description, server[i].description );
811           newServers[ i ].port = server[i].port;
812         }
813       }
814     }
815     config.directoryServers = newServers;
816     config.numDirectoryServers = size;
817   }
818 }
819
820 struct DirectoryServer * directoryServers( int* numServers )
821 {
822   if( numServers )
823     *numServers = config.numDirectoryServers;
824   return config.directoryServers;
825 };
826
827 void setCertificateSource( CertificateSource source )
828 {
829   config.certificateSource = source;
830 }
831
832 CertificateSource certificateSource()
833 {
834   return config.certificateSource;
835 }
836
837 void setCRLSource( CertificateSource source )
838 {
839   config.cRLSource = source;
840 }
841
842 CertificateSource crlSource()
843 {
844   return config.cRLSource;
845 }
846
847
848 bool certificateValidity( const char* certificate,
849                           int* level ){ return true; }
850
851
852 void storeNewCharPtr( char** dest, const char* src )
853 {
854   int sLen = strlen( src );
855   *dest = malloc( sLen + 1 );
856   strcpy( *dest, src );
857   (*dest)[sLen] = '\0';
858 }
859
860
861 bool signMessage( const char*  cleartext,
862                   const char** ciphertext,
863                   const char*  certificate,
864                   struct StructuringInfo* structuring )
865 {
866   GpgmeCtx ctx;
867   GpgmeError err;
868   GpgmeData data,  sig;
869   size_t rSLen = 0;
870   char*  rSig  = 0;
871   bool   bOk   = false;
872   int sendCerts = 1;
873
874   init_StructuringInfo( structuring );
875
876   if( !ciphertext )
877     return false;
878
879   err = gpgme_new (&ctx);
880   gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
881
882   gpgme_set_armor (ctx, 1);
883   gpgme_set_textmode (ctx, 1);
884
885   switch ( config.sendCertificates ) {
886     case SendCert_undef:
887       break;
888     case SendCert_DontSend:
889       sendCerts = 0;
890       break;
891     case SendCert_SendOwn:
892       sendCerts = 1;
893       break;
894     case SendCert_SendChainWithoutRoot:
895       sendCerts = -2;
896       break;
897     case SendCert_SendChainWithRoot:
898       sendCerts = -1;
899       break;
900     default:
901       sendCerts = 0;
902       break;
903   }
904   gpgme_set_include_certs (ctx, sendCerts);
905
906   // PENDING(g10) Implement this
907   //gpgme_set_signature_algorithm( ctx, config.signatureAlgorithm );
908
909   gpgme_data_new_from_mem (&data, cleartext,
910                             strlen( cleartext ), 1 );
911   gpgme_data_new ( &sig );
912   err = gpgme_op_sign (ctx, data, sig, GPGME_SIG_MODE_DETACH );
913
914   if (!err) {
915     rSig  = gpgme_data_release_and_get_mem( sig,  &rSLen );
916     *ciphertext = malloc( rSLen + 1 );
917     if( *ciphertext ) {
918       if( rSLen ) {
919         bOk = true;
920         strncpy((char*)*ciphertext, rSig, rSLen );
921       }
922       ((char*)(*ciphertext))[rSLen] = '\0';
923     }
924     free( rSig );
925   }
926   else {
927     gpgme_data_release( sig );
928     *ciphertext = 0;
929     // hier fehlt eine Fehlerbehandlung, falls das
930     // Signieren schiefging
931   }
932   gpgme_data_release( data );
933   gpgme_release (ctx);
934
935   if( bOk && structuring ) {
936     structuring->includeCleartext = GPGMEPLUG_SIGN_INCLUDE_CLEARTEXT;
937     structuring->makeMimeObject   = GPGMEPLUG_SIGN_MAKE_MIME_OBJECT;
938     if( structuring->makeMimeObject ) {
939       structuring->makeMultiMime  = GPGMEPLUG_SIGN_MAKE_MULTI_MIME;
940       storeNewCharPtr( &structuring->contentTypeMain,
941                        GPGMEPLUG_SIGN_CTYPE_MAIN );
942       storeNewCharPtr( &structuring->contentDispMain,
943                        GPGMEPLUG_SIGN_CDISP_MAIN );
944       storeNewCharPtr( &structuring->contentTEncMain,
945                        GPGMEPLUG_SIGN_CTENC_MAIN );
946       if( structuring->makeMultiMime ) {
947         storeNewCharPtr( &structuring->contentTypeVersion,
948                          GPGMEPLUG_SIGN_CTYPE_VERSION );
949         storeNewCharPtr( &structuring->contentDispVersion,
950                          GPGMEPLUG_SIGN_CDISP_VERSION );
951         storeNewCharPtr( &structuring->contentTEncVersion,
952                          GPGMEPLUG_SIGN_CTENC_VERSION );
953         storeNewCharPtr( &structuring->bodyTextVersion,
954                          GPGMEPLUG_SIGN_BTEXT_VERSION );
955         storeNewCharPtr( &structuring->contentTypeCode,
956                          GPGMEPLUG_SIGN_CTYPE_CODE );
957         storeNewCharPtr( &structuring->contentDispCode,
958                          GPGMEPLUG_SIGN_CDISP_CODE );
959         storeNewCharPtr( &structuring->contentTEncCode,
960                          GPGMEPLUG_SIGN_CTENC_CODE );
961       }
962     } else {
963       storeNewCharPtr( &structuring->flatTextPrefix,
964                        GPGMEPLUG_SIGN_FLAT_PREFIX );
965       storeNewCharPtr( &structuring->flatTextSeparator,
966                        GPGMEPLUG_SIGN_FLAT_SEPARATOR );
967       storeNewCharPtr( &structuring->flatTextPostfix,
968                        GPGMEPLUG_SIGN_FLAT_POSTFIX );
969     }
970   }
971   return bOk;
972 }
973
974
975 static const char*
976 sig_status_to_string( GpgmeSigStat status )
977 {
978   const char *result;
979
980   switch (status) {
981     case GPGME_SIG_STAT_NONE:
982       result = "Oops: Signature not verified";
983       break;
984     case GPGME_SIG_STAT_NOSIG:
985       result = "No signature found";
986       break;
987     case GPGME_SIG_STAT_GOOD:
988       result = "Good signature";
989       break;
990     case GPGME_SIG_STAT_BAD:
991       result = "BAD signature";
992       break;
993     case GPGME_SIG_STAT_NOKEY:
994       result = "No public key to verify the signature";
995       break;
996     case GPGME_SIG_STAT_ERROR:
997       result = "Error verifying the signature";
998       break;
999     case GPGME_SIG_STAT_DIFF:
1000       result = "Different results for signatures";
1001       break;
1002     default:
1003       result = "Error: Unknown status";
1004       break;
1005   }
1006
1007   return result;
1008 }
1009
1010
1011 bool checkMessageSignature( const char* ciphertext,
1012                             const char* signaturetext,
1013                             bool signatureIsBinary,
1014                             int signatureLen,
1015                             struct SignatureMetaData* sigmeta )
1016 {
1017   GpgmeCtx ctx;
1018   GpgmeSigStat status;
1019   GpgmeData datapart, sigpart;
1020   GpgmeError err;
1021   GpgmeKey key;
1022   time_t created;
1023   int sig_idx = 0;
1024   const char* statusStr;
1025   const char* fpr;
1026
1027   gpgme_new( &ctx );
1028   gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
1029   gpgme_set_armor (ctx,    signatureIsBinary ? 0 : 1);
1030 //  gpgme_set_textmode (ctx, signatureIsBinary ? 0 : 1);
1031
1032   gpgme_data_new_from_mem( &datapart, ciphertext,
1033                           strlen( ciphertext ), 1 );
1034
1035   gpgme_data_new_from_mem( &sigpart,
1036                            signaturetext,
1037                            signatureIsBinary
1038                            ? signatureLen
1039                            : strlen( signaturetext ),
1040                            1 );
1041
1042   gpgme_op_verify( ctx, sigpart, datapart, &status );
1043   gpgme_data_release( datapart );
1044   gpgme_data_release( sigpart );
1045
1046   /* Provide information in the sigmeta struct */
1047   /* the status string */
1048   statusStr = sig_status_to_string( status );
1049   sigmeta->status = malloc( strlen( statusStr ) + 1 );
1050   if( sigmeta->status ) {
1051     strcpy( sigmeta->status, statusStr );
1052     sigmeta->status[strlen( statusStr )] = '\0';
1053   } else
1054     ; // nothing to do, is already 0
1055
1056   // Extended information for any number of signatures.
1057   fpr = gpgme_get_sig_status( ctx, sig_idx, &status, &created );
1058   sigmeta->extended_info = 0;
1059   while( fpr != NULL ) {
1060     struct tm* ctime_val;
1061     const char* sig_status;
1062
1063     void* realloc_return = realloc( sigmeta->extended_info,
1064                                     sizeof( struct SignatureMetaDataExtendedInfo ) * ( sig_idx + 1 ) );
1065     if( realloc_return ) {
1066       sigmeta->extended_info = realloc_return;
1067       // the creation time
1068       sigmeta->extended_info[sig_idx].creation_time = malloc( sizeof( struct tm ) );
1069       if( sigmeta->extended_info[sig_idx].creation_time ) {
1070         ctime_val = localtime( &created );
1071         memcpy( sigmeta->extended_info[sig_idx].creation_time,
1072                 ctime_val, sizeof( struct tm ) );
1073       }
1074
1075       err = gpgme_get_sig_key (ctx, sig_idx, &key);
1076       sig_status = sig_status_to_string( status );
1077       sigmeta->extended_info[sig_idx].status_text = malloc( strlen( sig_status ) + 1 );
1078       if( sigmeta->extended_info[sig_idx].status_text ) {
1079         strcpy( sigmeta->extended_info[sig_idx].status_text,
1080                 sig_status );
1081         sigmeta->extended_info[sig_idx].status_text[strlen( sig_status )] = '\0';
1082       }
1083
1084       sigmeta->extended_info[sig_idx].fingerprint = malloc( strlen( fpr ) + 1 );
1085       if( sigmeta->extended_info[sig_idx].fingerprint ) {
1086         strcpy( sigmeta->extended_info[sig_idx].fingerprint, fpr );
1087         sigmeta->extended_info[sig_idx].fingerprint[strlen( fpr )] = '\0';
1088       }
1089     } else
1090       break; // if allocation fails once, it isn't likely to
1091               // succeed the next time either
1092
1093     fpr = gpgme_get_sig_status (ctx, ++sig_idx, &status, &created);
1094   }
1095   sigmeta->extended_info_count = sig_idx;
1096   sigmeta->nota_xml = gpgme_get_notation( ctx );
1097   sigmeta->status_code = status;
1098
1099   gpgme_release( ctx );
1100   return ( status == GPGME_SIG_STAT_GOOD );
1101 }
1102
1103 bool storeCertificatesFromMessage(
1104         const char* ciphertext ){ return true; }
1105
1106
1107 /* returns address if address doesn't contain a <xxx> part
1108  * else it returns a new string xxx and frees address
1109  */
1110 static char* parseAddress( char* address )
1111 {
1112   char* result = address;
1113   char* i;
1114   char* j;
1115   if( !result ) return result;
1116   i = index( address, '<' );
1117   if( i ) {
1118     j = index( i+1, '>' );
1119     if( j == NULL ) j = address+strlen(address);
1120     result = malloc( j-i );
1121     strncpy( result, i+1, j-i-1 );
1122     result[j-i-1] = '\0';
1123     free( address );
1124   } else {
1125     i = address;
1126     j = i+strlen(address);
1127   }
1128   {
1129     /* remove surrounding whitespace */
1130     char* k = result+(j-i-1);
1131     char* l = result;
1132     while( isspace( *l ) ) ++l;
1133     while( isspace( *k ) ) --k;
1134     if( l != result || k != result+(j-i-1) ) {
1135       char* result2 = malloc( k-l+2 );
1136       strncpy( result2, l, k-l+1 );
1137       result2[k-l+1] = '\0';
1138       free(result);
1139       result = result2;
1140     }
1141   }
1142   return result;
1143 }
1144
1145 static char* nextAddress( const char** address )
1146 {
1147   const char *start = *address;
1148   char* result = NULL;
1149   int quote = 0;
1150   int comment = 0;
1151   int found = 0;
1152   if( *address == NULL ) return NULL;
1153   while( **address ) {
1154
1155     switch( **address ) {
1156     case '\\': /* escaped character */
1157       ++(*address);
1158       break;
1159     case '"':
1160       if( comment == 0 ) {
1161         if( quote > 0 ) --quote;
1162         else ++quote;
1163       }
1164       break;
1165     case '(': /* comment start */
1166       if( quote == 0 ) ++comment;
1167       break;
1168     case ')': /* comment end */
1169       if( quote == 0 ) --comment;
1170       break;
1171     case '\0':
1172     case '\1': /* delimiter */
1173       if( quote == 0 && comment == 0 ) {
1174         found = 1;
1175       }
1176       break;
1177     }
1178     ++(*address);
1179     if( found ) break;
1180   }
1181   if( found || **address == 0 ) {
1182     size_t len;
1183     len = *address - start;
1184     if( len > 0 ) {
1185       if( **address != 0 ) --len;
1186       result = malloc( len*sizeof(char)+1 );
1187       strncpy( result, start, len );
1188       result[len] = '\0';
1189     }
1190   }
1191   return parseAddress(result);
1192 }
1193
1194 /*
1195   Find all certificate for a given addressee and return them in a
1196   '\1' separated list.
1197   NOTE: The certificate parameter must point to an allready allocated
1198   block of memory which is large enough to hold the complete list.
1199 */
1200 bool findCertificates( const char* addressee, char** certificates )
1201 {
1202   GpgmeCtx ctx;
1203   GpgmeError err;
1204   GpgmeKey rKey;
1205   const char *s;
1206   const char *s2;
1207   bool bOk = false;
1208   
1209   strcpy( *certificates, "" );
1210
1211   gpgme_new (&ctx);
1212   gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
1213
1214   err = gpgme_op_keylist_start(ctx, addressee, 0);
1215   while( GPGME_No_Error == err ) {
1216     err = gpgme_op_keylist_next(ctx, &rKey);
1217     if( GPGME_No_Error == err ) {
1218       bOk = true;
1219       s = gpgme_key_get_string_attr (rKey, GPGME_ATTR_USERID, NULL, 0);
1220       if( s ) {
1221         s2 = gpgme_key_get_string_attr (rKey, GPGME_ATTR_FPR, NULL, 0);
1222         if( s2 ) {
1223           strcat( *certificates, s );
1224           strcat( *certificates, "    (" );
1225           strcat( *certificates, s2 );
1226           strcat( *certificates, ")\1" );
1227         }
1228       }
1229     }
1230   }
1231   gpgme_op_keylist_end( ctx );
1232   return bOk;
1233 }
1234
1235 bool encryptMessage( const char*  cleartext,
1236                      const char** ciphertext,
1237                      const char*  certificate,
1238                      struct StructuringInfo* structuring )
1239 {
1240   GpgmeCtx ctx;
1241   GpgmeError err;
1242   GpgmeData gCiphertext, gPlaintext;
1243   GpgmeRecipients rset;
1244   size_t rCLen = 0;
1245   char*  rCiph = 0;
1246   bool   bOk   = false;
1247
1248   init_StructuringInfo( structuring );
1249
1250   gpgme_new (&ctx);
1251   gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
1252
1253   gpgme_set_armor (ctx, 1);
1254   gpgme_set_textmode (ctx, 1);
1255
1256   gpgme_data_new_from_mem (&gPlaintext, cleartext,
1257                             1+strlen( cleartext ), 1 );
1258   err = gpgme_data_new ( &gCiphertext );
1259
1260   gpgme_recipients_new (&rset);
1261
1262   /*
1263   if( GPGMEPLUG_PROTOCOL == GPGME_PROTOCOL_CMS )
1264   {
1265     gpgme_recipients_add_name_with_validity (rset,
1266       "/CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=DĂĽsseldorf,C=DE",
1267       GPGME_VALIDITY_FULL );
1268     fputs( "\nGPGSMPLUG encryptMessage() using test key of Aegypten Project\n", stderr );
1269   }
1270   else
1271   */
1272   {
1273     const char* p = certificate;
1274     char* tok;
1275     while( (tok = nextAddress( &p ) ) != 0 ) {
1276       if( GPGMEPLUG_PROTOCOL == GPGME_PROTOCOL_CMS )
1277         gpgme_recipients_add_name_with_validity (rset, tok, GPGME_VALIDITY_FULL );
1278       else
1279         gpgme_recipients_add_name (rset, tok);
1280       fprintf( stderr, "\nGPGMEPLUG encryptMessage() using addressee %s\n", tok );
1281       free(tok);
1282     }
1283   }
1284
1285   // PENDING(g10) Implement this
1286   // Possible values: RSA = 1, SHA1 = 2, TripleDES = 3
1287   //gpgme_set_encryption_algorithm( ctx, config.encryptionAlgorithm );
1288
1289
1290   // PENDING(g10) Implement this
1291   // gpgme_set_encryption_check_certificate_path(
1292   // config.checkCertificatePath )
1293
1294   // PENDING(g10) Implement this
1295   // gpgme_set_encryption_check_certificate_path_to_root(
1296   // config.checkEncryptionCertificatePathToRoot )
1297
1298
1299   err = gpgme_op_encrypt (ctx, rset, gPlaintext, gCiphertext );
1300   if( err )
1301     fprintf( stderr, "gpgme_op_encrypt() returned this error code:  %i\n\n", err );
1302
1303   gpgme_recipients_release (rset);
1304   gpgme_data_release (gPlaintext);
1305
1306   if( !err ) {
1307     rCiph = gpgme_data_release_and_get_mem( gCiphertext,  &rCLen );
1308     *ciphertext = malloc( rCLen + 1 );
1309     if( *ciphertext ) {
1310       if( rCLen ) {
1311         bOk = true;
1312         strncpy((char*)*ciphertext, rCiph, rCLen );
1313       }
1314       ((char*)(*ciphertext))[rCLen] = 0;
1315     }
1316     free( rCiph );
1317   }
1318   else {
1319     gpgme_data_release ( gCiphertext );
1320     *ciphertext = 0;
1321     // hier fehlt eine Fehlerbehandlung: fuer einen Recipient nur ein
1322     // untrusted key (oder gar keiner) gefunden wurde, verweigert gpg
1323     // das signieren.
1324   }
1325
1326   gpgme_release (ctx);
1327
1328   fflush( stderr );
1329
1330   if( bOk && structuring ) {
1331     structuring->includeCleartext = GPGMEPLUG_ENC_INCLUDE_CLEARTEXT;
1332     structuring->makeMimeObject   = GPGMEPLUG_ENC_MAKE_MIME_OBJECT;
1333     if( structuring->makeMimeObject ) {
1334       structuring->makeMultiMime  = GPGMEPLUG_ENC_MAKE_MULTI_MIME;
1335       storeNewCharPtr( &structuring->contentTypeMain,
1336                        GPGMEPLUG_ENC_CTYPE_MAIN );
1337       storeNewCharPtr( &structuring->contentDispMain,
1338                        GPGMEPLUG_ENC_CDISP_MAIN );
1339       storeNewCharPtr( &structuring->contentTEncMain,
1340                        GPGMEPLUG_ENC_CTENC_MAIN );
1341       if( structuring->makeMultiMime ) {
1342         storeNewCharPtr( &structuring->contentTypeVersion,
1343                          GPGMEPLUG_ENC_CTYPE_VERSION );
1344         storeNewCharPtr( &structuring->contentDispVersion,
1345                          GPGMEPLUG_ENC_CDISP_VERSION );
1346         storeNewCharPtr( &structuring->contentTEncVersion,
1347                          GPGMEPLUG_ENC_CTENC_VERSION );
1348         storeNewCharPtr( &structuring->bodyTextVersion,
1349                          GPGMEPLUG_ENC_BTEXT_VERSION );
1350         storeNewCharPtr( &structuring->contentTypeCode,
1351                          GPGMEPLUG_ENC_CTYPE_CODE );
1352         storeNewCharPtr( &structuring->contentDispCode,
1353                          GPGMEPLUG_ENC_CDISP_CODE );
1354         storeNewCharPtr( &structuring->contentTEncCode,
1355                          GPGMEPLUG_ENC_CTENC_CODE );
1356       }
1357     } else {
1358       storeNewCharPtr( &structuring->flatTextPrefix,
1359                        GPGMEPLUG_ENC_FLAT_PREFIX );
1360       storeNewCharPtr( &structuring->flatTextSeparator,
1361                        GPGMEPLUG_ENC_FLAT_SEPARATOR );
1362       storeNewCharPtr( &structuring->flatTextPostfix,
1363                        GPGMEPLUG_ENC_FLAT_POSTFIX );
1364     }
1365   }
1366   return bOk;
1367 }
1368
1369
1370 bool encryptAndSignMessage( const char* cleartext,
1371                             const char** ciphertext,
1372                             const char* certificate,
1373                             struct StructuringInfo* structuring )
1374 {
1375   bool bOk;
1376
1377   init_StructuringInfo( structuring );
1378
1379   bOk = false;
1380
1381   // implementation of this function is still missing
1382
1383   if( bOk && structuring ) {
1384     structuring->includeCleartext = GPGMEPLUG_ENCSIGN_INCLUDE_CLEARTEXT;
1385     structuring->makeMimeObject   = GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT;
1386     if( structuring->makeMimeObject ) {
1387       structuring->makeMultiMime  = GPGMEPLUG_ENCSIGN_MAKE_MULTI_MIME;
1388       storeNewCharPtr( &structuring->contentTypeMain,
1389                        GPGMEPLUG_ENCSIGN_CTYPE_MAIN );
1390       storeNewCharPtr( &structuring->contentDispMain,
1391                        GPGMEPLUG_ENCSIGN_CDISP_MAIN );
1392       storeNewCharPtr( &structuring->contentTEncMain,
1393                        GPGMEPLUG_ENCSIGN_CTENC_MAIN );
1394       if( structuring->makeMultiMime ) {
1395         storeNewCharPtr( &structuring->contentTypeVersion,
1396                          GPGMEPLUG_ENCSIGN_CTYPE_VERSION );
1397         storeNewCharPtr( &structuring->contentDispVersion,
1398                          GPGMEPLUG_ENCSIGN_CDISP_VERSION );
1399         storeNewCharPtr( &structuring->contentTEncVersion,
1400                          GPGMEPLUG_ENCSIGN_CTENC_VERSION );
1401         storeNewCharPtr( &structuring->bodyTextVersion,
1402                          GPGMEPLUG_ENCSIGN_BTEXT_VERSION );
1403         storeNewCharPtr( &structuring->contentTypeCode,
1404                          GPGMEPLUG_ENCSIGN_CTYPE_CODE );
1405         storeNewCharPtr( &structuring->contentDispCode,
1406                          GPGMEPLUG_ENCSIGN_CDISP_CODE );
1407         storeNewCharPtr( &structuring->contentTEncCode,
1408                          GPGMEPLUG_ENCSIGN_CTENC_CODE );
1409       }
1410     } else {
1411       storeNewCharPtr( &structuring->flatTextPrefix,
1412                        GPGMEPLUG_ENCSIGN_FLAT_PREFIX );
1413       storeNewCharPtr( &structuring->flatTextSeparator,
1414                        GPGMEPLUG_ENCSIGN_FLAT_SEPARATOR );
1415       storeNewCharPtr( &structuring->flatTextPostfix,
1416                        GPGMEPLUG_ENCSIGN_FLAT_POSTFIX );
1417     }
1418   }
1419   return bOk;
1420 }
1421
1422 bool decryptMessage( const char* ciphertext,
1423                      const char** cleartext,
1424                      const char* certificate )
1425 {
1426   GpgmeCtx ctx;
1427   GpgmeError err;
1428   GpgmeData gCiphertext, gPlaintext;
1429   size_t rCLen = 0;
1430   char*  rCiph = 0;
1431   bool bOk = false;
1432
1433   if( !ciphertext )
1434     return false;
1435
1436   err = gpgme_new (&ctx);
1437   gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
1438
1439   gpgme_data_new_from_mem( &gCiphertext, ciphertext,
1440                            1+strlen( ciphertext ), 1 );
1441   gpgme_data_new( &gPlaintext );
1442
1443   gpgme_op_decrypt( ctx, gCiphertext, gPlaintext );
1444   gpgme_data_release( gCiphertext );
1445
1446   rCiph = gpgme_data_release_and_get_mem( gPlaintext,  &rCLen );
1447
1448   *cleartext = malloc( rCLen + 1 );
1449   if( *cleartext ) {
1450       if( rCLen ) {
1451           bOk = true;
1452           strncpy((char*)*cleartext, rCiph, rCLen );
1453       }
1454       ((char*)(*cleartext))[rCLen] = 0;
1455   }
1456
1457   free( rCiph );
1458   gpgme_release( ctx );
1459   return bOk;
1460 }
1461
1462 bool decryptAndCheckMessage( const char* ciphertext,
1463           const char** cleartext, const char* certificate,
1464           struct SignatureMetaData* sigmeta ){ return true; }
1465
1466
1467 const char* requestCertificateDialog(){ return 0; }
1468
1469 bool requestDecentralCertificate( const char* name, const char*
1470           email, const char* organization, const char* department,
1471           const char* ca_address ){ return true; }
1472
1473 bool requestCentralCertificateAndPSE( const char* name,
1474           const char* email, const char* organization, const char* department,
1475           const char* ca_address ){ return true; }
1476
1477 bool createPSE(){ return true; }
1478
1479 bool registerCertificate( const char* certificate ){ return true; }
1480
1481 bool requestCertificateProlongation( const char* certificate,
1482                                      const char* ca_address ){ return true; }
1483
1484 const char* certificateChain(){ return 0; }
1485
1486 bool deleteCertificate( const char* certificate ){ return true; }
1487
1488 bool archiveCertificate( const char* certificate ){ return true; }
1489
1490
1491 const char* displayCRL(){ return 0; }
1492
1493 void updateCRL(){}