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