--- SOGo-4.0.6.orig/SoObjects/Mailer/NSData+SMIME.h	2019-02-21 16:11:07.000000000 +0100
+++ SOGo-4.0.6/SoObjects/Mailer/NSData+SMIME.h	2019-05-05 21:41:45.462408407 +0200
@@ -31,6 +31,8 @@
 - (NSData *) encryptUsingCertificate: (NSData *) theData;
 - (NSData *) decryptUsingCertificate: (NSData *) theData;
 - (NGMimeMessage *) messageFromEncryptedDataAndCertificate: (NSData *) theCertificate;
+- (NSData *) embeddedContent;
+- (NGMimeMessage *) messageFromOpaqueSignedData;
 - (NSData *) convertPKCS12ToPEMUsingPassword: (NSString *) thePassword;
 - (NSData *) convertPKCS7ToPEM;
 - (NSDictionary *) certificateDescription;
--- SOGo-4.0.6.orig/SoObjects/Mailer/NSData+SMIME.m	2019-02-21 16:11:07.000000000 +0100
+++ SOGo-4.0.6/SoObjects/Mailer/NSData+SMIME.m	2019-05-05 21:46:24.630420372 +0200
@@ -292,10 +292,86 @@
   NGMimeMessageParser *parser;
   NGMimeMessage *message;
   NSData *decryptedData; 
+  NGMimeType *contentType;
+  NSString *type, *subtype, *smimetype;
  
   decryptedData = [self decryptUsingCertificate: theCertificate];
   parser = [[NGMimeMessageParser alloc] init];
   message = [parser parsePartFromData: decryptedData];
+
+  // Extract contents if the encrypted messages contains opaque signed data
+  contentType = [message contentType];
+  type = [[contentType type] lowercaseString];
+  subtype = [[contentType subType] lowercaseString];
+  if ([type isEqualToString: @"application"])
+    {
+      if ([subtype isEqualToString: @"x-pkcs7-mime"] ||
+          [subtype isEqualToString: @"pkcs7-mime"])
+	{
+	  smimetype = [[contentType valueOfParameter: @"smime-type"] lowercaseString];
+	  if ([smimetype isEqualToString: @"signed-data"])
+	    {
+	      message = [decryptedData messageFromOpaqueSignedData];
+	    }
+	}
+    }
+
+  RELEASE(parser);
+
+  return message;
+}
+
+- (NSData *) embeddedContent
+{
+  NSData *output = NULL;
+
+  BIO *sbio, *obio;
+  BUF_MEM *bptr;
+  PKCS7 *p7 = NULL;
+  
+  sbio = BIO_new_mem_buf((void *)[self bytes], [self length]);
+
+  p7 = SMIME_read_PKCS7(sbio, NULL);
+
+  if (!p7)
+    {
+      NSLog(@"FATAL: could not read the signature");
+      goto cleanup;
+    }
+
+  // We output the S/MIME encrypted message
+  obio = BIO_new(BIO_s_mem());
+  
+  if (!PKCS7_verify(p7, NULL, NULL, NULL, obio, PKCS7_NOVERIFY|PKCS7_NOSIGS))
+    {
+      NSLog(@"FATAL: could not extract content");
+      goto cleanup;
+    }
+  
+  BIO_get_mem_ptr(obio, &bptr);
+  
+  output = [NSData dataWithBytes: bptr->data  length: bptr->length];
+
+ cleanup:
+  PKCS7_free(p7);
+  BIO_free(sbio);
+  BIO_free(obio);
+  
+  return output;
+}
+
+//
+//
+//
+- (NGMimeMessage *) messageFromOpaqueSignedData
+{
+  NGMimeMessageParser *parser;
+  NGMimeMessage *message;
+  NSData *extractedData; 
+ 
+  extractedData = [self embeddedContent];
+  parser = [[NGMimeMessageParser alloc] init];
+  message = [parser parsePartFromData: extractedData];
   RELEASE(parser);
 
   return message;
--- SOGo-4.0.6.orig/SoObjects/Mailer/SOGoDraftObject.m	2019-02-21 16:11:07.000000000 +0100
+++ SOGo-4.0.6/SoObjects/Mailer/SOGoDraftObject.m	2019-05-05 21:47:53.650424188 +0200
@@ -875,6 +875,18 @@
 //
 //
 //
+- (void) _fetchAttachmentsFromOpaqueSignedMail: (SOGoMailObject *) sourceMail
+{
+  NGMimeMessage *m;
+
+  m = [[sourceMail content] messageFromOpaqueSignedData];
+  [self _fileAttachmentsFromPart: [m body]];
+}
+
+
+//
+//
+//
 - (void) fetchMailForEditing: (SOGoMailObject *) sourceMail
 {
   NSString *subject, *msgid;
@@ -1007,6 +1019,8 @@
       [self setText: [sourceMail contentForInlineForward]];
       if ([sourceMail isEncrypted])
         [self _fetchAttachmentsFromEncryptedMail: sourceMail];
+      else if ([sourceMail isOpaqueSigned])
+        [self _fetchAttachmentsFromOpaqueSignedMail: sourceMail];
       else
         [self _fetchAttachmentsFromMail: sourceMail];
     }
--- SOGo-4.0.6.orig/SoObjects/Mailer/SOGoMailBodyPart.m	2019-02-21 16:11:07.000000000 +0100
+++ SOGo-4.0.6/SoObjects/Mailer/SOGoMailBodyPart.m	2019-05-05 21:58:43.746452051 +0200
@@ -210,6 +210,28 @@
                                                inContext: localContext];
       obj = [clazz objectWithName:key inContainer: self];
     }
+  else if ([o isOpaqueSigned])
+    {
+      NGMimeMessage *m;
+      id part;
+
+      int i;
+
+      m = [[o content] messageFromOpaqueSignedData];
+      part = [m body];
+
+      for (i = 0; i < [[self bodyPartPath] count]; i++)
+        {
+          nbr = [[[self bodyPartPath] objectAtIndex: i] intValue]-1;
+          part = [[part parts] objectAtIndex: nbr];;
+        }
+
+      part = [[part parts] objectAtIndex: ([key intValue]-1)];
+      mimeType = [[part contentType] stringValue];
+      clazz = [SOGoMailBodyPart bodyPartClassForMimeType: mimeType
+                                               inContext: localContext];
+      obj = [clazz objectWithName:key inContainer: self];
+    }
   else
     {
       infos = [self partInfo];
@@ -354,6 +376,24 @@
       part = [m body];
 
       for (i = 0; i < [[self bodyPartPath] count]; i++)
+        {
+          nbr = [[[self bodyPartPath] objectAtIndex: i] intValue]-1;
+          part = [[part parts] objectAtIndex: nbr];;
+        }
+
+      return [part body];
+    }
+  else if ([o isOpaqueSigned])
+    {
+      NGMimeMessage *m;
+      id part;
+
+      unsigned int i, nbr;
+
+      m = [[o content] messageFromOpaqueSignedData];
+      part = [m body];
+
+      for (i = 0; i < [[self bodyPartPath] count]; i++)
         {
           nbr = [[[self bodyPartPath] objectAtIndex: i] intValue]-1;
           part = [[part parts] objectAtIndex: nbr];;
--- SOGo-4.0.6.orig/SoObjects/Mailer/SOGoMailObject+Draft.m	2019-02-21 16:11:07.000000000 +0100
+++ SOGo-4.0.6/SoObjects/Mailer/SOGoMailObject+Draft.m	2019-05-05 21:48:46.038426433 +0200
@@ -238,6 +238,24 @@
   return nil;
 }
 
+
+//
+//
+//
+- (NSString *) _contentForEditingFromOpaqueSignedMail
+{
+  SOGoUserDefaults *ud;
+  NGMimeMessage *m;
+
+  m = [[self content] messageFromOpaqueSignedData];
+  ud = [[context activeUser] userDefaults];
+
+  return [self _preferredContentFromPart: [m body]
+                               favorHTML: [[ud mailComposeMessageType] isEqualToString: @"html"]];
+
+  return nil;
+}
+
 //
 //
 //
@@ -250,6 +268,8 @@
 
   if ([self isEncrypted])
     output = [self _contentForEditingFromEncryptedMail];
+  else if ([self isOpaqueSigned])
+    output = [self _contentForEditingFromOpaqueSignedMail];
 
   // If not encrypted or if decryption failed, we fallback
   // to the normal content fetching code.
--- SOGo-4.0.6.orig/SoObjects/Mailer/SOGoMailObject.h	2019-02-21 16:11:07.000000000 +0100
+++ SOGo-4.0.6/SoObjects/Mailer/SOGoMailObject.h	2019-05-05 21:41:45.462408407 +0200
@@ -124,7 +124,8 @@
 - (BOOL) replied;     /* \Answered */
 - (BOOL) forwarded;   /* $forwarded */
 - (BOOL) deleted;     /* \Deleted */
-- (BOOL) isSigned;    /* S/MIME signed message */
+- (BOOL) isSigned;       /* S/MIME signed message (detached signature) */
+- (BOOL) isOpaqueSigned; /* S/MIME signed message (embedded content) */
 - (BOOL) isEncrypted; /* S/MIME encrypted message */
 
 /* deletion */
--- SOGo-4.0.6.orig/SoObjects/Mailer/SOGoMailObject.m	2019-02-21 16:11:07.000000000 +0100
+++ SOGo-4.0.6/SoObjects/Mailer/SOGoMailObject.m	2019-05-05 21:50:58.394432106 +0200
@@ -1201,6 +1201,19 @@
           return [clazz objectWithName:_key inContainer: self];
         }
     }
+  else if ([self isOpaqueSigned])
+    {
+      NGMimeMessage *m;
+      id part;
+
+      m = [[self content] messageFromOpaqueSignedData];
+
+      part = [[[m body] parts] objectAtIndex: ([_key intValue]-1)];
+      mimeType = [[part contentType] stringValue];
+      clazz = [SOGoMailBodyPart bodyPartClassForMimeType: mimeType
+                                               inContext: _ctx];
+      return [clazz objectWithName:_key inContainer: self];
+    }
 
   parts = [[self bodyStructure] objectForKey: @"parts"];
 
@@ -1738,18 +1751,47 @@
            [protocol isEqualToString: @"application/pkcs7-signature"]));
 }
 
+- (BOOL) isOpaqueSigned
+{
+  NSString *type, *subtype, *smimetype;
+  NGMimeType *contentType;
+
+  contentType = [[self mailHeaders] objectForKey: @"content-type"];
+  type = [[contentType type] lowercaseString];
+  subtype = [[contentType subType] lowercaseString];
+
+  if ([type isEqualToString: @"application"])
+    {
+      if ([subtype isEqualToString: @"x-pkcs7-mime"] ||
+          [subtype isEqualToString: @"pkcs7-mime"])
+        {
+          smimetype = [[contentType valueOfParameter: @"smime-type"] lowercaseString];
+          if ([smimetype isEqualToString: @"signed-data"])
+              return YES;
+        }
+    }
+
+  return NO;
+}
+
 - (BOOL) isEncrypted
 {
-  NSString *type, *subtype;
+  NSString *type, *subtype, *smimetype;
+  NGMimeType *contentType;
 
-  type = [[[[self mailHeaders] objectForKey: @"content-type"] type] lowercaseString];
-  subtype = [[[[self mailHeaders] objectForKey: @"content-type"] subType] lowercaseString];
+  contentType = [[self mailHeaders] objectForKey: @"content-type"];
+  type = [[contentType type] lowercaseString];
+  subtype = [[contentType subType] lowercaseString];
 
   if ([type isEqualToString: @"application"])
     {
       if ([subtype isEqualToString: @"x-pkcs7-mime"] ||
           [subtype isEqualToString: @"pkcs7-mime"])
-        return YES;
+        {
+          smimetype = [[contentType valueOfParameter: @"smime-type"] lowercaseString];
+          if ([smimetype isEqualToString: @"enveloped-data"])
+              return YES;
+        }
     }
 
   return NO;
--- SOGo-4.0.6.orig/UI/MailPartViewers/UIxMailRenderingContext.m	2019-02-21 16:11:07.000000000 +0100
+++ SOGo-4.0.6/UI/MailPartViewers/UIxMailRenderingContext.m	2019-05-05 21:52:06.986435046 +0200
@@ -256,10 +256,18 @@
       if ([st isEqualToString: @"x-pkcs7-mime"] ||
           [st isEqualToString: @"pkcs7-mime"])
         {
-          // If the mail account has a valid certificate, we try to decode
-          // the encrypted email. Otherwise, we fallback to a link viewer
-          if ([[[viewer clientObject] mailAccountFolder] certificate])
-            return [self encryptedViewer];
+          NSString *smt = [[[_info objectForKey:@"parameterList"] valueForKey:@"smime-type"] lowercaseString];
+          if ([smt isEqualToString:@"signed-data"])
+            {
+              return [self encryptedViewer];
+            }
+          else if ([smt isEqualToString:@"enveloped-data"])
+            {
+              // If the mail account has a valid certificate, we try to decode
+              // the encrypted email. Otherwise, we fallback to a link viewer
+              if ([[[viewer clientObject] mailAccountFolder] certificate])
+                return [self encryptedViewer];
+            }
         }
 
 #if 0 /* the link viewer looks better than plain text ;-) */
--- SOGo-4.0.6.orig/UI/WebServerResources/js/Mailer/Message.service.js	2019-02-21 16:11:07.000000000 +0100
+++ SOGo-4.0.6/UI/WebServerResources/js/Mailer/Message.service.js	2019-05-05 21:41:45.466408407 +0200
@@ -321,13 +321,22 @@
               };
             }
             else if (part.type == 'UIxMailPartEncryptedViewer') {
-              _this.encrypted = {
-                valid: part.valid
-              };
-              if (part.valid)
-                _this.encrypted.message = l("This message is encrypted");
-              else
-                _this.encrypted.message = l("This message can't be decrypted. Please make sure you have uploaded your S/MIME certificate from the mail preferences module.");
+              if (part.encrypted) {
+                _this.encrypted = {
+                  valid: part.decrypted
+                };
+                if (part.decrypted)
+                  _this.encrypted.message = l("This message is encrypted");
+                else
+                  _this.encrypted.message = l("This message can't be decrypted. Please make sure you have uploaded your S/MIME certificate from the mail preferences module.");
+              }
+              if (part.opaqueSigned) {
+                _this.signed = {
+                  valid: part.valid,
+                  certificate: part.certificates[part.certificates.length - 1],
+                  message: part.message
+                };
+              }
             }
             _.forEach(part.content, function(mixedPart) {
               _visit(mixedPart);
--- SOGo-4.0.6.orig/UI/MailPartViewers/UIxMailPartEncryptedViewer.h	2019-02-21 16:11:07.000000000 +0100
+++ SOGo-4.0.6/UI/MailPartViewers/UIxMailPartEncryptedViewer.h	2019-05-05 21:41:45.466408407 +0200
@@ -28,8 +28,20 @@
 
 @interface UIxMailPartEncryptedViewer : UIxMailPartViewer
 {
+  BOOL processed;
+  BOOL encrypted;
+  BOOL opaqueSigned;
+  BOOL validSignature;
+  NSMutableArray *certificates;
+  NSString *validationMessage;
 }
 
+- (BOOL) validSignature;
+- (NSString *) validationMessage;
+- (NSArray *) smimeCertificates;
+- (NSDictionary *) certificateForSubject: (NSString *) subject
+                               andIssuer: (NSString *) issuer;
+
 @end
 
 #endif /* UIXMAILPARTENCRYPTEDVIEWER_H */
--- SOGo-4.0.6.orig/UI/MailPartViewers/UIxMailPartEncryptedViewer.m	2019-02-21 16:11:07.000000000 +0100
+++ SOGo-4.0.6/UI/MailPartViewers/UIxMailPartEncryptedViewer.m	2019-05-05 21:55:08.426442823 +0200
@@ -19,6 +19,14 @@
   02111-1307, USA.
 */
 
+#if defined(HAVE_OPENSSL) || defined(HAVE_GNUTLS)
+#include <openssl/ssl.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/pkcs7.h>
+#include <openssl/x509.h>
+#endif
+
 #import <Foundation/NSDictionary.h>
 #import <Foundation/NSNull.h>
 #import <Foundation/NSValue.h>
@@ -36,11 +44,222 @@
 #import <SoObjects/Mailer/SOGoMailObject.h>
 #import <UI/MailerUI/WOContext+UIxMailer.h>
 
+#import <SOGo/NSString+Utilities.h>
+
 #import "UIxMailRenderingContext.h"
 #import "UIxMailPartEncryptedViewer.h"
 
 @implementation UIxMailPartEncryptedViewer
 
+#if defined(HAVE_OPENSSL) || defined(HAVE_GNUTLS)
+- (X509_STORE *) _setupVerify
+{
+  X509_STORE *store;
+  X509_LOOKUP *lookup;
+  BOOL success;
+
+  success = NO;
+
+  store = X509_STORE_new();
+  OpenSSL_add_all_algorithms();
+
+  if (store)
+    {
+      lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
+      if (lookup)
+        {
+          X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
+          lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
+          if (lookup)
+            {
+              X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
+              ERR_clear_error();
+              success = YES;
+            }
+        }
+    }
+
+  if (!success)
+    {
+      if (store)
+        {
+          X509_STORE_free(store);
+          store = NULL;
+        }
+    }
+
+  return store;
+}
+
+- (NSData *) _processMessageWith: (NSData *) signedData
+{
+  NSData *output;
+
+  STACK_OF(X509) *certs;
+  X509_STORE *x509Store;
+  BIO *msgBio, *obio;
+  PKCS7 *p7;
+  int err, i;
+ 
+  ERR_clear_error();
+
+  msgBio = BIO_new_mem_buf ((void *) [signedData bytes], [signedData length]);
+
+  p7 = SMIME_read_PKCS7(msgBio, NULL);
+
+  certs = NULL;
+  certificates = [NSMutableArray array];
+  validationMessage = nil;
+
+  if (p7)
+    {
+      if (OBJ_obj2nid(p7->type) == NID_pkcs7_signed)
+	{
+          NSString *subject, *issuer;
+	  X509 *x;
+	  
+	  certs = p7->d.sign->cert;
+
+          for (i = 0; i < sk_X509_num(certs); i++)
+            {
+	      BIO *buf;
+	      char p[1024];
+
+	      x = sk_X509_value(certs, i);
+
+	      memset(p, 0, 1024);
+	      buf = BIO_new(BIO_s_mem());
+	      X509_NAME_print_ex(buf, X509_get_subject_name(x), 0,
+                                 ASN1_STRFLGS_ESC_CTRL | XN_FLAG_SEP_MULTILINE | XN_FLAG_FN_LN);
+              BIO_read(buf, p, 1024);
+	      subject = [NSString stringWithUTF8String: p];
+	      BIO_free(buf);
+
+	      memset(p, 0, 1024);
+	      buf = BIO_new(BIO_s_mem());
+	      X509_NAME_print_ex(buf, X509_get_issuer_name(x), 0,
+                                 ASN1_STRFLGS_ESC_CTRL | XN_FLAG_SEP_MULTILINE | XN_FLAG_FN_LN);
+	      BIO_read(buf, p, 1024);
+	      issuer = [NSString stringWithUTF8String: p];
+	      BIO_free(buf);
+
+              [certificates addObject: [self certificateForSubject: subject
+                                                         andIssuer: issuer]];
+	    }
+	}
+      
+      err = ERR_get_error();
+      if (err)
+	{
+	  validSignature = NO;
+	}
+      else
+	{
+	  x509Store = [self _setupVerify];
+          obio = BIO_new(BIO_s_mem());
+
+	  validSignature = (PKCS7_verify(p7, NULL, x509Store, NULL,
+					 obio, 0) == 1);
+	  
+	  err = ERR_get_error();
+	  
+	  if (x509Store)
+	    X509_STORE_free (x509Store);
+	}
+
+      if (err)
+        {
+#ifdef HAVE_GNUTLS
+          const char* sslError;
+	  ERR_load_crypto_strings();
+          SSL_load_error_strings();
+          sslError = ERR_reason_error_string(err);
+          validationMessage = [[self labelForKey: [NSString stringWithUTF8String: sslError ? sslError : @"No error information available"]] retain];
+#elif OPENSSL_VERSION_NUMBER < 0x10100000L
+          const char* sslError;
+	  ERR_load_crypto_strings();
+          SSL_load_error_strings();
+          sslError = ERR_reason_error_string(err);
+          validationMessage = [[self labelForKey: [NSString stringWithUTF8String: sslError ? sslError : @"No error information available"]] retain];
+#else
+	  validationMessage = [[self labelForKey: @"No error information available"] retain];
+#endif /* HAVE_GNUTLS */
+
+           BUF_MEM *bptr; //DEL
+           BIO_get_mem_ptr(obio, &bptr); //DEL
+          // extract contents without validation
+          output = [ signedData embeddedContent ];
+        }
+      else
+        {
+           BUF_MEM *bptr;
+           BIO_get_mem_ptr(obio, &bptr);
+           output = [NSData dataWithBytes: bptr->data  length: bptr->length];
+        }
+    }
+
+  PKCS7_free(p7);
+  BIO_free (msgBio);
+  BIO_free (obio);
+  
+  if (validSignature)
+    validationMessage = [NSString stringWithString: [self labelForKey: @"Message is signed"]];
+  else if (!validationMessage)
+    validationMessage = [NSString stringWithString: [self labelForKey: @"Digital signature is not valid"]];
+
+  processed = YES;
+  opaqueSigned = YES;
+  return output;
+}
+
+- (BOOL) validSignature
+{
+  if (!processed)
+    NSLog(@"ERROR: validSignature called but not processed yet");
+    //[self _processMessage];
+
+  return validSignature;
+}
+
+- (NSDictionary *) certificateForSubject: (NSString *) subject
+                               andIssuer: (NSString *) issuer
+{
+  return [NSDictionary dictionaryWithObjectsAndKeys:
+                              [subject componentsFromMultilineDN], @"subject",
+                              [issuer componentsFromMultilineDN], @"issuer",
+                       nil];
+}
+
+- (NSArray *) smimeCertificates
+{
+  return certificates;
+}
+
+- (NSString *) validationMessage
+{
+  if (!processed)
+    NSLog(@"ERROR: validationMessage called but not processed yet");
+    //[self _processMessage];
+
+  return validationMessage;
+}
+#else
+- (NSArray *) smimeCertificates
+{
+  return nil;
+}
+
+- (BOOL) validSignature
+{
+  return NO;
+}
+
+- (NSString *) validationMessage
+{
+  return nil;
+}
+#endif
+
 - (void) _attachmentIdsFromBodyPart: (id) thePart
                            partPath: (NSString *) thePartPath
 {
@@ -91,26 +310,107 @@
 
 - (id) renderedPart
 {
+  SOGoMailObject *mailObject;
   NSData *certificate, *decryptedData, *encryptedData;
   id info, viewer;
 
-  certificate = [[[self clientObject] mailAccountFolder] certificate];
-  encryptedData = [[self clientObject] content];
-  decryptedData = [encryptedData decryptUsingCertificate: certificate];
+  mailObject = [[self clientObject] mailObject];
+  if ([mailObject isEncrypted])
+    {
+      encrypted = YES;
+      certificate = [[[self clientObject] mailAccountFolder] certificate];
+      encryptedData = [[self clientObject] content];
+      decryptedData = [encryptedData decryptUsingCertificate: certificate];
 
-  if (decryptedData)
+      if (decryptedData)
+        {
+          NGMimeMessageParser *parser;
+          NGMimeMessage *message;
+          NGMimeType *contentType;
+          NSString *type, *subtype, *smimetype;
+          id part;
+
+          parser = [[NGMimeMessageParser alloc] init];
+          message = [parser parsePartFromData: decryptedData];
+
+          // Extract contents if the encrypted messages contains opaque signed data
+          contentType = [message contentType];
+          type = [[contentType type] lowercaseString];
+          subtype = [[contentType subType] lowercaseString];
+          if ([type isEqualToString: @"application"])
+            {
+              if ([subtype isEqualToString: @"x-pkcs7-mime"] ||
+                  [subtype isEqualToString: @"pkcs7-mime"])
+                {
+                  smimetype = [[contentType valueOfParameter: @"smime-type"] lowercaseString];
+                  if ([smimetype isEqualToString: @"signed-data"])
+                    {
+                      NGMimeMessageParser *parser;
+                      opaqueSigned = YES;
+                      NSData *extractedData = [self _processMessageWith: decryptedData];
+                      if (extractedData)
+                        {
+                          parser = [[NGMimeMessageParser alloc] init];
+                          message = [parser parsePartFromData: extractedData];
+                          decryptedData = extractedData;
+                          RELEASE(parser);
+                        }
+                    }
+                }
+            }
+
+          processed = YES;
+	  part = [message retain];
+
+          info = [NSDictionary dictionaryWithObjectsAndKeys: [[part contentType] type], @"type",
+                               [[part contentType] subType], @"subtype",
+                               [[part contentType] parametersAsDictionary], @"parameterList", nil];
+          viewer = [[[self context] mailRenderingContext] viewerForBodyInfo: info];
+          [viewer setBodyInfo: info];
+          [viewer setFlatContent: decryptedData];
+          [viewer setDecodedContent: [part body]];
+
+          // attachmentIds is empty in an ecrypted email as the IMAP body structure
+          // is of course not available for file attachments
+          [self _attachmentIdsFromBodyPart: [part body]  partPath: @""];
+          [viewer setAttachmentIds: attachmentIds];
+
+          return [NSDictionary dictionaryWithObjectsAndKeys:
+                                     [self className], @"type",
+                                   [NSNumber numberWithBool: YES], @"encrypted",
+                                   [NSNumber numberWithBool: YES], @"decrypted",
+                                   [NSNumber numberWithBool: opaqueSigned], @"opaqueSigned",
+                                   [NSNumber numberWithBool: [self validSignature]], @"valid",
+                                   [NSArray arrayWithObject: [viewer renderedPart]], @"content",
+                                   [self smimeCertificates], @"certificates",
+                                   [self validationMessage], @"message",
+                               nil];
+        }
+    }
+  else if ([mailObject isOpaqueSigned])
     {
       NGMimeMessageParser *parser;
+      NGMimeMessage *message;
       id part;
+      opaqueSigned = YES;
+      encryptedData = [[self clientObject] content];
+      NSData *extractedData = [self _processMessageWith: encryptedData];
+      if (extractedData)
+        {
+          parser = [[NGMimeMessageParser alloc] init];
+          message = [parser parsePartFromData: extractedData];
+          RELEASE(parser);
+        }
 
-      parser = [[NGMimeMessageParser alloc] init];
-      part = [[parser parsePartFromData: decryptedData] retain];
+      processed = YES;
+      part = [message retain];
 
       info = [NSDictionary dictionaryWithObjectsAndKeys: [[part contentType] type], @"type",
-                           [[part contentType] subType], @"subtype", nil];
+                           [[part contentType] subType], @"subtype",
+                           [[part contentType] parametersAsDictionary], @"parameterList", nil];
       viewer = [[[self context] mailRenderingContext] viewerForBodyInfo: info];
       [viewer setBodyInfo: info];
-      [viewer setFlatContent: decryptedData];
+      [viewer setFlatContent: extractedData];
       [viewer setDecodedContent: [part body]];
 
       // attachmentIds is empty in an ecrypted email as the IMAP body structure
@@ -120,8 +420,12 @@
 
       return [NSDictionary dictionaryWithObjectsAndKeys:
                                  [self className], @"type",
-                               [NSNumber numberWithBool: YES], @"valid",
+                               [NSNumber numberWithBool: NO], @"encrypted",
+                               [NSNumber numberWithBool: YES], @"opaqueSigned",
+                               [NSNumber numberWithBool: [self validSignature]], @"valid",
                                [NSArray arrayWithObject: [viewer renderedPart]], @"content",
+                               [self smimeCertificates], @"certificates",
+                               [self validationMessage], @"message",
                            nil];
     }
 
@@ -129,7 +433,9 @@
   // Decryption failed, let's return something else...
   return [NSDictionary dictionaryWithObjectsAndKeys:
                          [self className], @"type",
-                           [NSNumber numberWithBool: NO], @"valid",
+                       [NSNumber numberWithBool: encrypted], @"encrypted",
+                       [NSNumber numberWithBool: NO], @"decrypted",
+                       [NSNumber numberWithBool: NO], @"opaqueSigned",
                        [NSArray array], @"content",
                        nil];
 }
