Code:
#include <string>
#include <exception>
using std::string;
//typedef struct RSA;
#include <openssl/rsa.h>
class ReadError : public std::exception
{
public:
virtual const char* what() const throw();
};
class NoKeypairLoaded : public std::exception
{
public:
virtual const char* what() const throw();
};
class AccessCard
{
public:
AccessCard();
~AccessCard();
void Generate();
void Load(const string& pem, const string& pass);
void PublicKey(string& pem) const;
void PrivateKey(string& pem, const string& passphrase) const;
void Seal(FILE* in_file, FILE* out_file);
void Unseal(FILE* in_file, FILE* out_file);
private:
void CheckKey() const;
RSA* keypair;
};
class BioBox
{
public:
struct Buffer
{
void* buf;
int size;
};
BioBox();
~BioBox();
void ConstructSink(const string& str);
void NewBuffer();
BIO* Bio() const;
Buffer ReadAll();
private:
BIO* bio;
Buffer buf;
};
class EvpBox
{
public:
EvpBox(RSA* keyp);
~EvpBox();
EVP_PKEY* Key();
private:
EVP_PKEY* evpkey;
};
//--------------------
#include <openssl/pem.h>
const char* ReadError::what() const throw()
{
return "Problem reading BIO.";
}
const char* NoKeypairLoaded::what() const throw()
{
return "No keypair loaded.";
}
AccessCard::AccessCard()
: keypair(NULL)
{
if (EVP_get_cipherbyname("aes-256-cbc") == NULL)
OpenSSL_add_all_algorithms();
}
AccessCard::~AccessCard()
{
RSA_free(keypair);
}
void AccessCard::CheckKey() const
{
if (!keypair)
throw NoKeypairLoaded();
}
void AccessCard::Generate()
{
RSA_free(keypair);
keypair = RSA_generate_key(2048, RSA_F4, NULL, NULL);
CheckKey();
}
static char *LoseStringConst(const string& str)
{
return const_cast<char*>(str.c_str());
}
static void* StringAsVoid(const string& str)
{
return reinterpret_cast<void*>(LoseStringConst(str));
}
BioBox::BioBox()
: bio(NULL)
{
buf.buf = NULL;
buf.size = 0;
}
BioBox::~BioBox()
{
BIO_free(bio);
free(buf.buf);
}
void BioBox::ConstructSink(const string& str)
{
BIO_free(bio);
bio = BIO_new_mem_buf(StringAsVoid(str), -1);
if (!bio)
throw ReadError();
}
void BioBox::NewBuffer()
{
BIO_free(bio);
bio = BIO_new(BIO_s_mem());
if (!bio)
throw ReadError();
}
BIO* BioBox::Bio() const
{
return bio;
}
BioBox::Buffer BioBox::ReadAll()
{
buf.size = BIO_ctrl_pending(bio);
buf.buf = malloc(buf.size);
if (BIO_read(bio, buf.buf, buf.size) < 0) {
//if (ERR_peek_error()) {
// ERR_reason_error_string(ERR_get_error());
// return NULL;
//}
throw ReadError();
}
return buf;
}
EvpBox::EvpBox(RSA* keyp)
{
evpkey = EVP_PKEY_new();
if (!EVP_PKEY_set1_RSA(evpkey, keyp)) {
throw ReadError();
}
}
EvpBox::~EvpBox()
{
EVP_PKEY_free(evpkey);
}
EVP_PKEY* EvpBox::Key()
{
return evpkey;
}
static int pass_cb(char* buf, int size, int rwflag, void* u)
{
const string pass = reinterpret_cast<char*>(u);
int len = pass.size();
// if too long, truncate
if (len > size)
len = size;
pass.copy(buf, len);
return len;
}
void AccessCard::Load(const string& pem, const string& pass)
{
RSA_free(keypair);
BioBox bio;
bio.ConstructSink(pem);
keypair = PEM_read_bio_RSAPrivateKey(bio.Bio(), NULL, pass_cb,
StringAsVoid(pass));
CheckKey();
}
void AccessCard::PublicKey(string& pem) const
{
CheckKey();
BioBox bio;
bio.NewBuffer();
int ret = PEM_write_bio_RSA_PUBKEY(bio.Bio(), keypair);
if (!ret)
throw ReadError();
const BioBox::Buffer& buf = bio.ReadAll();
pem = string(reinterpret_cast<const char*>(buf.buf), buf.size);
}
void AccessCard::PrivateKey(string& pem, const string& passphrase) const
{
CheckKey();
BioBox bio;
bio.NewBuffer();
EvpBox evp(keypair);
int ret = PEM_write_bio_PKCS8PrivateKey(bio.Bio(), evp.Key(),
EVP_aes_256_cbc(),
LoseStringConst(passphrase),
passphrase.size(), NULL, NULL);
if (!ret)
throw ReadError();
const BioBox::Buffer& buf = bio.ReadAll();
pem = string(reinterpret_cast<const char*>(buf.buf), buf.size);
}
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <arpa/inet.h> /* For htonl() */
void AccessCard::Seal(FILE* in_file, FILE* out_file)
{
CheckKey();
// see below
}
void AccessCard::Unseal(FILE* in_file, FILE* out_file)
{
CheckKey();
}
//-------------------------------------------------------------------
// this wont be in the final file... it's our unit test
//-------------------------------------------------------------------
#include <iostream>
#include <assert.h>
using std::cout;
int main()
{
AccessCard acc;
// New key
acc.Generate();
string pem;
//acc.PublicKey(pem);
//cout << pem << "\n";
acc.PrivateKey(pem, "hello");
//cout << pem << "\n";
//// ----------------
acc.Load(pem, "hello");
acc.PublicKey(pem);
//cout << pem << "\n";
//acc.Seal(stdin, stdout);
return 0;
}
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <arpa/inet.h> /* For htonl() */
// rsa key should be 2048 bit with 65537 exponent
char* PUBLIC_KEY_PEM =
"-----BEGIN PUBLIC KEY-----\n"
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwu4ymKmuXoSvZn+TLOIh\n"
"SXq7w+P1OeM9LCDt7ZpR/krdMyW6UZBnZCNnB/1KWg+3dtO07ScSBgE0U/EMNvHB\n"
"Im/tvzhomZgMGtL0Ln+Lbh7UkdWqlBHgxgHzG6UX+Kr/jA+W1wR5mHIPZVBpx1Lq\n"
"ctSVf3EQhAHajyI3V+6JFDcdjzRPX9z5C/MCuHHhBhtjKfIE89dhZSyDvIFP/YFy\n"
"h/EeK7GiDcOrx+7hRZ6yfeD71xpK4lJ6GYw516+FaL1Yjdf/kRToDDziz00ZNEjg\n"
"gs7ps2D/8SKmUcsWRldbxm3+yKJPwUAv4jNAY/Aod7cs1q7f2YuPQC0WjriBR1s8\n"
"GwIDAQAB\n"
"-----END PUBLIC KEY-----\n";
char* PRIVATE_KEY_PEM =
"-----BEGIN ENCRYPTED PRIVATE KEY-----\n"
"MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIa4XBjpJFZtQCAggA\n"
"MB0GCWCGSAFlAwQBKgQQ/dTrBC83CJnHfwgM6rotAwSCBNCvGXvzLgNkWT3Kvwui\n"
"Ln7gfiGtOfaubw5oq8DVh51hMhyYKnS8wAjMEkB0heFwTLLy1PCZnGv916NcUWhu\n"
"b4OxwCb/F3viBRSRgNaq5GB/c1HNeeg8CtEHs/EkxdIJuJuNr/giQp//TZ7Gm6Xf\n"
"Zb2rrdbW8ivxnactmJHdy5aRWA6Bhf5qr+0MjrTrUWKORUUIRLzJzGJ481Y0WIA6\n"
"9iK7I6aQnr5KzTETTUcMj+zU+WvlW3Ly3kn5ZGds/yB0wHnLTvCOBnIv9mq2nmZ3\n"
"Pyfm+WJirMwXkcZF+7U3Hsbk3Uk6VJqR/G0gKSiBebCgypYe6w5JTJQAoWdy96Zc\n"
"QHwr47dXIuhMzusdx9D67xz2HR0InGTnSTUOxCfYFDQaWdVUh2lHDswWqi6ZlFLJ\n"
"POkh24yaxE2S7Yn/CKAnET961GLAvVXChecjF2XkOoOGxE2rmOkrpc6fjndVTz5J\n"
"B4Vj0d3jotuHG+a6kbksV+71JbpJr5F69VRjsWpiEOwunHmtTdGhOmBkcyqJHXBh\n"
"8kusMSbZUzJTPFuTMJmxxzExasmif2CbJBl4WyfvKQjKlXyJSkysJN2V2NrA5Vpc\n"
"eb9msgXX8vBaN40ahT5mDeG5TXDPdssYOnQTM4vJo6IkSS2DIbMcUgbTcj9Qf3WZ\n"
"Y+FPROyIu8aKmCqDnDqJFp7aYaqjw5BWm6gL9YroPvNB8Funs8O1IgksMIUC+mt8\n"
"kFmq/Z9eUeoRawg4MGcMrgTdPDlrDB7uWfY2tPG/kkHQWEQyv13jJ1uEjUKf6wYk\n"
"WmIY5tvPEX3y4smscdWZGDQEjWL7zLs+7oLOwru2TbYmCx+V2QJpIW6Ppql/HCYr\n"
"+fJ+3qZ+I+eVcAW52jY8ygesab/+bQOrgpEfmBpTglTd+tt6h+16INagI4W+cY0z\n"
"iRcQjerjsgHM6JP4o4ZgxHBryHr5HdaZtpNXf3sHnaSwDCM/kVaeHAg+ciduRg+O\n"
"S6TIfdk334IFg7wXHRjjZXDX1QzRpUSBWvG4IdgE5Z9/3B0tvDbcU+R6c4GCTsiH\n"
"gZ/BWBQKaS3HhxhaUIlZhXXVgFvmGP5DsdaDQZG2VAsZqsTISrEG8OnHaklZIqi6\n"
"/GcMHJ2bHGmBKMgj0cTtkE53h1UZzlDkYqnf8b50uYunvDTNne/LPsPbfeuxTxDL\n"
"Oe5LtSD36vhSaExmaOkSN0qTY83zTDvxbSe7GBf87TNRimfnXZtxpghpgDffXgVi\n"
"j5JUcDjXpSC4xeu8jbq/lzh6x4o4nJRloPye8Zmq5VP7heZRN07GHDY6r1Jzz/4c\n"
"mBJWfMEg/OqB8CrOJibi6IPN3VkKzcF2WSWG712RizNHkWwaamlesC0dluXDmudj\n"
"bKr1niEF7KinUYiDu7ZJAntMRSm0hzjilAabSBXYP1RFOsZfgUfltON0oC2Zj5iX\n"
"wPaBUYhx2Fwn9jsge4NBWn3OXnqzZaq1Ojl0qb3YRbi2FVkisyZV/Dqzj1uGYkRq\n"
"6n6yoPqfAk/+u69Hzp1hHQi2wYbHbIDuQEI/kKRZ/XBxoL6c9LvYyKXKgBqd8RVU\n"
"T+AmBDkjEtksjQYaicwxe3MEcrM1PcEDyxJwRDsWp8Lo8wOU30A6ESlZb2TH/GgV\n"
"OxKP46YqccVN57+pU8RZ6bi0jg==\n"
"-----END ENCRYPTED PRIVATE KEY-----\n";
char* PRIVATE_KEY_PEM_TWO =
"-----BEGIN RSA PRIVATE KEY-----\n"
"MIIEowIBAAKCAQEAwu4ymKmuXoSvZn+TLOIhSXq7w+P1OeM9LCDt7ZpR/krdMyW6\n"
"UZBnZCNnB/1KWg+3dtO07ScSBgE0U/EMNvHBIm/tvzhomZgMGtL0Ln+Lbh7UkdWq\n"
"lBHgxgHzG6UX+Kr/jA+W1wR5mHIPZVBpx1LqctSVf3EQhAHajyI3V+6JFDcdjzRP\n"
"X9z5C/MCuHHhBhtjKfIE89dhZSyDvIFP/YFyh/EeK7GiDcOrx+7hRZ6yfeD71xpK\n"
"4lJ6GYw516+FaL1Yjdf/kRToDDziz00ZNEjggs7ps2D/8SKmUcsWRldbxm3+yKJP\n"
"wUAv4jNAY/Aod7cs1q7f2YuPQC0WjriBR1s8GwIDAQABAoIBACNlFRLbXKoU9bRq\n"
"3dJ8jQbGnmmHbvO/60+j+w/1wYWnGls7MoW07tEkDIVK3MFVsT6GWoflXERy24mS\n"
"b2FarHMQV98s4vFgxnHodCYtSqgIORjx7zNLu8C4geg3Jg8lHZnVCtKoIVwo+dqv\n"
"q0ViLOgE6dBmO1V88K6ky9/PlFxzBA7ER/XLqbkdmgDC+XLGQ63s31FXeKla9rQg\n"
"XodPx9AYUYuTLXOlNT1KXCa9a53qgB2woTGdtc1fPkBpnd+SHd2MItR+35X2ZXnY\n"
"b3kzOj+62O5MmC+sNysNy5D6Aut1fsEzauJr4jGP8TtpvC4Qc3/vLt2l7g/WHAzp\n"
"0TPiMGECgYEA9fHMBVIkTUzpKnzoF3jhqNFoqJqXgul32e7ej8Ov5b06wId1WLA/\n"
"/ZmgucPLAL1DDVyJMotNqeQPWt3x9++nTpnDHavGQ96y7SEI2zHuLMuhoR9c1zfA\n"
"MQicGfk25dhXWtMxFilFAkBbwCcLEq1XHcMI6ek4zKYlJ8tCHC4BmtcCgYEAyuZ0\n"
"91CBLcBuBrwpnxdXtOurwRDoOgXpJxy8bD9ctltcPFeilBUWuLYZ+gyBozli23Uh\n"
"KuDlKMZJw+CHztiEJwuzzzWOOxejs2qtBfSHM7Hne37Qpb/qcVfgn5C6fj7LeIgG\n"
"hUdK2QN2jEx+AWahFFFJ6Z2cmQBXXBGOW4LGZF0CgYA9+/ukV6hohvq4x5Qi3kdZ\n"
"KbXL0HJg/wBCv639457AMunMvhb4DCuEeaSFTPArtodgpbK6N1uSdrTb/NXP2+l5\n"
"qM0A/FrSnhzQIKQ/why503RfzCy03QsmEHpvHV0VnmmdrV5QrIQE5j15dx2WTnOH\n"
"P7FOaoXzJeh1WAfIXFvxLwKBgQC2XvIfIVMa5m1+zD2062xAB9w3CpVRIeLw7tlF\n"
"iqYwmmmLK1HMPDBSEgvDPt5+8aOzkdIgEkinn6LJ1tT6zI3r8o7J3l9bKeJP78BZ\n"
"K/MiOfPQgqnTcW6uNciGY7Xcp2CHk+wYe34BFSXG8TII3FBITNBclPgeZbof3P/R\n"
"rPfZWQKBgEbk1OsuDxUbcfgeMT0f1cBiJxtkRsj3Kffm6c2PAzGZg8A/EgoR25Cr\n"
"v+u4s5aS/3cBAfJhu9OAqoXdYJlXfYsoKuyOyvzeyOcsAsKjd6tIiU6xUe/u65oZ\n"
"1KXWzXoYgnNW3eoU7YeQ0Ca4SSg3qG2jqGFIAClla+hyLUeEgXB1\n"
"-----END RSA PRIVATE KEY-----\n";
static int pass_cb(char* buf, int size, int rwflag, void* u)
{
int len = strlen("hello");
// if too long, truncate
if (len > size)
len = size;
strncpy(buf, "hello", len);
return len;
}
int do_evp_seal(FILE *in_file, FILE *out_file)
{
int retval = 0;
RSA *rsa_pkey = NULL;
EVP_PKEY *pkey = EVP_PKEY_new();
EVP_CIPHER_CTX ctx;
unsigned char buffer[4096];
unsigned char buffer_out[4096 + EVP_MAX_IV_LENGTH];
size_t len;
int len_out;
unsigned char *ek;
int eklen;
uint32_t eklen_n;
unsigned char iv[EVP_MAX_IV_LENGTH];
OpenSSL_add_all_algorithms();
BIO* pBio = BIO_new_mem_buf(reinterpret_cast<void*>(PRIVATE_KEY_PEM), -1);
//BIO* pBio = BIO_new_mem_buf(reinterpret_cast<void*>(PUBLIC_KEY_PEM), -1);
//if (!PEM_read_bio_RSA_PUBKEY(pBio, &rsa_pkey, NULL, NULL))
if (!PEM_read_bio_RSAPrivateKey(pBio, &rsa_pkey, pass_cb, NULL))
//if (!PEM_read_bio_RSAPrivateKey(pBio, &rsa_pkey, NULL, NULL))
{
fprintf(stderr, "Error loading RSA Public Key File.\n");
ERR_print_errors_fp(stderr);
retval = 2;
goto out;
}
if (!EVP_PKEY_assign_RSA(pkey, rsa_pkey))
{
fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n");
retval = 3;
goto out;
}
EVP_CIPHER_CTX_init(&ctx);
ek = reinterpret_cast<unsigned char*>(malloc(EVP_PKEY_size(pkey)));
if (!EVP_SealInit(&ctx, EVP_aes_256_cbc(), &ek, &eklen, iv, &pkey, 1))
{
fprintf(stderr, "EVP_SealInit: failed.\n");
retval = 3;
goto out_free;
}
/* First we write out the encrypted key length, then the encrypted key,
* then the iv (the IV length is fixed by the cipher we have chosen).
*/
eklen_n = htonl(eklen);
if (fwrite(&eklen_n, sizeof eklen_n, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
if (fwrite(ek, eklen, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
if (fwrite(iv, EVP_CIPHER_iv_length(EVP_aes_256_cbc()), 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
/* Now we process the input file and write the encrypted data to the
* output file. */
while ((len = fread(buffer, 1, sizeof buffer, in_file)) > 0)
{
if (!EVP_SealUpdate(&ctx, buffer_out, &len_out, buffer, len))
{
fprintf(stderr, "EVP_SealUpdate: failed.\n");
retval = 3;
goto out_free;
}
if (fwrite(buffer_out, len_out, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
}
if (ferror(in_file))
{
perror("input file");
retval = 4;
goto out_free;
}
if (!EVP_SealFinal(&ctx, buffer_out, &len_out))
{
fprintf(stderr, "EVP_SealFinal: failed.\n");
retval = 3;
goto out_free;
}
if (fwrite(buffer_out, len_out, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
out_free:
EVP_PKEY_free(pkey);
free(ek);
out:
return retval;
}
int main()
{
return do_evp_seal(stdin, stdout);
}
Code:
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <arpa/inet.h>
char* PUBLIC_KEY_PEM =
"-----BEGIN PUBLIC KEY-----\n"
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvdbGZes3N/v3EqbbwYHW4rr4W\n"
"gav9eD36kVD7Hn5LIKwhfAqd1+LSN2YC49IsIhzwbXqoMUN89UZmFEdY4/M4qW1+\n"
"qwOfaX80EKCl8zV5Ztp8fvoErS1Z/G0k0c0kRdP0BCZTI9nSfjZkhbqWKnJrtCgi\n"
"s6OXXTeanU9B9Bz3HQIDAQAB\n"
"-----END PUBLIC KEY-----\n";
char* PRIVATE_KEY_PEM =
"-----BEGIN ENCRYPTED PRIVATE KEY-----\n"
"MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIa4XBjpJFZtQCAggA\n"
"MB0GCWCGSAFlAwQBKgQQ/dTrBC83CJnHfwgM6rotAwSCBNCvGXvzLgNkWT3Kvwui\n"
"Ln7gfiGtOfaubw5oq8DVh51hMhyYKnS8wAjMEkB0heFwTLLy1PCZnGv916NcUWhu\n"
"b4OxwCb/F3viBRSRgNaq5GB/c1HNeeg8CtEHs/EkxdIJuJuNr/giQp//TZ7Gm6Xf\n"
"Zb2rrdbW8ivxnactmJHdy5aRWA6Bhf5qr+0MjrTrUWKORUUIRLzJzGJ481Y0WIA6\n"
"9iK7I6aQnr5KzTETTUcMj+zU+WvlW3Ly3kn5ZGds/yB0wHnLTvCOBnIv9mq2nmZ3\n"
"Pyfm+WJirMwXkcZF+7U3Hsbk3Uk6VJqR/G0gKSiBebCgypYe6w5JTJQAoWdy96Zc\n"
"QHwr47dXIuhMzusdx9D67xz2HR0InGTnSTUOxCfYFDQaWdVUh2lHDswWqi6ZlFLJ\n"
"POkh24yaxE2S7Yn/CKAnET961GLAvVXChecjF2XkOoOGxE2rmOkrpc6fjndVTz5J\n"
"B4Vj0d3jotuHG+a6kbksV+71JbpJr5F69VRjsWpiEOwunHmtTdGhOmBkcyqJHXBh\n"
"8kusMSbZUzJTPFuTMJmxxzExasmif2CbJBl4WyfvKQjKlXyJSkysJN2V2NrA5Vpc\n"
"eb9msgXX8vBaN40ahT5mDeG5TXDPdssYOnQTM4vJo6IkSS2DIbMcUgbTcj9Qf3WZ\n"
"Y+FPROyIu8aKmCqDnDqJFp7aYaqjw5BWm6gL9YroPvNB8Funs8O1IgksMIUC+mt8\n"
"kFmq/Z9eUeoRawg4MGcMrgTdPDlrDB7uWfY2tPG/kkHQWEQyv13jJ1uEjUKf6wYk\n"
"WmIY5tvPEX3y4smscdWZGDQEjWL7zLs+7oLOwru2TbYmCx+V2QJpIW6Ppql/HCYr\n"
"+fJ+3qZ+I+eVcAW52jY8ygesab/+bQOrgpEfmBpTglTd+tt6h+16INagI4W+cY0z\n"
"iRcQjerjsgHM6JP4o4ZgxHBryHr5HdaZtpNXf3sHnaSwDCM/kVaeHAg+ciduRg+O\n"
"S6TIfdk334IFg7wXHRjjZXDX1QzRpUSBWvG4IdgE5Z9/3B0tvDbcU+R6c4GCTsiH\n"
"gZ/BWBQKaS3HhxhaUIlZhXXVgFvmGP5DsdaDQZG2VAsZqsTISrEG8OnHaklZIqi6\n"
"/GcMHJ2bHGmBKMgj0cTtkE53h1UZzlDkYqnf8b50uYunvDTNne/LPsPbfeuxTxDL\n"
"Oe5LtSD36vhSaExmaOkSN0qTY83zTDvxbSe7GBf87TNRimfnXZtxpghpgDffXgVi\n"
"j5JUcDjXpSC4xeu8jbq/lzh6x4o4nJRloPye8Zmq5VP7heZRN07GHDY6r1Jzz/4c\n"
"mBJWfMEg/OqB8CrOJibi6IPN3VkKzcF2WSWG712RizNHkWwaamlesC0dluXDmudj\n"
"bKr1niEF7KinUYiDu7ZJAntMRSm0hzjilAabSBXYP1RFOsZfgUfltON0oC2Zj5iX\n"
"wPaBUYhx2Fwn9jsge4NBWn3OXnqzZaq1Ojl0qb3YRbi2FVkisyZV/Dqzj1uGYkRq\n"
"6n6yoPqfAk/+u69Hzp1hHQi2wYbHbIDuQEI/kKRZ/XBxoL6c9LvYyKXKgBqd8RVU\n"
"T+AmBDkjEtksjQYaicwxe3MEcrM1PcEDyxJwRDsWp8Lo8wOU30A6ESlZb2TH/GgV\n"
"OxKP46YqccVN57+pU8RZ6bi0jg==\n"
"-----END ENCRYPTED PRIVATE KEY-----\n";
char* PRIVATE_KEY_PEM_TWO =
"-----BEGIN RSA PRIVATE KEY-----\n"
"MIIEowIBAAKCAQEAwu4ymKmuXoSvZn+TLOIhSXq7w+P1OeM9LCDt7ZpR/krdMyW6\n"
"UZBnZCNnB/1KWg+3dtO07ScSBgE0U/EMNvHBIm/tvzhomZgMGtL0Ln+Lbh7UkdWq\n"
"lBHgxgHzG6UX+Kr/jA+W1wR5mHIPZVBpx1LqctSVf3EQhAHajyI3V+6JFDcdjzRP\n"
"X9z5C/MCuHHhBhtjKfIE89dhZSyDvIFP/YFyh/EeK7GiDcOrx+7hRZ6yfeD71xpK\n"
"4lJ6GYw516+FaL1Yjdf/kRToDDziz00ZNEjggs7ps2D/8SKmUcsWRldbxm3+yKJP\n"
"wUAv4jNAY/Aod7cs1q7f2YuPQC0WjriBR1s8GwIDAQABAoIBACNlFRLbXKoU9bRq\n"
"3dJ8jQbGnmmHbvO/60+j+w/1wYWnGls7MoW07tEkDIVK3MFVsT6GWoflXERy24mS\n"
"b2FarHMQV98s4vFgxnHodCYtSqgIORjx7zNLu8C4geg3Jg8lHZnVCtKoIVwo+dqv\n"
"q0ViLOgE6dBmO1V88K6ky9/PlFxzBA7ER/XLqbkdmgDC+XLGQ63s31FXeKla9rQg\n"
"XodPx9AYUYuTLXOlNT1KXCa9a53qgB2woTGdtc1fPkBpnd+SHd2MItR+35X2ZXnY\n"
"b3kzOj+62O5MmC+sNysNy5D6Aut1fsEzauJr4jGP8TtpvC4Qc3/vLt2l7g/WHAzp\n"
"0TPiMGECgYEA9fHMBVIkTUzpKnzoF3jhqNFoqJqXgul32e7ej8Ov5b06wId1WLA/\n"
"/ZmgucPLAL1DDVyJMotNqeQPWt3x9++nTpnDHavGQ96y7SEI2zHuLMuhoR9c1zfA\n"
"MQicGfk25dhXWtMxFilFAkBbwCcLEq1XHcMI6ek4zKYlJ8tCHC4BmtcCgYEAyuZ0\n"
"91CBLcBuBrwpnxdXtOurwRDoOgXpJxy8bD9ctltcPFeilBUWuLYZ+gyBozli23Uh\n"
"KuDlKMZJw+CHztiEJwuzzzWOOxejs2qtBfSHM7Hne37Qpb/qcVfgn5C6fj7LeIgG\n"
"hUdK2QN2jEx+AWahFFFJ6Z2cmQBXXBGOW4LGZF0CgYA9+/ukV6hohvq4x5Qi3kdZ\n"
"KbXL0HJg/wBCv639457AMunMvhb4DCuEeaSFTPArtodgpbK6N1uSdrTb/NXP2+l5\n"
"qM0A/FrSnhzQIKQ/why503RfzCy03QsmEHpvHV0VnmmdrV5QrIQE5j15dx2WTnOH\n"
"P7FOaoXzJeh1WAfIXFvxLwKBgQC2XvIfIVMa5m1+zD2062xAB9w3CpVRIeLw7tlF\n"
"iqYwmmmLK1HMPDBSEgvDPt5+8aOzkdIgEkinn6LJ1tT6zI3r8o7J3l9bKeJP78BZ\n"
"K/MiOfPQgqnTcW6uNciGY7Xcp2CHk+wYe34BFSXG8TII3FBITNBclPgeZbof3P/R\n"
"rPfZWQKBgEbk1OsuDxUbcfgeMT0f1cBiJxtkRsj3Kffm6c2PAzGZg8A/EgoR25Cr\n"
"v+u4s5aS/3cBAfJhu9OAqoXdYJlXfYsoKuyOyvzeyOcsAsKjd6tIiU6xUe/u65oZ\n"
"1KXWzXoYgnNW3eoU7YeQ0Ca4SSg3qG2jqGFIAClla+hyLUeEgXB1\n"
"-----END RSA PRIVATE KEY-----\n";
int do_evp_seal(FILE *in_file, FILE *out_file)
{
int retval = 0;
RSA *rsa_pkey = NULL;
EVP_PKEY *pkey = EVP_PKEY_new();
EVP_CIPHER_CTX ctx;
unsigned char buffer[4096];
unsigned char buffer_out[4096 + EVP_MAX_IV_LENGTH];
size_t len;
int len_out;
unsigned char *ek;
int eklen;
uint32_t eklen_n;
unsigned char iv[EVP_MAX_IV_LENGTH];
OpenSSL_add_all_algorithms();
BIO* pBio = BIO_new_mem_buf(reinterpret_cast<void*>(PRIVATE_KEY_PEM), -1);
if (!PEM_read_bio_RSAPrivateKey(pBio, &rsa_pkey, NULL, NULL))
{
fprintf(stderr, "Error loading RSA Public Key File.\n");
ERR_print_errors_fp(stderr);
retval = 2;
goto out;
}
if (!EVP_PKEY_assign_RSA(pkey, rsa_pkey))
{
fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n");
retval = 3;
goto out;
}
/* First we write out the encrypted key length, then the encrypted key,
* then the iv (the IV length is fixed by the cipher we have chosen).
*/
if (fread(&eklen_n, sizeof eklen_n, 1, in_file) != 1)
{
perror("input file");
retval = 5;
goto out_free;
}
eklen = ntohl(eklen_n);
//eklen = 128;
//ek = reinterpret_cast<unsigned char*>(malloc(EVP_PKEY_size(pkey)));
//ek = reinterpret_cast<unsigned char*>(malloc(eklen));
ek = new unsigned char[eklen];
if (fread(ek, eklen, 1, in_file) != 1)
{
perror("input file");
retval = 5;
goto out_free;
}
if (fread(iv, EVP_CIPHER_iv_length(EVP_aes_256_cbc()), 1, in_file) != 1)
{
perror("input file");
retval = 5;
goto out_free;
}
EVP_CIPHER_CTX_init(&ctx);
if (!EVP_OpenInit(&ctx, EVP_aes_256_cbc(), ek, eklen, iv, pkey))
{
fprintf(stderr, "EVP_OpenInit: failed.\n");
retval = 3;
goto out_free;
}
printf("%d\n", eklen);
/* Now we process the input file and write the encrypted data to the
* output file. */
while ((len = fread(buffer, 1, sizeof buffer, in_file)) > 0)
{
if (!EVP_OpenUpdate(&ctx, buffer_out, &len_out, buffer, len))
{
fprintf(stderr, "EVP_OpenUpdate: failed.\n");
retval = 3;
goto out_free;
}
if (fwrite(buffer_out, len_out, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
}
if (ferror(in_file))
{
perror("input file");
retval = 4;
goto out_free;
}
if (!EVP_OpenFinal(&ctx, buffer_out, &len_out))
{
fprintf(stderr, "EVP_OpenFinal: failed.\n");
retval = 3;
goto out_free;
}
if (fwrite(buffer_out, len_out, 1, out_file) != 1)
{
perror("output file");
retval = 5;
goto out_free;
}
out_free:
EVP_PKEY_free(pkey);
free(ek);
out:
return retval;
}
int main(int argc, char *argv[])
{
return do_evp_seal(stdin, stdout);
}
Not sure if that code is useful now, but dumping it anyway...
g++ a.cpp -lssl -o enctest
./enctest
g++ b.cpp -lssl -o seal
./seal < INPUT > ENCOUT
g++ c.cpp -lssl -o unseal
./unseal < ENCOUT