S/MIMEを使用してメールに署名するために少しメールmilterを書き込もうとします。これまでのところ、私はメールにサインアップするまでにコードを完成させました。私は仕事をするためにopensslのデモ/スミムコードの例を使用しました。残念ながら、出力ファイルに入力メッセージを書き込む方法を示していますが、結果は文字列として必要です。PKCS7_signの結果をchar *またはstd :: stringに取得する方法
これは私のSMIME-方法である:opensslのための1600の以上のmanページがあるので
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;
}
、私はどこの情報を探すには考えています。
私は "p7"を使い、単純なstd :: string(または必要に応じてchar *)に書きたいと思います。私が書いたmilterアプリケーションは、この文字列をピックアップし、チェンジボディを行います(まだ書かれていませんが、これは私の考えです)。
誰かがルーチン/マニュアルページを指すことができますか、私に役立つコード例がありますか?事前に
おかげ
私はあなたが '文字でそれを置くことができるとは思わない*'切り捨てう埋め込ま 'NULL'、があるかもしれないので、結果。 – jww
このコード例は、BIO_new_file( "smout.txt"、 "w")を呼び出します。 ... SMIME_write_PKCS7(out、p7、in、flags) 結果はbase64でエンコードされます。私はかなり確信しています、それは仕事をするだろう1つまたは2つの機能だけです。しかしどちら? :-) –