Search code examples
microsoft-graph-apiazure-keyvaultx509certificate2mailkitmimekit

Mimekit - Access is denied trying to decrypt


I'm getting this error when trying to decrypt a MIME message:enter image description here

When I decrypt it in my local machine I can decrypt the mail without any problem, but the app deployed in server can't decrypt and results in this error. this is the code I'm using for decrypting

GraphServiceClient graphClient = new GraphServiceClient(clientSecretCredential, new string[] { _laCaixaSettings.GraphApiSettings.Scope });
var streamMessage = await graphClient.GetMessage(_laCaixaSettings.GraphApiSettings.UserId, pasarelaSettings.FicheroId);
using var message = await MimeMessage.LoadAsync(streamMessage);
var decryptedStream = await MimeMailUtils.Decrypt(message, _laCaixaSettings.GraphApiSettings.PrivateCertificate);
    
public static async Task<Stream> GetMessage(this GraphServiceClient graphServiceClient, string userId, string messageId)
{
    var request = graphServiceClient.Users[userId].Messages[messageId].Request().GetHttpRequestMessage();
    request.RequestUri = new Uri(request.RequestUri.OriginalString + "/$value");
    var response = await graphServiceClient.HttpProvider.SendAsync(request);
    response.EnsureSuccessStatusCode();
    var content = await response.Content.ReadAsStreamAsync();
    content.Position = 0;
    return content;
}

public static async Task<MimeEntity> Decrypt(MimeMessage message, X509Certificate2 certificate)
{
    var encryptedContent = (ApplicationPkcs7Mime)message.Body;
    using var context = new WindowsSecureMimeContext(StoreLocation.CurrentUser);
    context.Import(StoreName.CertificateAuthority, certificate);
    return await encryptedContent.DecryptAsync(context);
}

And this is how I get the certificate

public void SetSecrets()
{
    using KeyVaultClient client = VaultClientExtensions.GetKeyVaultClient(AzureVaultManagerSettings.ClientId, AzureVaultManagerSettings.ClientSecret);
    var secret = AsyncUtil.RunSync(() => client.GetSecret<string>(AzureVaultManagerSettings.SecretUrl));
    GraphApiSettings.PrivateCertificate = new X509Certificate2(
        Convert.FromBase64String(secret),
        string.Empty,
        X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
}

I believe the problem could be that this certificate is not installed in the server. Could anyone help me with this? Thanks in advance!


Solution

  • You don't have access to StoreName.CertificateAuthority.

    If you look at the stack trace in the exception, it is failing in System.Security.Cryptography.X509Certificates.X509Store.Open()

    Generally, the StoreName.CertificateAuthority is only accessible to admin users.