Cyberiafreak

"Fortunate are those who take the first steps.” ― Paulo Coelho

How to use EWS API for reading SMIME email message

What is SMIME – http://technet.microsoft.com/en-us/library/aa995740(v=exchg.65).aspx 

class Program
{
static ExchangeService exService;

static void Main(string[] args)
{
try
{
exService = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
exService.UseDefaultCredentials = true;
exService.AutodiscoverUrl(“user@Contoso.com”, RedirectionCallback);

Console.WriteLine(“Connected(Autodiscovered EWS Endpoint)- ” + exService.Url);

//find the trace log dumped in debug\log.txt
exService.TraceEnabled = true;
exService.TraceListener = new TraceListener();
exService.TraceEnablePrettyPrinting = true;

Console.WriteLine(“Getting inbox items..”);
byte[] data = GetInboxMailItems();

if (data == null)
{
Console.WriteLine(“No Mails retreived “);
Console.ReadKey();
return;
}
//
byte[] resultObject= DecryptToFile(data);

if(resultObject==null)
{
Console.WriteLine(“No object retrieved from Decrypt. somthing wrong in this method”);

}
else
{
string uniqueFname = Path.GetRandomFileName()+”.eml”;
Console.WriteLine(@”Decrypted EML file dumped here — c:\temp\” + uniqueFname);

//Find the decrypted file here
//Load this file in Outlook for testing.
File.WriteAllBytes(@”c:\temp\” + uniqueFname, resultObject);
}

//write the decrypted content to a file – mail item .eml
Console.WriteLine(“Press any key to exit..”);
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine(“Error while initializing..” + ex.ToString());
}
}

/// <summary>
///
/// </summary>
private static byte[] GetInboxMailItems()
{
byte[] data = null;

//Get inbox unread mails (have a mail ready for decrypt which is signed & decrypt)
Folder inbox = Folder.Bind(exService, WellKnownFolderName.Inbox);
SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));

ItemView view = new ItemView(1);

FindItemsResults<Item> findResults = exService.FindItems(WellKnownFolderName.Inbox, sf, view);

//Have atleast 1 unread ‘encrypted,signed’ mail for this testing
if (findResults.TotalCount == 0)
{
return data;
Console.WriteLine(“No Mails retreived”);
}

//Loop through the items and do whatever is required.
foreach (Item item in findResults)
{
//Load the mail item
PropertySet ps = new PropertySet(BasePropertySet.FirstClassProperties, ItemSchema.Attachments);
item.Load(ps);

foreach (Microsoft.Exchange.WebServices.Data.Attachment attach in item.Attachments)
{
// find the encrypted mails attachment- in general body and any mail content for encrypted mail would be bundled as smime.p7m file in mailstore
if (attach.Name == “smime.p7m”)
{
Console.WriteLine(“Process smime.p7m file”);
FileAttachment fileAttachment = (FileAttachment)attach;
MemoryStream stream = new MemoryStream();
fileAttachment.Load(stream);
StreamReader stReader = new StreamReader(stream);
stream.Seek(0, SeekOrigin.Begin);
data = stream.GetBuffer();

return data;
}
}
}
return data;
}

/// <summary>
///
/// </summary>
/// <param name=”data”></param>
private static byte[] DecryptToFile(byte[] data)
{
byte[] resultObject = null;

try
{
EnvelopedCms envelopObj = new EnvelopedCms();
envelopObj.Decode(data);

Console.WriteLine(“Encryption Algorithm: Name={0}”, envelopObj.ContentEncryptionAlgorithm.Oid.FriendlyName);
Console.WriteLine(“Key length={0}”, envelopObj.ContentEncryptionAlgorithm.KeyLength);
Console.WriteLine(“Recipients ({0})”, envelopObj.RecipientInfos.Count);

foreach (RecipientInfo r in envelopObj.RecipientInfos)
{
Console.WriteLine(” Encrypted key={0}”, BitConverter.ToString(r.EncryptedKey));
Console.WriteLine(” Encryption alg={0}”, r.KeyEncryptionAlgorithm.Oid.FriendlyName);

if (r.RecipientIdentifier.Type == SubjectIdentifierType.IssuerAndSerialNumber)
{
X509IssuerSerial xi = (X509IssuerSerial)r.RecipientIdentifier.Value;
Console.WriteLine(” Issuer={0}”, xi.IssuerName);
Console.WriteLine(” SerialNumber={0}”, xi.SerialNumber);
}
else
{
Console.WriteLine(” SubjectKeyInfo={0}”, r.RecipientIdentifier.Value);
}
}

Console.WriteLine(“Certificates ({0})”, envelopObj.Certificates.Count);

foreach (X509Certificate2 cert in envelopObj.Certificates)
{
Console.WriteLine(“Subject={0}”, cert.SubjectName);
}

Console.WriteLine(“Unprotected Attributes ({0})”, envelopObj.UnprotectedAttributes.Count);

foreach (CryptographicAttributeObject obj in envelopObj.UnprotectedAttributes)
{
Console.WriteLine(obj.Oid.FriendlyName);
}

envelopObj.Decrypt();
Console.WriteLine(“Success. Decrypted… !!”);
resultObject = envelopObj.ContentInfo.Content;

return resultObject; ;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return resultObject;
}

/// <summary>
///
/// </summary>
/// <param name=”url”></param>
/// <returns></returns>
static bool RedirectionCallback(string url)
{
// Return true if the URL is an HTTPS URL.
return url.ToLower().StartsWith(“https://&#8221;);
}
}

/// <summary>
///
/// </summary>
public class TraceListener : ITraceListener
{
#region ITraceListener Members

public void Trace(string traceType, string traceMessage)
{
CreateXMLTextFile(traceType + ” — ” + traceMessage.ToString());
}

#endregion

private void CreateXMLTextFile(string traceContent)
{
string strPath = System.AppDomain.CurrentDomain.BaseDirectory;
strPath = strPath + “\\Log.txt”;
System.IO.FileStream fs;
if (System.IO.File.Exists(strPath) == false)
{
fs = System.IO.File.Create(strPath);
}
else
{
fs = System.IO.File.OpenWrite(strPath);
}

fs.Close();

// Create an instance of StreamWriter to write text to a file.
System.IO.StreamWriter sw = System.IO.File.AppendText(strPath);
sw.WriteLine(System.DateTime.Now.ToString() + “: ” + traceContent);
sw.Close();

}
}

Advertisements

April 15, 2014 - Posted by | Uncategorized | , ,

10 Comments »

  1. hi Mahesh,

    I am working on sending smime emails using EWS API. can you please help by providing c# code?

    Like

    Comment by nipu7 | February 26, 2015 | Reply

    • Hi Nipu7, Thanks for visiting my blog. As I remember correctly, I have shared the actual code as it is. Should work. Please copy and try as you wish.

      Mahesh

      Like

      Comment by Cyberiafreak | February 26, 2015 | Reply

  2. hi Mahesh, thanks for the quick reply. can you please provide me with the url of that post?

    Like

    Comment by nipu7 | February 26, 2015 | Reply

  3. Ok, got it. Allow me few days time, I have to check in my drive and let you know.

    Like

    Comment by Cyberiafreak | February 26, 2015 | Reply

    • thanks a lot

      Like

      Comment by nipu7 | February 26, 2015 | Reply

      • Sorry I did not try the sending part. Sending should be the easier one than reading. You will find some samples in .net for sure (sending) where as reading is trickier.

        Like

        Comment by Cyberiafreak | February 28, 2015

  4. HI Mahesh, Is there a way to read digitally signed email(not encrypted) & save the digital certificate to a folder.

    Like

    Comment by Senthil | March 9, 2015 | Reply

  5. I tried this solution, but I’ve encountered exception on “Decode” operation

    System.Security.Cryptography.CryptographicException: ASN1 bad tag value met.
    in System.Security.Cryptography.Pkcs.EnvelopedCms.OpenToDecode(Byte[] encodedMessage)
    in System.Security.Cryptography.Pkcs.EnvelopedCms.Decode(Byte[] encodedMessage)
    in myExchange.Email.DecryptToFile(Byte[] data)

    Am I doing something wrong?

    Like

    Comment by Rafal | February 21, 2017 | Reply


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: