gint main (gint argc, gchar **argv) { CamelSession *session; CamelSMimeContext *ctx; GError **error; CamelCipherValidity *valid; CamelStream *stream1, *stream2, *stream3; GPtrArray *recipients; GByteArray *buf; gchar *before, *after; camel_test_init (argc, argv); ex = camel_exception_new (); /* clear out any camel-test data */ system ("/bin/rm -rf /tmp/camel-test"); session = camel_test_session_new ("/tmp/camel-test"); ctx = camel_smime_context_new (session); camel_test_start ("Test of S/MIME PKCS7 functions"); stream1 = camel_stream_mem_new (); camel_stream_write (stream1, "Hello, I am a test stream.", 25); g_seekable_seek (G_SEEKABLE (stream1), 0, G_SEEK_SET, NULL, NULL); stream2 = camel_stream_mem_new (); camel_test_push ("PKCS7 signing"); camel_smime_sign (ctx, "*****@*****.**", CAMEL_CIPHER_HASH_SHA1, stream1, stream2, ex); check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex)); camel_test_pull (); camel_exception_clear (ex); camel_test_push ("PKCS7 verify"); g_seekable_seek (G_SEEKABLE (stream1), 0, G_SEEK_SET, NULL, NULL); g_seekable_seek (G_SEEKABLE (stream2), 0, G_SEEK_SET, NULL, NULL); valid = camel_smime_verify (ctx, CAMEL_CIPHER_HASH_SHA1, stream1, stream2, ex); check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex)); check_msg (camel_cipher_validity_get_valid (valid), "%s", camel_cipher_validity_get_description (valid)); camel_cipher_validity_free (valid); camel_test_pull (); g_object_unref (stream1); g_object_unref (stream2); stream1 = camel_stream_mem_new (); stream2 = camel_stream_mem_new (); stream3 = camel_stream_mem_new (); camel_stream_write (stream1, "Hello, I am a test of encryption/decryption.", 44); g_seekable_seek (G_SEEKABLE (stream1), 0, G_SEEK_SET, NULL, NULL); camel_exception_clear (ex); camel_test_push ("PKCS7 encrypt"); recipients = g_ptr_array_new (); g_ptr_array_add (recipients, "*****@*****.**"); camel_smime_encrypt (ctx, FALSE, "*****@*****.**", recipients, stream1, stream2, ex); check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex)); g_ptr_array_free (recipients, TRUE); camel_test_pull (); g_seekable_seek (G_SEEKABLE (stream2), 0, G_SEEK_SET, NULL, NULL); camel_exception_clear (ex); camel_test_push ("PKCS7 decrypt"); camel_smime_decrypt (ctx, stream2, stream3, ex); check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex)); buf = CAMEL_STREAM_MEM (stream1)->buffer; before = g_strndup (buf->data, buf->len); buf = CAMEL_STREAM_MEM (stream3)->buffer; after = g_strndup (buf->data, buf->len); check_msg (string_equal (before, after), "before = '%s', after = '%s'", before, after); g_free (before); g_free (after); camel_test_pull (); g_object_unref (ctx); g_object_unref (session); camel_test_end (); return 0; }
static gboolean empe_mp_signed_parse (EMailParserExtension *extension, EMailParser *parser, CamelMimePart *part, GString *part_id, GCancellable *cancellable, GQueue *out_mail_parts) { CamelMimePart *cpart = NULL; CamelMultipart *multipart; CamelCipherContext *cipher = NULL; CamelContentType *content_type; CamelSession *session; guint32 validity_type; CamelCipherValidity *valid; const gchar *protocol = NULL; GError *local_error = NULL; gint i, nparts, len; gboolean secured; /* If the part is application/pgp-signature sub-part then skip it. */ if (!CAMEL_IS_MULTIPART (part)) { content_type = camel_mime_part_get_content_type (part); if (camel_content_type_is ( content_type, "application", "pgp-signature")) { return TRUE; } } multipart = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part); if (CAMEL_IS_MULTIPART_SIGNED (multipart)) { cpart = camel_multipart_get_part ( multipart, CAMEL_MULTIPART_SIGNED_CONTENT); } if (cpart == NULL) { e_mail_parser_error ( parser, out_mail_parts, _("Could not parse MIME message. " "Displaying as source.")); e_mail_parser_parse_part_as ( parser, part, part_id, "application/vnd.evolution.source", cancellable, out_mail_parts); return TRUE; } content_type = camel_data_wrapper_get_mime_type_field ( CAMEL_DATA_WRAPPER (multipart)); if (content_type != NULL) protocol = camel_content_type_param (content_type, "protocol"); session = e_mail_parser_get_session (parser); /* FIXME: Should be done via a plugin interface */ /* FIXME: duplicated in em-format-html-display.c */ if (protocol != NULL) { #ifdef ENABLE_SMIME if (g_ascii_strcasecmp ("application/x-pkcs7-signature", protocol) == 0 || g_ascii_strcasecmp ("application/pkcs7-signature", protocol) == 0) { cipher = camel_smime_context_new (session); validity_type = E_MAIL_PART_VALIDITY_SMIME; } else { #endif if (g_ascii_strcasecmp ("application/pgp-signature", protocol) == 0) { cipher = camel_gpg_context_new (session); validity_type = E_MAIL_PART_VALIDITY_PGP; } #ifdef ENABLE_SMIME } #endif } if (cipher == NULL) { e_mail_parser_error ( parser, out_mail_parts, _("Unsupported signature format")); e_mail_parser_parse_part_as ( parser, part, part_id, "multipart/mixed", cancellable, out_mail_parts); return TRUE; } valid = camel_cipher_context_verify_sync ( cipher, part, cancellable, &local_error); if (local_error != NULL) { e_mail_parser_error ( parser, out_mail_parts, _("Error verifying signature: %s"), local_error->message); e_mail_parser_parse_part_as ( parser, part, part_id, "multipart/mixed", cancellable, out_mail_parts); g_object_unref (cipher); g_error_free (local_error); return TRUE; } nparts = camel_multipart_get_number (multipart); secured = FALSE; len = part_id->len; for (i = 0; i < nparts; i++) { GQueue work_queue = G_QUEUE_INIT; GList *head, *link; CamelMimePart *subpart; subpart = camel_multipart_get_part (multipart, i); g_string_append_printf (part_id, ".signed.%d", i); g_warn_if_fail (e_mail_parser_parse_part ( parser, subpart, part_id, cancellable, &work_queue)); g_string_truncate (part_id, len); if (!secured) secured = e_mail_part_is_secured (subpart); head = g_queue_peek_head_link (&work_queue); for (link = head; link != NULL; link = g_list_next (link)) { EMailPart *mail_part = link->data; e_mail_part_update_validity ( mail_part, valid, validity_type | E_MAIL_PART_VALIDITY_SIGNED); } e_queue_transfer (&work_queue, out_mail_parts); } /* Add a widget with details about the encryption, but only when * the encrypted isn't itself secured, in that case it has created * the button itself. */ if (!secured) { GQueue work_queue = G_QUEUE_INIT; EMailPart *mail_part; g_string_append (part_id, ".signed.button"); e_mail_parser_parse_part_as ( parser, part, part_id, "application/vnd.evolution.widget.secure-button", cancellable, &work_queue); mail_part = g_queue_peek_head (&work_queue); if (mail_part != NULL) e_mail_part_update_validity ( mail_part, valid, validity_type | E_MAIL_PART_VALIDITY_SIGNED); e_queue_transfer (&work_queue, out_mail_parts); g_string_truncate (part_id, len); } camel_cipher_validity_free (valid); g_object_unref (cipher); return TRUE; }