I try to write a little mail milter to sign mails with S/MIME. So far, I have completed to the code up to signing the mail. I used the demos/smime code examples in openssl to do the job. Unfortunately the examples demonstrate how to write a input message to an output file, but I need the result as a string.
This is my Smime-method:
void Smime::sign() {
    if (!isLoaded())
        return;
    // Null-mailer or unknown
    if (mailFrom.empty())
        return;
    auto *client = util::mlfipriv(ctx);
    bool signedOrEncrypted = false;
    std::vector<std::string> contentType;
    contentType.push_back("multipart/signed");
    contentType.push_back("multipart/encrypted");
    contentType.push_back("application/pkcs7-mime");
    if (client->sessionData.count("Content-Type") == 1) {
        std::string value {client->sessionData["Content-Type"]};
        std::size_t found;
        for (int i=0; i<contentType.size(); i++) {
            found = value.find(contentType.at(i));
            if (found != std::string::npos) {
                signedOrEncrypted = true;
                break;
            }
        }
    }
    if (signedOrEncrypted) {
        const char logmsg[] = "Message already signed or encrypted";
        syslog(LOG_NOTICE, "%s", logmsg);
        return;
    }
    /*
     * TODO:
     * Catch more cases, where an email already could have been encrypted
     * or signed elsewhere.
     */
    mapfile::Map email {mailFrom};
    auto cert = fs::path(email.getSmimeFilename<mapfile::Smime::CERT>());
    auto key = fs::path(email.getSmimeFilename<mapfile::Smime::KEY>());
    if (!fs::exists(cert) && !fs::is_regular(cert))
        return;
    if (!fs::exists(key) && !fs::is_regular(key))
        return;
    // Signing starts here
    BIO *in = nullptr, *out = nullptr, *tbio = nullptr;
    X509 *scert = nullptr;
    EVP_PKEY *skey = nullptr;
    PKCS7 *p7 = nullptr;
    int flags = PKCS7_DETACHED | PKCS7_STREAM;
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();
    // S/MIME certificate
    tbio = BIO_new_file(cert.string().c_str(), "r");
    if (!tbio) {
        std::cerr << "Error: BIO_new_file(Cert) failed" << std::endl;
        return;
    }
    scert = PEM_read_bio_X509(tbio, nullptr, 0, nullptr);
    // S/MIME key
    tbio = BIO_new_file(key.string().c_str(), "r");
    if (!tbio) {
        std::cerr << "Error: BIO_new_file(Key) failed" << std::endl;
        return;
    }
    skey = PEM_read_bio_PrivateKey(tbio, nullptr, 0, nullptr);
    if (!scert || !skey) {
        std::cerr << "Error: Neither cert or key was loaded" << std::endl;
        return;
    }
    // Loading mail content from temp file
    in = BIO_new_file(client->getTempFile().c_str(), "r");
    if (!in) {
        std::cerr << "Error: Unable to load content from temp file"
                  << std::endl;
        return;
    }
    // Signing
    p7 = PKCS7_sign(scert, skey, nullptr, in, flags);
    if (!p7) {
        std::cerr << "Error: Message could not be signed" << std::endl;
        return;
    }
    // Cleanup
    PKCS7_free(p7);
    X509_free(scert);
    EVP_PKEY_free(skey);
    BIO_free(in);
    BIO_free(out);
    BIO_free(tbio);
    smimeSigned = true;
}
As there are more than 1600 man pages for openssl, I have no idea where to look for information.
I would love to use the "p7" and write it to a simple std::string (or char *, if required). The milter application I write will pick up this string and does a change-body (Not yet written, but this is my idea).
Can somebody point me to routines/man pages or does have a code example that may help me?
Thanks in advance