outlookmicrosoft-graph-apioutlook-addinoutlook-web-addinssmime

How to add smime certificate to outlook contacts programmatically?


We're currently working on a project that requires adding S/MIME certificates to outlook contacts. Currently there's no api to add or retrieve S/MIME related information with existing solutions (We looked into Graph API but it doesn't provide the functionality. We've also looked into outlook addin JS docs. It also, doesn't reference anything related to S/MIME).

Our guess is that we need to add the certificates in the local device. We got this code snippet on Github which we think adds S/MIME certificate to our own email only but not contacts.

So, how to add or import S/MIME certificate of outlook contacts Programmatically?

Certificate field on Contacts


Solution

  • I found a dated solution attempt in this post:

       private static object[] BuildProperty(byte[] rawData)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                byte[] headerWithoutLength = { 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00 };
                ms.Write(headerWithoutLength, 0, headerWithoutLength.Length);
                byte[] lengthBytes = BitConverter.GetBytes((short)(rawData.Length + 4));
                ms.WriteByte(lengthBytes[0]);
                ms.WriteByte(lengthBytes[1]);
                ms.Write(rawData, 0, rawData.Length);
                byte[] footer = { 0x06, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 
                    0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00 };
                ms.Write(footer, 0, footer.Length);
    
                object[] o = new object[] { ms.ToArray() };
                return o;
            }
    
        }
    
        private static void Create()
        {
            OutLook.Application outlookObj = new OutLook.Application();
            try
            {
                X509Certificate2 existingCert = new X509Certificate2(@"[path to my certificate].cer");
                byte[] result = existingCert.RawData;
    
                OutLook.MAPIFolder fldContacts = (OutLook.MAPIFolder)outlookObj.Session.GetDefaultFolder(OutLook.OlDefaultFolders.olFolderContacts);
    
                OutLook.ContactItem newContact = (OutLook.ContactItem)fldContacts.Items.Add(OutLook.OlItemType.olContactItem);
    
                newContact.FirstName = "Test Name";
                newContact.FileAs = "Test Name";
    
                object[] o = BuildProperty(result);
                newContact.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3A701102", o);
    
                newContact.Save();
            }
            finally
            {
                Marshal.ReleaseComObject(outlookObj);
            }
        }
    

    It creates a new contact and assigns a certificate to it. To assign a certificate to an existing contact should be similar. Additional error checking is required to make this snippet useful and trustworthy.