2

I am trying to find a S/MIME email encryption library for an iOS email app I am creating in Swift. I have been having trouble trying to find a library for the encryption, has anyone had any experience with this? I have tried OpenSSL but have run into issues with importing all the files in need in the bridging header, for example I need to use functions in pem.h but if I try import pem.h the bridging header fails to be imported altogether.

Any help with this would be greatly appreciated.

  • You should ask a specific question for a particular problem. Since Stack Overflow hides the Close reason from you: *"Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it."* – jww Mar 30 '17 at 18:52
  • If you need crypto library on iOS, OpenSSL is the way to go. You should try to solve specific problems with building the library into static lib or framework by asking specific questions. I believe this resource is up to date: [OpenSSL-for-iPhone](https://github.com/x2on/OpenSSL-for-iPhone) – Slava Ivanov May 04 '17 at 15:54

1 Answers1

1

I had a similar requirement. Eventually I had to import openSSL and write my own code to handle the decrypt of PKCS7. I made a small github repo which should help

https://github.com/zkrige/iOS-pkcs7-decrypt

here is the gist of the code

#include <openssl/bio.h>
#include <openssl/cms.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/crypto.h>
#include <openssl/rand.h>

X509 *getCert(const char *certificate) {
    BIO *membuf = BIO_new(BIO_s_mem());
    BIO_puts(membuf, certificate);
    X509 *x509 = PEM_read_bio_X509(membuf, NULL, NULL, NULL);
    return x509;
}

EVP_PKEY *getKey(const char *privateKey) {
    BIO *membuf = BIO_new(BIO_s_mem());
    BIO_puts(membuf, privateKey);
    EVP_PKEY *key = PEM_read_bio_PrivateKey(membuf, NULL, 0, NULL);
    return key;
}

PKCS7 *getContainer(const char *encrypted) {
    BIO* membuf = BIO_new(BIO_s_mem());
    BIO_set_mem_eof_return(membuf, 0); 
    BIO_puts(membuf, encrypted);
    PKCS7* pkcs7 = SMIME_read_PKCS7(membuf, NULL);
    if (!pkcs7) {
        fprintf(stderr, "error: %ld\n", ERR_get_error());
    }
    return pkcs7;
}

char *decrypt(PKCS7 *pkcs7, EVP_PKEY *pkey, X509 *cert) {

    BIO *out = BIO_new(BIO_s_mem());
    if (PKCS7_decrypt(pkcs7, pkey, cert, out, 0) != 1) {
        X509_free(cert);
        EVP_PKEY_free(pkey);
        PKCS7_free(pkcs7);
        fprintf(stderr, "Error decrypting PKCS#7 object: %ld\n", ERR_get_error());
        return NULL;
    }
    BUF_MEM* mem;
    BIO_get_mem_ptr(out, &mem);
    char *data = malloc(mem->length + 1);
    memcpy(data, mem->data, mem->length + 1);
    BIO_flush(out);
    BIO_free(out);
    return data;

}

char *decrypt_smime(const char *encrypted, const char *privateKey, const char *certificate) {

    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    X509 *cert = getCert(certificate);
    if (!cert) {
        return NULL;
    }

    EVP_PKEY *pkey = getKey(privateKey);
    if (!pkey) {
        X509_free(cert);
        return NULL;
    }

    PKCS7 *pkcs7 = getContainer(encrypted);
    if (!pkcs7) {
        X509_free(cert);
        EVP_PKEY_free(pkey);
        return NULL;
    }

    char *data = decrypt(pkcs7, pkey, cert);

    X509_free(cert);
    EVP_PKEY_free(pkey);
    PKCS7_free(pkcs7);

    return data;
}
Zayin Krige
  • 3,229
  • 1
  • 35
  • 34