Initialize the gmime for upstream
[platform/upstream/gmime.git] / gmime / gmime-crypto-context.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*  GMime
3  *  Copyright (C) 2000-2012 Jeffrey Stedfast
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public License
7  *  as published by the Free Software Foundation; either version 2.1
8  *  of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free
17  *  Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
18  *  02110-1301, USA.
19  */
20
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "gmime-crypto-context.h"
27 #include "gmime-error.h"
28
29
30 /**
31  * SECTION: gmime-crypto-context
32  * @title: GMimeCryptoContext
33  * @short_description: Encryption/signing contexts
34  * @see_also:
35  *
36  * A #GMimeCryptoContext is used for encrypting, decrypting, signing
37  * and verifying cryptographic signatures.
38  **/
39
40
41 static void g_mime_crypto_context_class_init (GMimeCryptoContextClass *klass);
42 static void g_mime_crypto_context_init (GMimeCryptoContext *ctx, GMimeCryptoContextClass *klass);
43 static void g_mime_crypto_context_finalize (GObject *object);
44
45 static GMimeDigestAlgo crypto_digest_id (GMimeCryptoContext *ctx, const char *name);
46
47 static const char *crypto_digest_name (GMimeCryptoContext *ctx, GMimeDigestAlgo );
48
49 static const char *crypto_get_signature_protocol (GMimeCryptoContext *ctx);
50
51 static const char *crypto_get_encryption_protocol (GMimeCryptoContext *ctx);
52
53 static const char *crypto_get_key_exchange_protocol (GMimeCryptoContext *ctx);
54
55 static int crypto_sign (GMimeCryptoContext *ctx, const char *userid,
56                         GMimeDigestAlgo digest, GMimeStream *istream,
57                         GMimeStream *ostream, GError **err);
58         
59 static GMimeSignatureList *crypto_verify (GMimeCryptoContext *ctx, GMimeDigestAlgo digest,
60                                           GMimeStream *istream, GMimeStream *sigstream,
61                                           GError **err);
62         
63 static int crypto_encrypt (GMimeCryptoContext *ctx, gboolean sign,
64                            const char *userid, GMimeDigestAlgo digest,
65                            GPtrArray *recipients, GMimeStream *istream,
66                            GMimeStream *ostream, GError **err);
67
68 static GMimeDecryptResult *crypto_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
69                                            GMimeStream *ostream, GError **err);
70
71 static int crypto_import_keys (GMimeCryptoContext *ctx, GMimeStream *istream,
72                                GError **err);
73
74 static int crypto_export_keys (GMimeCryptoContext *ctx, GPtrArray *keys,
75                                GMimeStream *ostream, GError **err);
76
77
78 static GObjectClass *parent_class = NULL;
79
80
81 GType
82 g_mime_crypto_context_get_type (void)
83 {
84         static GType type = 0;
85         
86         if (!type) {
87                 static const GTypeInfo info = {
88                         sizeof (GMimeCryptoContextClass),
89                         NULL, /* base_class_init */
90                         NULL, /* base_class_finalize */
91                         (GClassInitFunc) g_mime_crypto_context_class_init,
92                         NULL, /* class_finalize */
93                         NULL, /* class_data */
94                         sizeof (GMimeCryptoContext),
95                         0,    /* n_preallocs */
96                         (GInstanceInitFunc) g_mime_crypto_context_init,
97                 };
98                 
99                 type = g_type_register_static (G_TYPE_OBJECT, "GMimeCryptoContext", &info, 0);
100         }
101         
102         return type;
103 }
104
105
106 static void
107 g_mime_crypto_context_class_init (GMimeCryptoContextClass *klass)
108 {
109         GObjectClass *object_class = G_OBJECT_CLASS (klass);
110         
111         parent_class = g_type_class_ref (G_TYPE_OBJECT);
112         
113         object_class->finalize = g_mime_crypto_context_finalize;
114         
115         klass->digest_id = crypto_digest_id;
116         klass->digest_name = crypto_digest_name;
117         klass->sign = crypto_sign;
118         klass->verify = crypto_verify;
119         klass->encrypt = crypto_encrypt;
120         klass->decrypt = crypto_decrypt;
121         klass->import_keys = crypto_import_keys;
122         klass->export_keys = crypto_export_keys;
123         klass->get_signature_protocol = crypto_get_signature_protocol;
124         klass->get_encryption_protocol = crypto_get_encryption_protocol;
125         klass->get_key_exchange_protocol = crypto_get_key_exchange_protocol;
126 }
127
128 static void
129 g_mime_crypto_context_init (GMimeCryptoContext *ctx, GMimeCryptoContextClass *klass)
130 {
131         ctx->request_passwd = NULL;
132 }
133
134 static void
135 g_mime_crypto_context_finalize (GObject *object)
136 {
137         G_OBJECT_CLASS (parent_class)->finalize (object);
138 }
139
140
141 /**
142  * g_mime_crypto_context_set_request_password:
143  * @ctx: a #GMimeCryptoContext
144  * @request_passwd: a callback function for requesting a password
145  *
146  * Sets the function used by the @ctx for requesting a password from
147  * the user.
148  **/
149 void
150 g_mime_crypto_context_set_request_password (GMimeCryptoContext *ctx, GMimePasswordRequestFunc request_passwd)
151 {
152         g_return_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx));
153         
154         ctx->request_passwd = request_passwd;
155 }
156
157
158 static GMimeDigestAlgo
159 crypto_digest_id (GMimeCryptoContext *ctx, const char *name)
160 {
161         return GMIME_DIGEST_ALGO_DEFAULT;
162 }
163
164
165 /**
166  * g_mime_crypto_context_get_request_password:
167  * @ctx: a #GMimeCryptoContext
168  *
169  * Gets the function used by the @ctx for requesting a password from
170  * the user.
171  *
172  * Returns: a #GMimePasswordRequestFunc or %NULL if not set.
173  **/
174 GMimePasswordRequestFunc
175 g_mime_crypto_context_get_request_password (GMimeCryptoContext *ctx)
176 {
177         g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
178         
179         return ctx->request_passwd;
180 }
181
182
183 /**
184  * g_mime_crypto_context_digest_id:
185  * @ctx: a #GMimeCryptoContext
186  * @name: digest name
187  *
188  * Gets the digest id based on the digest name.
189  *
190  * Returns: the equivalent digest id or #GMIME_DIGEST_ALGO_DEFAULT on fail.
191  **/
192 GMimeDigestAlgo
193 g_mime_crypto_context_digest_id (GMimeCryptoContext *ctx, const char *name)
194 {
195         g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), GMIME_DIGEST_ALGO_DEFAULT);
196         g_return_val_if_fail (name != NULL, GMIME_DIGEST_ALGO_DEFAULT);
197         
198         return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->digest_id (ctx, name);
199 }
200
201
202 static const char *
203 crypto_digest_name (GMimeCryptoContext *ctx, GMimeDigestAlgo digest)
204 {
205         return NULL;
206 }
207
208
209 /**
210  * g_mime_crypto_context_digest_name:
211  * @ctx: a #GMimeCryptoContext
212  * @digest: digest id
213  *
214  * Gets the digest name based on the digest id @digest.
215  *
216  * Returns: the equivalent digest name or %NULL on fail.
217  **/
218 const char *
219 g_mime_crypto_context_digest_name (GMimeCryptoContext *ctx, GMimeDigestAlgo digest)
220 {
221         g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
222         
223         return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->digest_name (ctx, digest);
224 }
225
226
227 static const char *
228 crypto_get_signature_protocol (GMimeCryptoContext *ctx)
229 {
230         return NULL;
231 }
232
233
234 /**
235  * g_mime_crypto_context_get_signature_protocol:
236  * @ctx: a #GMimeCryptoContext
237  *
238  * Gets the signature protocol for the crypto context.
239  *
240  * Returns: the signature protocol or %NULL if not supported.
241  **/
242 const char *
243 g_mime_crypto_context_get_signature_protocol (GMimeCryptoContext *ctx)
244 {
245         g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
246         
247         return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->get_signature_protocol (ctx);
248 }
249
250
251 static const char *
252 crypto_get_encryption_protocol (GMimeCryptoContext *ctx)
253 {
254         return NULL;
255 }
256
257
258 /**
259  * g_mime_crypto_context_get_encryption_protocol:
260  * @ctx: a #GMimeCryptoContext
261  *
262  * Gets the encryption protocol for the crypto context.
263  *
264  * Returns: the encryption protocol or %NULL if not supported.
265  **/
266 const char *
267 g_mime_crypto_context_get_encryption_protocol (GMimeCryptoContext *ctx)
268 {
269         g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
270         
271         return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->get_encryption_protocol (ctx);
272 }
273
274
275 static const char *
276 crypto_get_key_exchange_protocol (GMimeCryptoContext *ctx)
277 {
278         return NULL;
279 }
280
281
282 /**
283  * g_mime_crypto_context_get_key_exchange_protocol:
284  * @ctx: a #GMimeCryptoContext
285  *
286  * Gets the key exchange protocol for the crypto context.
287  *
288  * Returns: the key exchange protocol or %NULL if not supported.
289  **/
290 const char *
291 g_mime_crypto_context_get_key_exchange_protocol (GMimeCryptoContext *ctx)
292 {
293         g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
294         
295         return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->get_key_exchange_protocol (ctx);
296 }
297
298
299 static int
300 crypto_sign (GMimeCryptoContext *ctx, const char *userid, GMimeDigestAlgo digest,
301              GMimeStream *istream, GMimeStream *ostream, GError **err)
302 {
303         g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
304                      "Signing is not supported by this crypto context");
305         
306         return -1;
307 }
308
309
310 /**
311  * g_mime_crypto_context_sign:
312  * @ctx: a #GMimeCryptoContext
313  * @userid: private key to use to sign the stream
314  * @digest: digest algorithm to use
315  * @istream: input stream
316  * @ostream: output stream
317  * @err: a #GError
318  *
319  * Signs the input stream and writes the resulting signature to the output stream.
320  *
321  * Returns: the #GMimeDigestAlgo used on success (useful if @digest is
322  * specified as #GMIME_DIGEST_ALGO_DEFAULT) or %-1 on fail.
323  **/
324 int
325 g_mime_crypto_context_sign (GMimeCryptoContext *ctx, const char *userid, GMimeDigestAlgo digest,
326                             GMimeStream *istream, GMimeStream *ostream, GError **err)
327 {
328         g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), -1);
329         g_return_val_if_fail (GMIME_IS_STREAM (istream), -1);
330         g_return_val_if_fail (GMIME_IS_STREAM (ostream), -1);
331         
332         return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->sign (ctx, userid, digest, istream, ostream, err);
333 }
334
335
336 static GMimeSignatureList *
337 crypto_verify (GMimeCryptoContext *ctx, GMimeDigestAlgo digest, GMimeStream *istream,
338                GMimeStream *sigstream, GError **err)
339 {
340         g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
341                      "Verifying is not supported by this crypto context");
342         
343         return NULL;
344 }
345
346
347 /**
348  * g_mime_crypto_context_verify:
349  * @ctx: a #GMimeCryptoContext
350  * @digest: digest algorithm used, if known
351  * @istream: input stream
352  * @sigstream: optional detached-signature stream
353  * @err: a #GError
354  *
355  * Verifies the signature. If @istream is a clearsigned stream,
356  * you should pass %NULL as the sigstream parameter. Otherwise
357  * @sigstream is assumed to be the signature stream and is used to
358  * verify the integirity of the @istream.
359  *
360  * Returns: a #GMimeSignatureList object containing the status of each
361  * signature or %NULL on error.
362  **/
363 GMimeSignatureList *
364 g_mime_crypto_context_verify (GMimeCryptoContext *ctx, GMimeDigestAlgo digest, GMimeStream *istream,
365                               GMimeStream *sigstream, GError **err)
366 {
367         g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
368         g_return_val_if_fail (GMIME_IS_STREAM (istream), NULL);
369         
370         return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->verify (ctx, digest, istream, sigstream, err);
371 }
372
373
374 static int
375 crypto_encrypt (GMimeCryptoContext *ctx, gboolean sign, const char *userid, GMimeDigestAlgo digest,
376                 GPtrArray *recipients, GMimeStream *istream, GMimeStream *ostream, GError **err)
377 {
378         g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
379                      "Encryption is not supported by this crypto context");
380         
381         return -1;
382 }
383
384
385 /**
386  * g_mime_crypto_context_encrypt:
387  * @ctx: a #GMimeCryptoContext
388  * @sign: sign as well as encrypt
389  * @userid: key id (or email address) to use when signing (assuming @sign is %TRUE)
390  * @digest: digest algorithm to use when signing
391  * @recipients: an array of recipient key ids and/or email addresses
392  * @istream: cleartext input stream
393  * @ostream: ciphertext output stream
394  * @err: a #GError
395  *
396  * Encrypts (and optionally signs) the cleartext input stream and
397  * writes the resulting ciphertext to the output stream.
398  *
399  * Returns: %0 on success or %-1 on fail.
400  **/
401 int
402 g_mime_crypto_context_encrypt (GMimeCryptoContext *ctx, gboolean sign, const char *userid, GMimeDigestAlgo digest,
403                                GPtrArray *recipients, GMimeStream *istream, GMimeStream *ostream, GError **err)
404 {
405         g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), -1);
406         g_return_val_if_fail (GMIME_IS_STREAM (istream), -1);
407         g_return_val_if_fail (GMIME_IS_STREAM (ostream), -1);
408         
409         return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->encrypt (ctx, sign, userid, digest, recipients, istream, ostream, err);
410 }
411
412
413 static GMimeDecryptResult *
414 crypto_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
415                 GMimeStream *ostream, GError **err)
416 {
417         g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
418                      "Decryption is not supported by this crypto context");
419         
420         return NULL;
421 }
422
423
424 /**
425  * g_mime_crypto_context_decrypt:
426  * @ctx: a #GMimeCryptoContext
427  * @istream: input/ciphertext stream
428  * @ostream: output/cleartext stream
429  * @err: a #GError
430  *
431  * Decrypts the ciphertext input stream and writes the resulting
432  * cleartext to the output stream.
433  *
434  * If the encrypted input stream was also signed, the returned
435  * #GMimeDecryptResult will have a non-%NULL list of signatures, each with a
436  * #GMimeSignatureStatus (among other details about each signature).
437  *
438  * On success, the returned #GMimeDecryptResult will contain a list of
439  * certificates, one for each recipient, that the original encrypted stream
440  * was encrypted to.
441  *
442  * Returns: a #GMimeDecryptResult on success or %NULL on error.
443  **/
444 GMimeDecryptResult *
445 g_mime_crypto_context_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
446                                GMimeStream *ostream, GError **err)
447 {
448         g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
449         g_return_val_if_fail (GMIME_IS_STREAM (istream), NULL);
450         g_return_val_if_fail (GMIME_IS_STREAM (ostream), NULL);
451         
452         return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->decrypt (ctx, istream, ostream, err);
453 }
454
455
456 static int
457 crypto_import_keys (GMimeCryptoContext *ctx, GMimeStream *istream, GError **err)
458 {
459         g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
460                      "You may not import keys with this crypto");
461         
462         return -1;
463 }
464
465
466 /**
467  * g_mime_crypto_context_import_keys:
468  * @ctx: a #GMimeCryptoContext
469  * @istream: input stream (containing keys)
470  * @err: a #GError
471  *
472  * Imports a stream of keys/certificates contained within @istream
473  * into the key/certificate database controlled by @ctx.
474  *
475  * Returns: %0 on success or %-1 on fail.
476  **/
477 int
478 g_mime_crypto_context_import_keys (GMimeCryptoContext *ctx, GMimeStream *istream, GError **err)
479 {
480         g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), -1);
481         g_return_val_if_fail (GMIME_IS_STREAM (istream), -1);
482         
483         return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->import_keys (ctx, istream, err);
484 }
485
486
487 static int
488 crypto_export_keys (GMimeCryptoContext *ctx, GPtrArray *keys,
489                     GMimeStream *ostream, GError **err)
490 {
491         g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
492                      "You may not export keys with this crypto");
493         
494         return -1;
495 }
496
497
498 /**
499  * g_mime_crypto_context_export_keys:
500  * @ctx: a #GMimeCryptoContext
501  * @keys: an array of key ids
502  * @ostream: output stream
503  * @err: a #GError
504  *
505  * Exports the keys/certificates in @keys to the stream @ostream from
506  * the key/certificate database controlled by @ctx.
507  *
508  * Returns: %0 on success or %-1 on fail.
509  **/
510 int
511 g_mime_crypto_context_export_keys (GMimeCryptoContext *ctx, GPtrArray *keys,
512                                    GMimeStream *ostream, GError **err)
513 {
514         g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), -1);
515         g_return_val_if_fail (GMIME_IS_STREAM (ostream), -1);
516         g_return_val_if_fail (keys != NULL, -1);
517         
518         return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->export_keys (ctx, keys, ostream, err);
519 }
520
521
522 static void g_mime_decrypt_result_class_init (GMimeDecryptResultClass *klass);
523 static void g_mime_decrypt_result_init (GMimeDecryptResult *cert, GMimeDecryptResultClass *klass);
524 static void g_mime_decrypt_result_finalize (GObject *object);
525
526 static GObjectClass *result_parent_class = NULL;
527
528
529 GType
530 g_mime_decrypt_result_get_type (void)
531 {
532         static GType type = 0;
533         
534         if (!type) {
535                 static const GTypeInfo info = {
536                         sizeof (GMimeDecryptResultClass),
537                         NULL, /* base_class_init */
538                         NULL, /* base_class_finalize */
539                         (GClassInitFunc) g_mime_decrypt_result_class_init,
540                         NULL, /* class_finalize */
541                         NULL, /* class_data */
542                         sizeof (GMimeDecryptResult),
543                         0,    /* n_preallocs */
544                         (GInstanceInitFunc) g_mime_decrypt_result_init,
545                 };
546                 
547                 type = g_type_register_static (G_TYPE_OBJECT, "GMimeDecryptResult", &info, 0);
548         }
549         
550         return type;
551 }
552
553 static void
554 g_mime_decrypt_result_class_init (GMimeDecryptResultClass *klass)
555 {
556         GObjectClass *object_class = G_OBJECT_CLASS (klass);
557         
558         result_parent_class = g_type_class_ref (G_TYPE_OBJECT);
559         
560         object_class->finalize = g_mime_decrypt_result_finalize;
561 }
562
563 static void
564 g_mime_decrypt_result_init (GMimeDecryptResult *result, GMimeDecryptResultClass *klass)
565 {
566         result->cipher = GMIME_CIPHER_ALGO_DEFAULT;
567         result->mdc = GMIME_DIGEST_ALGO_DEFAULT;
568         result->recipients = NULL;
569         result->signatures = NULL;
570 }
571
572 static void
573 g_mime_decrypt_result_finalize (GObject *object)
574 {
575         GMimeDecryptResult *result = (GMimeDecryptResult *) object;
576         
577         if (result->recipients)
578                 g_object_unref (result->recipients);
579         
580         if (result->signatures)
581                 g_object_unref (result->signatures);
582         
583         G_OBJECT_CLASS (result_parent_class)->finalize (object);
584 }
585
586
587 /**
588  * g_mime_decrypt_result_new:
589  *
590  * Creates a new #GMimeDecryptResult object.
591  * 
592  * Returns: a new #GMimeDecryptResult object.
593  **/
594 GMimeDecryptResult *
595 g_mime_decrypt_result_new (void)
596 {
597         return g_object_newv (GMIME_TYPE_DECRYPT_RESULT, 0, NULL);
598 }
599
600
601 /**
602  * g_mime_decrypt_result_set_recipients:
603  * @result: A #GMimeDecryptResult
604  * @recipients: A #GMimeCertificateList
605  *
606  * Sets the list of certificates that the stream had been encrypted to.
607  **/
608 void
609 g_mime_decrypt_result_set_recipients (GMimeDecryptResult *result, GMimeCertificateList *recipients)
610 {
611         g_return_if_fail (GMIME_IS_DECRYPT_RESULT (result));
612         g_return_if_fail (GMIME_IS_CERTIFICATE_LIST (recipients));
613         
614         if (result->recipients == recipients)
615                 return;
616         
617         if (result->recipients)
618                 g_object_unref (result->recipients);
619         
620         if (recipients)
621                 g_object_ref (recipients);
622         
623         result->recipients = recipients;
624 }
625
626
627 /**
628  * g_mime_decrypt_result_get_recipients:
629  * @result: A #GMimeDecryptResult
630  *
631  * Gets the list of certificates that the stream had been encrypted to.
632  *
633  * Returns: a #GMimeCertificateList.
634  **/
635 GMimeCertificateList *
636 g_mime_decrypt_result_get_recipients (GMimeDecryptResult *result)
637 {
638         g_return_val_if_fail (GMIME_IS_DECRYPT_RESULT (result), NULL);
639         
640         return result->recipients;
641 }
642
643
644 /**
645  * g_mime_decrypt_result_set_signatures:
646  * @result: A #GMimeDecryptResult
647  * @signatures: A #GMimeSignatureList
648  *
649  * Sets the list of signatures.
650  **/
651 void
652 g_mime_decrypt_result_set_signatures (GMimeDecryptResult *result, GMimeSignatureList *signatures)
653 {
654         g_return_if_fail (GMIME_IS_DECRYPT_RESULT (result));
655         g_return_if_fail (GMIME_IS_SIGNATURE_LIST (signatures));
656         
657         if (result->signatures == signatures)
658                 return;
659         
660         if (result->signatures)
661                 g_object_unref (result->signatures);
662         
663         if (signatures)
664                 g_object_ref (signatures);
665         
666         result->signatures = signatures;
667 }
668
669
670 /**
671  * g_mime_decrypt_result_get_signatures:
672  * @result: A #GMimeDecryptResult
673  *
674  * Gets a list of signatures if the encrypted stream had also been signed.
675  *
676  * Returns: a #GMimeSignatureList or %NULL if the stream was not signed.
677  **/
678 GMimeSignatureList *
679 g_mime_decrypt_result_get_signatures (GMimeDecryptResult *result)
680 {
681         g_return_val_if_fail (GMIME_IS_DECRYPT_RESULT (result), NULL);
682         
683         return result->signatures;
684 }
685
686
687 /**
688  * g_mime_decrypt_result_set_cipher:
689  * @result: a #GMimeDecryptResult
690  * @cipher: a #GMimeCipherAlgo
691  *
692  * Set the cipher algorithm used.
693  **/
694 void
695 g_mime_decrypt_result_set_cipher (GMimeDecryptResult *result, GMimeCipherAlgo cipher)
696 {
697         g_return_if_fail (GMIME_IS_DECRYPT_RESULT (result));
698         
699         result->cipher = cipher;
700 }
701
702
703 /**
704  * g_mime_decrypt_result_get_cipher:
705  * @result: a #GMimeDecryptResult
706  *
707  * Get the cipher algorithm used.
708  *
709  * Returns: the cipher algorithm used.
710  **/
711 GMimeCipherAlgo
712 g_mime_decrypt_result_get_cipher (GMimeDecryptResult *result)
713 {
714         g_return_val_if_fail (GMIME_IS_DECRYPT_RESULT (result), GMIME_CIPHER_ALGO_DEFAULT);
715         
716         return result->cipher;
717 }
718
719
720 /**
721  * g_mime_decrypt_result_set_mdc:
722  * @result: a #GMimeDecryptResult
723  * @mdc: a #GMimeDigestAlgo
724  *
725  * Set the mdc digest algorithm used.
726  **/
727 void
728 g_mime_decrypt_result_set_mdc (GMimeDecryptResult *result, GMimeDigestAlgo mdc)
729 {
730         g_return_if_fail (GMIME_IS_DECRYPT_RESULT (result));
731         
732         result->mdc = mdc;
733 }
734
735
736 /**
737  * g_mime_decrypt_result_get_mdc:
738  * @result: a #GMimeDecryptResult
739  *
740  * Get the mdc digest algorithm used.
741  *
742  * Returns: the mdc digest algorithm used.
743  **/
744 GMimeDigestAlgo
745 g_mime_decryption_result_get_mdc (GMimeDecryptResult *result)
746 {
747         g_return_val_if_fail (GMIME_IS_DECRYPT_RESULT (result), GMIME_DIGEST_ALGO_DEFAULT);
748         
749         return result->mdc;
750 }