-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathopenssl_pem.cc
101 lines (78 loc) · 2.08 KB
/
openssl_pem.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "openssl_utils.hpp"
#include <openssl/pem.h>
#include <gtest/gtest.h>
// PEM encode
auto pem_encode(const std::string &type, const std::string &data) -> std::string
{
std::string pem;
BIO *bio = BIO_new(BIO_s_mem());
if (bio == nullptr) {
openssl_error();
return pem;
}
char *name = const_cast<char *>(type.c_str());
if (!PEM_write_bio(bio,
name,
nullptr,
reinterpret_cast<const unsigned char *>(data.c_str()),
static_cast<int>(data.size()))) {
openssl_error();
BIO_free(bio);
return pem;
}
int len = BIO_pending(bio);
pem.resize(len);
if (BIO_read(bio, &pem[0], len) != len) {
openssl_error();
BIO_free(bio);
return pem;
}
BIO_free(bio);
return pem;
}
// PEM decode
auto pem_decode(const std::string &type, const std::string &pem) -> std::string
{
std::string data;
BIO *bio = BIO_new(BIO_s_mem());
if (bio == nullptr) {
openssl_error();
return data;
}
if (BIO_write(bio, pem.c_str(), static_cast<int>(pem.size())) != static_cast<int>(pem.size())) {
openssl_error();
BIO_free(bio);
return data;
}
char *name = const_cast<char *>(type.c_str());
char *header = nullptr;
unsigned char *data_ = nullptr;
long len = 0;
if (!PEM_read_bio(bio, &name, &header, &data_, &len)) {
openssl_error();
BIO_free(bio);
return data;
}
data.resize(len);
memcpy(&data[0], data_, len);
OPENSSL_free(header);
OPENSSL_free(data_);
BIO_free(bio);
return data;
}
TEST(openssl_pem, pem)
{
auto plain = "hello world";
auto type = "RSA PRIVATE KEY";
auto pem = pem_encode(type, plain);
std::cout << "pem: " << pem << std::endl;
auto pem_data = pem_decode(type, pem);
std::cout << "pem data: " << pem_data << std::endl;
EXPECT_EQ(plain, pem_data);
}
auto main() -> int
{
openssl_version();
testing::InitGoogleTest();
return RUN_ALL_TESTS();
}