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