create signature (and write it to stdout for testing)
[gpgme.git] / gpgmeplug / gpgmeplug.c
1 /* -*- Mode: C -*-
2
3   $Id$
4
5   GPGMEPLUG - an GPGME based cryptography plug-in following
6               the common CRYPTPLUG specification.
7
8   Copyright (C) 2001 by Klarälvdalens Datakonsult AB
9
10   GPGMEPLUG is free software; you can redistribute it and/or modify
11   it under the terms of GNU General Public License as published by
12   the Free Software Foundation; version 2 of the License.
13
14   GPGMEPLUG is distributed in the hope that it will be useful,
15   it under the terms of GNU General Public License as published by
16   the Free Software Foundation; version 2 of the License
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20
21   You should have received a copy of the GNU General Public License
22   along with this program; if not, write to the Free Software
23   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
24 */
25
26
27
28 /*! \file gpgmeplug.c
29     \brief GPGME implementation of CRYPTPLUG following the
30     specification located in common API header cryptplug.h.
31
32     CRYPTPLUG is an independent cryptography plug-in API
33     developed for Sphinx-enabeling KMail and Mutt.
34
35     CRYPTPLUG was designed for the Aegypten project, but it may
36     be used by 3rd party developers as well to design pluggable
37     crypto backends for the above mentioned MUAs.
38
39     \note All string parameters appearing in this API are to be
40     interpreted as UTF-8 encoded.
41
42     \see cryptplug.h
43 */
44
45 #ifdef HAVE_CONFIG_H
46 #include <config.h>
47 #endif
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <assert.h>
52 #include <errno.h>
53
54 #include "../gpgme/gpgme.h"
55 #include "../gpgme/util.h"
56
57 #include "cryptplug.h"
58
59
60 typedef struct {
61   const char*             signatureKeyCertificate;
62   SignatureAlgorithm      signatureAlgorithm;
63   SendCertificates        sendCertificates;
64   SignEmail               signEmail;
65   bool                    saveSentSignatures;
66   bool                    warnNoCertificate;
67   PinRequests             numPINRequests;
68   bool                    checkSignatureCertificatePathToRoot;
69   bool                    signatureUseCRLs;
70   EncryptionAlgorithm     encryptionAlgorithm;
71   EncryptEmail            encryptEmail;
72   bool                    saveMessagesEncrypted;
73   bool                    checkEncryptionCertificatePathToRoot;
74   bool                    encryptionUseCRLs;
75   bool                    encryptionCRLExpiryNearWarning;
76   int                     encryptionCRLNearExpiryInterval;
77   struct DirectoryServer *directoryServers;
78   unsigned int            numDirectoryServers;
79   CertificateSource       certificateSource;
80   CertificateSource       cRLSource;
81   bool                    warnSendUnsigned;
82   int                     numPINRequestsInterval;
83   bool                    signatureCertificateExpiryNearWarning;
84   int                     signatureCertificateExpiryNearInterval;
85   bool                    cACertificateExpiryNearWarning;
86   int                     cACertificateExpiryNearInterval;
87   bool                    rootCertificateExpiryNearWarning;
88   int                     rootCertificateExpiryNearInterval;
89   bool                    warnSendUnencrypted;
90   bool                    checkCertificatePath;
91   bool                    receiverCertificateExpiryNearWarning;
92   int                     receiverCertificateExpiryNearWarningInterval;
93   bool                    certificateInChainExpiryNearWarning;
94   int                     certificateInChainExpiryNearWarningInterval;
95   bool                    receiverEmailAddressNotInCertificateWarning;
96 } Config;
97
98
99 Config config;
100
101
102 #define NEAR_EXPIRY 14
103
104 bool initialize()
105 {
106   config.signatureKeyCertificate              = "";
107   config.signatureAlgorithm                   = SignAlg_SHA1;
108   config.sendCertificates                     = SendCert_SendChainWithRoot;
109   config.signEmail                            = SignEmail_SignAll;
110   config.saveSentSignatures                   = true;
111   config.warnNoCertificate                    = true;
112   config.numPINRequests                       = PinRequest_Always;
113   config.checkSignatureCertificatePathToRoot  = true;
114   config.signatureUseCRLs                     = true;
115   config.encryptionAlgorithm                  = EncryptAlg_RSA;
116   config.encryptEmail                         = EncryptEmail_Ask;
117   config.saveMessagesEncrypted                = true;
118   config.checkEncryptionCertificatePathToRoot = true;
119   config.encryptionUseCRLs                    = true;
120   config.encryptionCRLExpiryNearWarning       = true;
121   config.encryptionCRLNearExpiryInterval      = NEAR_EXPIRY;
122   config.directoryServers                     = NULL;
123   config.numDirectoryServers                  = 0;
124   config.certificateSource                    = CertSrc_Server;
125   config.cRLSource                            = CertSrc_Server;
126   config.warnSendUnsigned                             = true;
127   config.numPINRequestsInterval                       = NEAR_EXPIRY;
128   config.signatureCertificateExpiryNearWarning        = true;
129   config.signatureCertificateExpiryNearInterval       = NEAR_EXPIRY;
130   config.cACertificateExpiryNearWarning               = true;
131   config.cACertificateExpiryNearInterval              = NEAR_EXPIRY;
132   config.rootCertificateExpiryNearWarning             = true;
133   config.rootCertificateExpiryNearInterval            = NEAR_EXPIRY;
134   config.warnSendUnencrypted                          = false;
135   config.checkCertificatePath                         = true;
136   config.receiverCertificateExpiryNearWarning         = true;
137   config.receiverCertificateExpiryNearWarningInterval = NEAR_EXPIRY;
138   config.certificateInChainExpiryNearWarning          = true;
139   config.certificateInChainExpiryNearWarningInterval  = NEAR_EXPIRY;
140   config.receiverEmailAddressNotInCertificateWarning  = true;
141
142   return true;
143 };
144
145
146 void deinitialize()
147 {
148   unsigned int i;
149   for( i = 0; i < config.numDirectoryServers; ++i ) {
150     free( (char *)config.directoryServers[i].servername );
151     free( (char *)config.directoryServers[i].description );
152   }
153   free( config.directoryServers );
154 }
155
156
157 bool hasFeature( Feature flag )
158 {
159   switch ( flag ) {
160     case CryptPlugFeat_SignMessages:              return true;
161     case CryptPlugFeat_VerifySignatures:          return true;
162     case CryptPlugFeat_EncryptMessages:           return true;
163     case CryptPlugFeat_DecryptMessages:           return true;
164     // undefined or not yet implemented:
165     case CryptPlugFeat_undef:                     return false;
166     default:                                      return false;
167   }
168 }
169
170
171 void unsafeStationery( void** pixmap, const char** menutext, char* accel,
172           const char** tooltip, const char** statusbartext ){}
173
174 void signedStationery( void** pixmap, const char** menutext, char* accel,
175           const char** tooltip, const char** statusbartext ){}
176
177 void encryptedStationery( void** pixmap, const char**
178           menutext, char* accel,
179           const char** tooltip, const char** statusbartext ){}
180
181 void signedEncryptedStationery( void** pixmap, const char**
182           menutext, char* accel,
183           const char** tooltip, const char** statusbartext ){}
184
185 const char* signatureConfigurationDialog(){ return 0; }
186
187 const char* signatureKeySelectionDialog(){ return 0; }
188
189 const char* signatureAlgorithmDialog(){ return 0; }
190
191 const char* signatureHandlingDialog(){ return 0; }
192
193 void setSignatureKeyCertificate( const char* certificate )
194 {
195   config.signatureKeyCertificate = certificate;
196 }
197
198 const char* signatureKeyCertificate()
199 {
200   return config.signatureKeyCertificate;
201 }
202
203 void setSignatureAlgorithm( SignatureAlgorithm sigAlg )
204 {
205   config.signatureAlgorithm = sigAlg;
206 }
207
208 SignatureAlgorithm signatureAlgorithm()
209 {
210   return config.signatureAlgorithm;
211 }
212
213 void setSendCertificates( SendCertificates sendCert )
214 {
215   config.sendCertificates = sendCert;
216 }
217
218 SendCertificates sendCertificates()
219 {
220   return config.sendCertificates;
221 }
222
223 void setSignEmail( SignEmail signMail )
224 {
225   config.signEmail = signMail;
226 }
227
228 SignEmail signEmail()
229 {
230   return config.signEmail;
231 }
232
233
234
235
236
237 void setWarnSendUnsigned( bool flag )
238 {
239   config.warnSendUnsigned = flag;
240 }
241
242 bool warnSendUnsigned()
243 {
244   return config.warnSendUnsigned;
245 }
246
247
248
249
250
251
252 void setSaveSentSignatures( bool flag )
253 {
254   config.saveSentSignatures = flag;
255 }
256
257 bool saveSentSignatures()
258 {
259   return config.saveSentSignatures;
260 }
261
262 void setWarnNoCertificate( bool flag )
263 {
264   config.warnNoCertificate = flag;
265 }
266
267 bool warnNoCertificate()
268 {
269   return config.warnNoCertificate;
270 }
271
272 void setNumPINRequests( PinRequests reqMode )
273 {
274   config.numPINRequests = reqMode;
275 }
276
277 PinRequests numPINRequests()
278 {
279   return config.numPINRequests;
280 }
281
282
283
284
285
286 void setNumPINRequestsInterval( int interval )
287 {
288   config.numPINRequestsInterval = interval;
289 }
290
291 int numPINRequestsInterval()
292 {
293   return config.numPINRequestsInterval;
294 }
295
296
297
298
299
300
301
302 void setCheckSignatureCertificatePathToRoot( bool flag )
303 {
304   config.checkSignatureCertificatePathToRoot = flag;
305 }
306
307 bool checkSignatureCertificatePathToRoot()
308 {
309   return config.checkSignatureCertificatePathToRoot;
310 }
311
312 void setSignatureUseCRLs( bool flag )
313 {
314   config.signatureUseCRLs = flag;
315 }
316
317 bool signatureUseCRLs()
318 {
319   return config.signatureUseCRLs;
320 }
321
322
323
324
325
326
327 void setSignatureCertificateExpiryNearWarning( bool flag )
328 {
329   config.signatureCertificateExpiryNearWarning = flag;
330 }
331
332 bool signatureCertificateExpiryNearWarning( void )
333 {
334   return config.signatureCertificateExpiryNearWarning;
335 }
336
337 void setSignatureCertificateExpiryNearInterval( int interval )
338 {
339   config.signatureCertificateExpiryNearInterval = interval;
340 }
341
342 int signatureCertificateExpiryNearInterval( void )
343 {
344   return config.signatureCertificateExpiryNearInterval;
345 }
346
347 void setCACertificateExpiryNearWarning( bool flag )
348 {
349   config.cACertificateExpiryNearWarning = flag;
350 }
351
352 bool caCertificateExpiryNearWarning( void )
353 {
354   return config.cACertificateExpiryNearWarning;
355 }
356
357 void setCACertificateExpiryNearInterval( int interval )
358 {
359   config.cACertificateExpiryNearInterval = interval;
360 }
361
362 int caCertificateExpiryNearInterval( void )
363 {
364   return config.cACertificateExpiryNearInterval;
365 }
366
367 void setRootCertificateExpiryNearWarning( bool flag )
368 {
369   config.rootCertificateExpiryNearWarning = flag;
370 }
371
372 bool rootCertificateExpiryNearWarning( void )
373 {
374   return config.rootCertificateExpiryNearWarning;
375 }
376
377 void setRootCertificateExpiryNearInterval( int interval )
378 {
379   config.rootCertificateExpiryNearInterval = interval;
380 }
381
382 int rootCertificateExpiryNearInterval( void )
383 {
384   return config.rootCertificateExpiryNearInterval;
385 }
386
387
388
389
390
391
392
393
394 const char* encryptionConfigurationDialog(){ return 0; }
395
396 const char* encryptionAlgorithmDialog(){ return 0; }
397
398 const char* encryptionHandlingDialog(){ return 0; }
399
400 const char* encryptionReceiverDialog(){ return 0; }
401
402 void setEncryptionAlgorithm( EncryptionAlgorithm cryptAlg )
403 {
404   config.encryptionAlgorithm = cryptAlg;
405 }
406
407 EncryptionAlgorithm encryptionAlgorithm()
408 {
409   return config.encryptionAlgorithm;
410 }
411
412 void setEncryptEmail( EncryptEmail cryptMode )
413 {
414   config.encryptEmail = cryptMode;
415 }
416
417 EncryptEmail encryptEmail()
418 {
419   return config.encryptEmail;
420 }
421
422
423
424
425
426
427 void setWarnSendUnencrypted( bool flag )
428 {
429   config.warnSendUnencrypted = flag;
430 }
431
432 bool warnSendUnencrypted()
433 {
434   return config.warnSendUnencrypted;
435 }
436
437
438
439
440
441
442
443
444
445 void setSaveMessagesEncrypted( bool flag )
446 {
447   config.saveMessagesEncrypted = flag;
448 }
449
450 bool saveMessagesEncrypted()
451 {
452   return config.saveMessagesEncrypted;
453 }
454
455
456
457
458
459
460
461 void setCheckCertificatePath( bool flag )
462 {
463   config.checkCertificatePath = flag;
464 }
465
466 bool checkCertificatePath()
467 {
468   return config.checkCertificatePath;
469 }
470
471
472
473
474
475
476
477
478 void setCheckEncryptionCertificatePathToRoot( bool flag )
479 {
480   config.checkEncryptionCertificatePathToRoot = flag;
481 }
482
483 bool checkEncryptionCertificatePathToRoot()
484 {
485   return config.checkEncryptionCertificatePathToRoot;
486 }
487
488
489
490
491
492
493
494 void setReceiverCertificateExpiryNearWarning( bool flag )
495 {
496   config.receiverCertificateExpiryNearWarning = flag;
497 }
498
499 bool receiverCertificateExpiryNearWarning()
500 {
501   return config.receiverCertificateExpiryNearWarning;
502 }
503
504 void setReceiverCertificateExpiryNearWarningInterval( int interval )
505 {
506   config.receiverCertificateExpiryNearWarningInterval = interval;
507 }
508
509 int receiverCertificateExpiryNearWarningInterval()
510 {
511   return config.receiverCertificateExpiryNearWarningInterval;
512 }
513
514 void setCertificateInChainExpiryNearWarning( bool flag )
515 {
516   config.certificateInChainExpiryNearWarning = flag;
517 }
518
519 bool certificateInChainExpiryNearWarning()
520 {
521   return config.certificateInChainExpiryNearWarning;
522 }
523
524 void setCertificateInChainExpiryNearWarningInterval( int interval )
525 {
526   config.certificateInChainExpiryNearWarningInterval = interval;
527 }
528
529 int certificateInChainExpiryNearWarningInterval()
530 {
531   return config.certificateInChainExpiryNearWarningInterval;
532 }
533
534 void setReceiverEmailAddressNotInCertificateWarning( bool flag )
535 {
536   config.receiverEmailAddressNotInCertificateWarning = flag;
537 }
538
539 bool receiverEmailAddressNotInCertificateWarning()
540 {
541   return config.receiverEmailAddressNotInCertificateWarning;
542 }
543
544
545
546
547
548
549
550
551 void setEncryptionUseCRLs( bool flag )
552 {
553   config.encryptionUseCRLs = flag;
554 }
555
556 bool encryptionUseCRLs()
557 {
558   return config.encryptionUseCRLs;
559 }
560
561 void setEncryptionCRLExpiryNearWarning( bool flag )
562 {
563   config.encryptionCRLExpiryNearWarning = flag;
564 }
565
566 bool encryptionCRLExpiryNearWarning()
567 {
568   return config.encryptionCRLExpiryNearWarning;
569 }
570
571 void setEncryptionCRLNearExpiryInterval( int interval )
572 {
573   config.encryptionCRLNearExpiryInterval = interval;
574 }
575
576 int encryptionCRLNearExpiryInterval()
577 {
578   return config.encryptionCRLNearExpiryInterval;
579 }
580
581
582 const char* directoryServiceConfigurationDialog(){ return 0; }
583
584 void appendDirectoryServer( const char* servername,
585                             int         port,
586                             const char* description )
587 {
588   struct DirectoryServer *newServers = NULL;
589   newServers = realloc( config.directoryServers,
590                         (1+config.numDirectoryServers) * sizeof *newServers );
591   if( newServers ) {
592     config.directoryServers = newServers;
593     newServers[ config.numDirectoryServers ].servername =
594       malloc( strlen( servername ) );
595     if( newServers[ config.numDirectoryServers ].servername ) {
596       strcpy( (char *)newServers[ config.numDirectoryServers ].servername,
597         servername );
598       newServers[ config.numDirectoryServers ].description =
599         malloc( strlen(  description ) );
600       if( newServers[ config.numDirectoryServers ].description ) {
601         strcpy( (char *)newServers[ config.numDirectoryServers ].description,
602           description );
603         newServers[ config.numDirectoryServers ].port = port;
604         config.numDirectoryServers += 1;
605       }
606     }
607   }
608 }
609
610 void setDirectoryServers( struct DirectoryServer server[], unsigned int size )
611 {
612   unsigned int i;
613   int oldSize = config.numDirectoryServers;
614   struct DirectoryServer *newServers = NULL;
615   newServers = calloc ( size, sizeof *newServers );
616   if( newServers ) {
617     for( i=0; i < oldSize; ++i ) {
618       free( (char *)config.directoryServers[i].servername );
619       free( (char *)config.directoryServers[i].description );
620     }
621     free( config.directoryServers );
622     for( i=0; i < size; ++i ) {
623       newServers[ i ].servername = malloc( strlen( server[i].servername ) );
624       if( newServers[ i ].servername ) {
625         strcpy( (char *)newServers[ i ].servername, server[i].servername );
626         newServers[ i ].description = malloc( strlen( server[i].description ) );
627         if( newServers[ i ].description ) {
628           strcpy( (char *)newServers[ i ].description, server[i].description );
629           newServers[ i ].port = server[i].port;
630         }
631       }
632     }
633     config.directoryServers = newServers;
634     config.numDirectoryServers = size;
635   }
636 }
637
638 struct DirectoryServer * directoryServers( int* numServers )
639 {
640   if( numServers )
641     *numServers = config.numDirectoryServers;
642   return config.directoryServers;
643 };
644
645 void setCertificateSource( CertificateSource source )
646 {
647   config.certificateSource = source;
648 }
649
650 CertificateSource certificateSource()
651 {
652   return config.certificateSource;
653 }
654
655 void setCRLSource( CertificateSource source )
656 {
657   config.cRLSource = source;
658 }
659
660 CertificateSource crlSource()
661 {
662   return config.cRLSource;
663 }
664
665
666 bool certificateValidity( const char* certificate,
667                           int* level ){ return true; }
668
669
670 bool signMessage( const char*  cleartext,
671                   const char** ciphertext,
672                   const char*  certificate )
673 {
674   GpgmeCtx ctx;
675   GpgmeData data, sig;
676
677   char buf[1024];
678   size_t nread;
679
680
681   gpgme_new (&ctx);
682   gpgme_set_armor (ctx, 1);
683   gpgme_set_textmode (ctx, 1);
684
685   gpgme_data_new_from_mem (&data, cleartext,
686                             strlen( cleartext ), 1 );
687   gpgme_data_new ( &sig );
688   gpgme_op_sign (ctx, data, sig, GPGME_SIG_MODE_DETACH );
689
690   fputs ( "Content-Type: multipart/signed;\r\n"
691           "              protocol=\"application/pgp-signature\";\r\n"
692           "              boundary=\"42=.42=.42=.42\"\r\n"
693           "\r\n--42=.42=.42=.42\r\n",
694           stdout );
695
696   gpgme_data_rewind (data);
697   while ( !gpgme_data_read (data, buf, sizeof buf, &nread ) ) {
698         fwrite (buf, nread, 1, stdout );
699   }
700   fputs ( "\r\n--42=.42=.42=.42\r\n"
701           "Content-Type: application/pgp-signature\r\n\r\n", stdout);
702
703   gpgme_data_rewind (sig);
704   while ( !gpgme_data_read (sig, buf, sizeof buf, &nread ) ) {
705         fwrite (buf, nread, 1, stdout );
706   }
707   fputs ( "\r\n--42=.42=.42=.42--\r\n", stdout );
708
709   gpgme_release (ctx);
710   gpgme_data_release(data);
711   gpgme_data_release(sig);
712
713   return true;
714 }
715
716 bool checkMessageSignature( const char* ciphertext, const char**
717         cleartext, struct SignatureMetaData* sigmeta ){ return true; }
718
719 bool storeCertificatesFromMessage(
720         const char* ciphertext ){ return true; }
721
722
723 bool encryptMessage( const char* cleartext,
724                      const char** ciphertext ){ return true; }
725
726 bool encryptAndSignMessage( const char* cleartext,
727           const char** ciphertext, const char* certificate,
728           struct SignatureMetaData* sigmeta ){ return true; }
729
730 bool decryptMessage( const char* ciphertext, const
731           char** cleartext, const char* certificate ){ return true; }
732
733 bool decryptAndCheckMessage( const char* ciphertext,
734           const char** cleartext, const char* certificate,
735           struct SignatureMetaData* sigmeta ){ return true; }
736
737
738 const char* requestCertificateDialog(){ return 0; }
739
740 bool requestDecentralCertificate( const char* name, const char*
741           email, const char* organization, const char* department,
742           const char* ca_address ){ return true; }
743
744 bool requestCentralCertificateAndPSE( const char* name,
745           const char* email, const char* organization, const char* department,
746           const char* ca_address ){ return true; }
747
748 bool createPSE(){ return true; }
749
750 bool registerCertificate( const char* certificate ){ return true; }
751
752 bool requestCertificateProlongation( const char* certificate,
753                                      const char* ca_address ){ return true; }
754
755 const char* certificateChain(){ return 0; }
756
757 bool deleteCertificate( const char* certificate ){ return true; }
758
759 bool archiveCertificate( const char* certificate ){ return true; }
760
761
762 const char* displayCRL(){ return 0; }
763
764 void updateCRL(){}