1 #include "keymanager.h" 5 #include <boost/scoped_array.hpp> 12 static constexpr
bool built_with_p11 =
true;
14 static constexpr
bool built_with_p11 =
false;
17 KeyManager::KeyManager(std::shared_ptr<INvStorage> backend,
KeyManagerConfig config)
18 : backend_(
std::move(backend)), config_(
std::move(config)) {
20 p11_ = std_::make_unique<P11EngineGuard>(config_.p11);
24 void KeyManager::loadKeys(
const std::string *pkey_content,
const std::string *cert_content,
25 const std::string *ca_content) {
26 if (config_.tls_pkey_source == CryptoSource::kFile) {
28 if (pkey_content !=
nullptr) {
31 backend_->loadTlsPkey(&pkey);
34 if (tmp_pkey_file ==
nullptr) {
35 tmp_pkey_file = std_::make_unique<TemporaryFile>(
"tls-pkey");
37 tmp_pkey_file->PutContents(pkey);
40 if (config_.tls_cert_source == CryptoSource::kFile) {
42 if (cert_content !=
nullptr) {
45 backend_->loadTlsCert(&cert);
48 if (tmp_cert_file ==
nullptr) {
49 tmp_cert_file = std_::make_unique<TemporaryFile>(
"tls-cert");
51 tmp_cert_file->PutContents(cert);
54 if (config_.tls_ca_source == CryptoSource::kFile) {
56 if (ca_content !=
nullptr) {
59 backend_->loadTlsCa(&ca);
62 if (tmp_ca_file ==
nullptr) {
63 tmp_ca_file = std_::make_unique<TemporaryFile>(
"tls-ca");
65 tmp_ca_file->PutContents(ca);
70 std::string KeyManager::getPkeyFile()
const {
71 std::string pkey_file;
72 if (config_.tls_pkey_source == CryptoSource::kPkcs11) {
73 if (!built_with_p11) {
74 throw std::runtime_error(
"Aktualizr was built without PKCS#11");
76 pkey_file = (*p11_)->getTlsPkeyId();
78 if (config_.tls_pkey_source == CryptoSource::kFile) {
79 if (tmp_pkey_file && !boost::filesystem::is_empty(tmp_pkey_file->PathString())) {
80 pkey_file = tmp_pkey_file->PathString();
86 std::string KeyManager::getCertFile()
const {
87 std::string cert_file;
88 if (config_.tls_cert_source == CryptoSource::kPkcs11) {
89 if (!built_with_p11) {
90 throw std::runtime_error(
"Aktualizr was built without PKCS#11");
92 cert_file = (*p11_)->getTlsCertId();
94 if (config_.tls_cert_source == CryptoSource::kFile) {
95 if (tmp_cert_file && !boost::filesystem::is_empty(tmp_cert_file->PathString())) {
96 cert_file = tmp_cert_file->PathString();
102 std::string KeyManager::getCaFile()
const {
104 if (config_.tls_ca_source == CryptoSource::kPkcs11) {
105 if (!built_with_p11) {
106 throw std::runtime_error(
"Aktualizr was built without PKCS#11");
108 ca_file = (*p11_)->getTlsCacertId();
110 if (config_.tls_ca_source == CryptoSource::kFile) {
111 if (tmp_ca_file && !boost::filesystem::is_empty(tmp_ca_file->PathString())) {
112 ca_file = tmp_ca_file->PathString();
118 std::string KeyManager::getPkey()
const {
120 if (config_.tls_pkey_source == CryptoSource::kPkcs11) {
121 if (!built_with_p11) {
122 throw std::runtime_error(
"Aktualizr was built without PKCS#11");
124 pkey = (*p11_)->getTlsPkeyId();
126 if (config_.tls_pkey_source == CryptoSource::kFile) {
127 backend_->loadTlsPkey(&pkey);
132 std::string KeyManager::getCert()
const {
134 if (config_.tls_cert_source == CryptoSource::kPkcs11) {
135 if (!built_with_p11) {
136 throw std::runtime_error(
"Aktualizr was built without PKCS#11");
138 cert = (*p11_)->getTlsCertId();
140 if (config_.tls_cert_source == CryptoSource::kFile) {
141 backend_->loadTlsCert(&cert);
146 std::string KeyManager::getCa()
const {
148 if (config_.tls_ca_source == CryptoSource::kPkcs11) {
149 if (!built_with_p11) {
150 throw std::runtime_error(
"Aktualizr was built without PKCS#11");
152 ca = (*p11_)->getTlsCacertId();
154 if (config_.tls_ca_source == CryptoSource::kFile) {
155 backend_->loadTlsCa(&ca);
160 std::string KeyManager::getCN()
const {
161 std::string not_found_cert_message =
"Certificate is not found, can't extract device_id";
163 if (config_.tls_cert_source == CryptoSource::kFile) {
164 if (!backend_->loadTlsCert(&cert)) {
165 throw std::runtime_error(not_found_cert_message);
168 if (!built_with_p11) {
169 throw std::runtime_error(
"Aktualizr was built without PKCS#11 support, can't extract device_id");
171 if (!(*p11_)->readTlsCert(&cert)) {
172 throw std::runtime_error(not_found_cert_message);
176 StructGuard<BIO> bio(BIO_new_mem_buf(const_cast<char *>(cert.c_str()), static_cast<int>(cert.size())), BIO_vfree);
177 StructGuard<X509> x(PEM_read_bio_X509(bio.get(),
nullptr,
nullptr,
nullptr), X509_free);
179 throw std::runtime_error(
"Could not parse certificate");
182 int len = X509_NAME_get_text_by_NID(X509_get_subject_name(x.get()), NID_commonName,
nullptr, 0);
184 throw std::runtime_error(
"Could not get CN from certificate");
186 boost::scoped_array<char> buf(
new char[len + 1]);
187 X509_NAME_get_text_by_NID(X509_get_subject_name(x.get()), NID_commonName, buf.get(), len + 1);
188 std::string cn(buf.get());
192 void KeyManager::copyCertsToCurl(
const std::shared_ptr<HttpInterface> &http) {
193 std::string pkey = getPkey();
194 std::string cert = getCert();
195 std::string ca = getCa();
197 if ((pkey.size() != 0u) && (cert.size() != 0u) && (ca.size() != 0u)) {
198 http->setCerts(ca, config_.tls_ca_source, cert, config_.tls_cert_source, pkey, config_.tls_pkey_source);
202 Json::Value KeyManager::signTuf(
const Json::Value &in_data)
const {
203 ENGINE *crypto_engine =
nullptr;
204 std::string private_key;
205 if (config_.uptane_key_source == CryptoSource::kPkcs11) {
206 if (!built_with_p11) {
207 throw std::runtime_error(
"Aktualizr was built without PKCS#11");
209 crypto_engine = (*p11_)->getEngine();
210 private_key = config_.p11.uptane_key_id;
212 if (config_.uptane_key_source == CryptoSource::kFile) {
213 backend_->loadPrimaryPrivate(&private_key);
215 std::string b64sig = Utils::toBase64(
216 Crypto::Sign(config_.uptane_key_type, crypto_engine, private_key, Json::FastWriter().write(in_data)));
217 Json::Value signature;
218 signature[
"method"] =
"rsassa-pss";
219 signature[
"sig"] = b64sig;
221 Json::Value out_data;
222 signature[
"keyid"] = UptanePublicKey().KeyId();
223 out_data[
"signed"] = in_data;
224 out_data[
"signatures"] = Json::Value(Json::arrayValue);
225 out_data[
"signatures"].append(signature);
229 std::string KeyManager::generateUptaneKeyPair() {
230 std::string primary_public;
232 if (config_.uptane_key_source == CryptoSource::kFile) {
233 std::string primary_private;
234 if (!backend_->loadPrimaryKeys(&primary_public, &primary_private)) {
235 if (Crypto::generateKeyPair(config_.uptane_key_type, &primary_public, &primary_private)) {
236 backend_->storePrimaryKeys(primary_public, primary_private);
239 if (primary_public.empty() && primary_private.empty()) {
240 throw std::runtime_error(
"Could not get uptane keys");
243 if (!built_with_p11) {
244 throw std::runtime_error(
"Aktualizr was built without pkcs11 support!");
247 if (!(*p11_)->readUptanePublicKey(&primary_public)) {
248 (*p11_)->generateUptaneKeyPair();
251 if (primary_public.empty() && !(*p11_)->readUptanePublicKey(&primary_public)) {
252 throw std::runtime_error(
"Could not get uptane keys");
255 return primary_public;
258 PublicKey KeyManager::UptanePublicKey()
const {
259 std::string primary_public;
260 if (config_.uptane_key_source == CryptoSource::kFile) {
261 if (!backend_->loadPrimaryPublic(&primary_public)) {
262 throw std::runtime_error(
"Could not get uptane public key!");
265 if (!built_with_p11) {
266 throw std::runtime_error(
"Aktualizr was built without pkcs11 support!");
269 if (!(*p11_)->readUptanePublicKey(&primary_public)) {
270 throw std::runtime_error(
"Could not get uptane public key!");
273 return PublicKey(primary_public, config_.uptane_key_type);