Search code examples
exchange-serverexchangewebservicesx509certificate

Parsing a X509Certificate from Exchange


I am trying to retrieve the certificate of an Microsoft Exchange contact. It was set in Outlook by importing it in the certificate tab.

It is available by using PidTagUserX509Certificate on EWS, see https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxoabk/e4de26c4-9bcb-4da2-99c6-5f67aebc221a but i have to admit i do not understand how to handle the object as described in the documentation.

I try to base64-decode the retrieved data, then use a X509 CertificateFactory to read the certificate.

byte[] bytes = Base64.decode(certificateValue, Base64.DEFAULT);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(is);

This leads to an parsing exception: error:0c0000be:ASN.1 encoding routines:OPENSSL_internal:WRONG_TAG

My Code runs on Android, but the issue should be universal.

You can find the base64 data here: https://pastebin.com/dCnMtjn4

Any idea how i could get to the certificate?


Solution

  • It seems that the data is enveloped. First 12 bytes is kind of envelope (idk what it is) and the rest bytes look as X.509 cert. After first line, skip first 12 bytes and pass the rest of the byte array to ByteArrayInputStream. I'm not familiar with Java, but there should be kind of .Skip method for arrays? Quick google suggest, you can do it this way:

    byte[] bytes = Base64.decode(certificateValue, Base64.DEFAULT);
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    ByteArrayInputStream is = new ByteArrayInputStream(bytes);
    is.skip(12);
    X509Certificate certificate = (X509Certificate)certificateFactory.generateCertificate(is);