1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2000-2012 Jeffrey Stedfast
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.
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.
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
26 #include "gmime-crypto-context.h"
27 #include "gmime-error.h"
31 * SECTION: gmime-crypto-context
32 * @title: GMimeCryptoContext
33 * @short_description: Encryption/signing contexts
36 * A #GMimeCryptoContext is used for encrypting, decrypting, signing
37 * and verifying cryptographic signatures.
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);
45 static GMimeDigestAlgo crypto_digest_id (GMimeCryptoContext *ctx, const char *name);
47 static const char *crypto_digest_name (GMimeCryptoContext *ctx, GMimeDigestAlgo );
49 static const char *crypto_get_signature_protocol (GMimeCryptoContext *ctx);
51 static const char *crypto_get_encryption_protocol (GMimeCryptoContext *ctx);
53 static const char *crypto_get_key_exchange_protocol (GMimeCryptoContext *ctx);
55 static int crypto_sign (GMimeCryptoContext *ctx, const char *userid,
56 GMimeDigestAlgo digest, GMimeStream *istream,
57 GMimeStream *ostream, GError **err);
59 static GMimeSignatureList *crypto_verify (GMimeCryptoContext *ctx, GMimeDigestAlgo digest,
60 GMimeStream *istream, GMimeStream *sigstream,
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);
68 static GMimeDecryptResult *crypto_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
69 GMimeStream *ostream, GError **err);
71 static int crypto_import_keys (GMimeCryptoContext *ctx, GMimeStream *istream,
74 static int crypto_export_keys (GMimeCryptoContext *ctx, GPtrArray *keys,
75 GMimeStream *ostream, GError **err);
78 static GObjectClass *parent_class = NULL;
82 g_mime_crypto_context_get_type (void)
84 static GType type = 0;
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),
96 (GInstanceInitFunc) g_mime_crypto_context_init,
99 type = g_type_register_static (G_TYPE_OBJECT, "GMimeCryptoContext", &info, 0);
107 g_mime_crypto_context_class_init (GMimeCryptoContextClass *klass)
109 GObjectClass *object_class = G_OBJECT_CLASS (klass);
111 parent_class = g_type_class_ref (G_TYPE_OBJECT);
113 object_class->finalize = g_mime_crypto_context_finalize;
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;
129 g_mime_crypto_context_init (GMimeCryptoContext *ctx, GMimeCryptoContextClass *klass)
131 ctx->request_passwd = NULL;
135 g_mime_crypto_context_finalize (GObject *object)
137 G_OBJECT_CLASS (parent_class)->finalize (object);
142 * g_mime_crypto_context_set_request_password:
143 * @ctx: a #GMimeCryptoContext
144 * @request_passwd: a callback function for requesting a password
146 * Sets the function used by the @ctx for requesting a password from
150 g_mime_crypto_context_set_request_password (GMimeCryptoContext *ctx, GMimePasswordRequestFunc request_passwd)
152 g_return_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx));
154 ctx->request_passwd = request_passwd;
158 static GMimeDigestAlgo
159 crypto_digest_id (GMimeCryptoContext *ctx, const char *name)
161 return GMIME_DIGEST_ALGO_DEFAULT;
166 * g_mime_crypto_context_get_request_password:
167 * @ctx: a #GMimeCryptoContext
169 * Gets the function used by the @ctx for requesting a password from
172 * Returns: a #GMimePasswordRequestFunc or %NULL if not set.
174 GMimePasswordRequestFunc
175 g_mime_crypto_context_get_request_password (GMimeCryptoContext *ctx)
177 g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
179 return ctx->request_passwd;
184 * g_mime_crypto_context_digest_id:
185 * @ctx: a #GMimeCryptoContext
188 * Gets the digest id based on the digest name.
190 * Returns: the equivalent digest id or #GMIME_DIGEST_ALGO_DEFAULT on fail.
193 g_mime_crypto_context_digest_id (GMimeCryptoContext *ctx, const char *name)
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);
198 return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->digest_id (ctx, name);
203 crypto_digest_name (GMimeCryptoContext *ctx, GMimeDigestAlgo digest)
210 * g_mime_crypto_context_digest_name:
211 * @ctx: a #GMimeCryptoContext
214 * Gets the digest name based on the digest id @digest.
216 * Returns: the equivalent digest name or %NULL on fail.
219 g_mime_crypto_context_digest_name (GMimeCryptoContext *ctx, GMimeDigestAlgo digest)
221 g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
223 return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->digest_name (ctx, digest);
228 crypto_get_signature_protocol (GMimeCryptoContext *ctx)
235 * g_mime_crypto_context_get_signature_protocol:
236 * @ctx: a #GMimeCryptoContext
238 * Gets the signature protocol for the crypto context.
240 * Returns: the signature protocol or %NULL if not supported.
243 g_mime_crypto_context_get_signature_protocol (GMimeCryptoContext *ctx)
245 g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
247 return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->get_signature_protocol (ctx);
252 crypto_get_encryption_protocol (GMimeCryptoContext *ctx)
259 * g_mime_crypto_context_get_encryption_protocol:
260 * @ctx: a #GMimeCryptoContext
262 * Gets the encryption protocol for the crypto context.
264 * Returns: the encryption protocol or %NULL if not supported.
267 g_mime_crypto_context_get_encryption_protocol (GMimeCryptoContext *ctx)
269 g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
271 return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->get_encryption_protocol (ctx);
276 crypto_get_key_exchange_protocol (GMimeCryptoContext *ctx)
283 * g_mime_crypto_context_get_key_exchange_protocol:
284 * @ctx: a #GMimeCryptoContext
286 * Gets the key exchange protocol for the crypto context.
288 * Returns: the key exchange protocol or %NULL if not supported.
291 g_mime_crypto_context_get_key_exchange_protocol (GMimeCryptoContext *ctx)
293 g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
295 return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->get_key_exchange_protocol (ctx);
300 crypto_sign (GMimeCryptoContext *ctx, const char *userid, GMimeDigestAlgo digest,
301 GMimeStream *istream, GMimeStream *ostream, GError **err)
303 g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
304 "Signing is not supported by this crypto context");
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
319 * Signs the input stream and writes the resulting signature to the output stream.
321 * Returns: the #GMimeDigestAlgo used on success (useful if @digest is
322 * specified as #GMIME_DIGEST_ALGO_DEFAULT) or %-1 on fail.
325 g_mime_crypto_context_sign (GMimeCryptoContext *ctx, const char *userid, GMimeDigestAlgo digest,
326 GMimeStream *istream, GMimeStream *ostream, GError **err)
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);
332 return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->sign (ctx, userid, digest, istream, ostream, err);
336 static GMimeSignatureList *
337 crypto_verify (GMimeCryptoContext *ctx, GMimeDigestAlgo digest, GMimeStream *istream,
338 GMimeStream *sigstream, GError **err)
340 g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
341 "Verifying is not supported by this crypto context");
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
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.
360 * Returns: a #GMimeSignatureList object containing the status of each
361 * signature or %NULL on error.
364 g_mime_crypto_context_verify (GMimeCryptoContext *ctx, GMimeDigestAlgo digest, GMimeStream *istream,
365 GMimeStream *sigstream, GError **err)
367 g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), NULL);
368 g_return_val_if_fail (GMIME_IS_STREAM (istream), NULL);
370 return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->verify (ctx, digest, istream, sigstream, err);
375 crypto_encrypt (GMimeCryptoContext *ctx, gboolean sign, const char *userid, GMimeDigestAlgo digest,
376 GPtrArray *recipients, GMimeStream *istream, GMimeStream *ostream, GError **err)
378 g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
379 "Encryption is not supported by this crypto context");
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
396 * Encrypts (and optionally signs) the cleartext input stream and
397 * writes the resulting ciphertext to the output stream.
399 * Returns: %0 on success or %-1 on fail.
402 g_mime_crypto_context_encrypt (GMimeCryptoContext *ctx, gboolean sign, const char *userid, GMimeDigestAlgo digest,
403 GPtrArray *recipients, GMimeStream *istream, GMimeStream *ostream, GError **err)
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);
409 return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->encrypt (ctx, sign, userid, digest, recipients, istream, ostream, err);
413 static GMimeDecryptResult *
414 crypto_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
415 GMimeStream *ostream, GError **err)
417 g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
418 "Decryption is not supported by this crypto context");
425 * g_mime_crypto_context_decrypt:
426 * @ctx: a #GMimeCryptoContext
427 * @istream: input/ciphertext stream
428 * @ostream: output/cleartext stream
431 * Decrypts the ciphertext input stream and writes the resulting
432 * cleartext to the output stream.
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).
438 * On success, the returned #GMimeDecryptResult will contain a list of
439 * certificates, one for each recipient, that the original encrypted stream
442 * Returns: a #GMimeDecryptResult on success or %NULL on error.
445 g_mime_crypto_context_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
446 GMimeStream *ostream, GError **err)
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);
452 return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->decrypt (ctx, istream, ostream, err);
457 crypto_import_keys (GMimeCryptoContext *ctx, GMimeStream *istream, GError **err)
459 g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
460 "You may not import keys with this crypto");
467 * g_mime_crypto_context_import_keys:
468 * @ctx: a #GMimeCryptoContext
469 * @istream: input stream (containing keys)
472 * Imports a stream of keys/certificates contained within @istream
473 * into the key/certificate database controlled by @ctx.
475 * Returns: %0 on success or %-1 on fail.
478 g_mime_crypto_context_import_keys (GMimeCryptoContext *ctx, GMimeStream *istream, GError **err)
480 g_return_val_if_fail (GMIME_IS_CRYPTO_CONTEXT (ctx), -1);
481 g_return_val_if_fail (GMIME_IS_STREAM (istream), -1);
483 return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->import_keys (ctx, istream, err);
488 crypto_export_keys (GMimeCryptoContext *ctx, GPtrArray *keys,
489 GMimeStream *ostream, GError **err)
491 g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED,
492 "You may not export keys with this crypto");
499 * g_mime_crypto_context_export_keys:
500 * @ctx: a #GMimeCryptoContext
501 * @keys: an array of key ids
502 * @ostream: output stream
505 * Exports the keys/certificates in @keys to the stream @ostream from
506 * the key/certificate database controlled by @ctx.
508 * Returns: %0 on success or %-1 on fail.
511 g_mime_crypto_context_export_keys (GMimeCryptoContext *ctx, GPtrArray *keys,
512 GMimeStream *ostream, GError **err)
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);
518 return GMIME_CRYPTO_CONTEXT_GET_CLASS (ctx)->export_keys (ctx, keys, ostream, err);
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);
526 static GObjectClass *result_parent_class = NULL;
530 g_mime_decrypt_result_get_type (void)
532 static GType type = 0;
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),
544 (GInstanceInitFunc) g_mime_decrypt_result_init,
547 type = g_type_register_static (G_TYPE_OBJECT, "GMimeDecryptResult", &info, 0);
554 g_mime_decrypt_result_class_init (GMimeDecryptResultClass *klass)
556 GObjectClass *object_class = G_OBJECT_CLASS (klass);
558 result_parent_class = g_type_class_ref (G_TYPE_OBJECT);
560 object_class->finalize = g_mime_decrypt_result_finalize;
564 g_mime_decrypt_result_init (GMimeDecryptResult *result, GMimeDecryptResultClass *klass)
566 result->cipher = GMIME_CIPHER_ALGO_DEFAULT;
567 result->mdc = GMIME_DIGEST_ALGO_DEFAULT;
568 result->recipients = NULL;
569 result->signatures = NULL;
573 g_mime_decrypt_result_finalize (GObject *object)
575 GMimeDecryptResult *result = (GMimeDecryptResult *) object;
577 if (result->recipients)
578 g_object_unref (result->recipients);
580 if (result->signatures)
581 g_object_unref (result->signatures);
583 G_OBJECT_CLASS (result_parent_class)->finalize (object);
588 * g_mime_decrypt_result_new:
590 * Creates a new #GMimeDecryptResult object.
592 * Returns: a new #GMimeDecryptResult object.
595 g_mime_decrypt_result_new (void)
597 return g_object_newv (GMIME_TYPE_DECRYPT_RESULT, 0, NULL);
602 * g_mime_decrypt_result_set_recipients:
603 * @result: A #GMimeDecryptResult
604 * @recipients: A #GMimeCertificateList
606 * Sets the list of certificates that the stream had been encrypted to.
609 g_mime_decrypt_result_set_recipients (GMimeDecryptResult *result, GMimeCertificateList *recipients)
611 g_return_if_fail (GMIME_IS_DECRYPT_RESULT (result));
612 g_return_if_fail (GMIME_IS_CERTIFICATE_LIST (recipients));
614 if (result->recipients == recipients)
617 if (result->recipients)
618 g_object_unref (result->recipients);
621 g_object_ref (recipients);
623 result->recipients = recipients;
628 * g_mime_decrypt_result_get_recipients:
629 * @result: A #GMimeDecryptResult
631 * Gets the list of certificates that the stream had been encrypted to.
633 * Returns: a #GMimeCertificateList.
635 GMimeCertificateList *
636 g_mime_decrypt_result_get_recipients (GMimeDecryptResult *result)
638 g_return_val_if_fail (GMIME_IS_DECRYPT_RESULT (result), NULL);
640 return result->recipients;
645 * g_mime_decrypt_result_set_signatures:
646 * @result: A #GMimeDecryptResult
647 * @signatures: A #GMimeSignatureList
649 * Sets the list of signatures.
652 g_mime_decrypt_result_set_signatures (GMimeDecryptResult *result, GMimeSignatureList *signatures)
654 g_return_if_fail (GMIME_IS_DECRYPT_RESULT (result));
655 g_return_if_fail (GMIME_IS_SIGNATURE_LIST (signatures));
657 if (result->signatures == signatures)
660 if (result->signatures)
661 g_object_unref (result->signatures);
664 g_object_ref (signatures);
666 result->signatures = signatures;
671 * g_mime_decrypt_result_get_signatures:
672 * @result: A #GMimeDecryptResult
674 * Gets a list of signatures if the encrypted stream had also been signed.
676 * Returns: a #GMimeSignatureList or %NULL if the stream was not signed.
679 g_mime_decrypt_result_get_signatures (GMimeDecryptResult *result)
681 g_return_val_if_fail (GMIME_IS_DECRYPT_RESULT (result), NULL);
683 return result->signatures;
688 * g_mime_decrypt_result_set_cipher:
689 * @result: a #GMimeDecryptResult
690 * @cipher: a #GMimeCipherAlgo
692 * Set the cipher algorithm used.
695 g_mime_decrypt_result_set_cipher (GMimeDecryptResult *result, GMimeCipherAlgo cipher)
697 g_return_if_fail (GMIME_IS_DECRYPT_RESULT (result));
699 result->cipher = cipher;
704 * g_mime_decrypt_result_get_cipher:
705 * @result: a #GMimeDecryptResult
707 * Get the cipher algorithm used.
709 * Returns: the cipher algorithm used.
712 g_mime_decrypt_result_get_cipher (GMimeDecryptResult *result)
714 g_return_val_if_fail (GMIME_IS_DECRYPT_RESULT (result), GMIME_CIPHER_ALGO_DEFAULT);
716 return result->cipher;
721 * g_mime_decrypt_result_set_mdc:
722 * @result: a #GMimeDecryptResult
723 * @mdc: a #GMimeDigestAlgo
725 * Set the mdc digest algorithm used.
728 g_mime_decrypt_result_set_mdc (GMimeDecryptResult *result, GMimeDigestAlgo mdc)
730 g_return_if_fail (GMIME_IS_DECRYPT_RESULT (result));
737 * g_mime_decrypt_result_get_mdc:
738 * @result: a #GMimeDecryptResult
740 * Get the mdc digest algorithm used.
742 * Returns: the mdc digest algorithm used.
745 g_mime_decryption_result_get_mdc (GMimeDecryptResult *result)
747 g_return_val_if_fail (GMIME_IS_DECRYPT_RESULT (result), GMIME_DIGEST_ALGO_DEFAULT);