* Custom certificate should be renamed as subject-name-hash.
Change-Id: I5dd52d7cd19cacd624e2d66b0e59183835011085
Signed-off-by: sangwan.kwon <sangwan.kwon@samsung.com>
#include <unistd.h>
#include <cerrno>
+#include <set>
+
#include <klay/filesystem.h>
#include <klay/audit/logger.h>
+#include "Certificate.h"
#include "Exception.h"
namespace transec {
private:
void linkTo(const std::string &src, const std::string &dst);
void makeCustomBundle(void);
- std::string getSubHashName(const std::string &filePath);
+ std::string getHashName(const std::string &filePath);
std::string m_packageId;
std::string m_appCertsPath;
std::string m_basePath;
std::string m_sysCertsPath;
std::string m_customCertsPath;
+
+ std::set<std::string> m_customCertNameSet;
};
AppCustomTrustAnchor::Impl::Impl(const std::string &packageId,
{
errno = 0;
int ret = ::symlink(src.c_str(), dst.c_str());
- DEBUG("Make symlink from " << src << " to " << dst);
if (ret != 0)
throw std::logic_error("Fail to link " + src + " -> " + dst +
"[" + std::to_string(errno) + "]");
// make the package's custom directory
runtime::File customDir(this->m_customCertsPath);
- DEBUG(this->m_customCertsPath);
if (customDir.exists()) {
WARN("App custom certs directory is already exist. remove it!");
customDir.remove(true);
while (iter != end) {
linkTo(iter->getPath(),
this->m_customCertsPath + "/" + iter->getName());
+ this->m_customCertNameSet.emplace(iter->getName());
++iter;
}
}
runtime::DirectoryIterator iter(this->m_appCertsPath), end;
while (iter != end) {
- std::string hashName = this->getSubHashName(iter->getPath());
+ std::string hashName = this->getHashName(iter->getPath());
linkTo(iter->getPath(),
this->m_customCertsPath + "/" + hashName);
+ this->m_customCertNameSet.emplace(std::move(hashName));
++iter;
}
this->makeCustomBundle();
- INFO("Success to install : " << this->m_packageId);
+ INFO("Success to install[" << this->m_packageId <<
+ "] to " << this->m_customCertsPath);
return 0;
EXCEPTION_GUARD_END
return -1;
}
-/*
- This function returns 'dummy file name' temporary.
- It should be replaced with Openssl Class.
-*/
-std::string AppCustomTrustAnchor::Impl::getSubHashName(const std::string &filePath)
+std::string AppCustomTrustAnchor::Impl::getHashName(const std::string &filePath)
{
- runtime::File rawCert(filePath);
-
+ auto hashName = Certificate::getSubjectNameHash(filePath);
int sameFileNameCnt = 0;
- // TODO (openssl) rename certificates to subject_hash
- runtime::DirectoryIterator iter(this->m_customCertsPath), end;
- while(iter != end) {
- if (iter->getName() == rawCert.getName())
- sameFileNameCnt++;
-
- ++iter;
- }
+ std::string uniqueName;
+ do {
+ uniqueName = hashName + "." + std::to_string(sameFileNameCnt++);
+ } while (this->m_customCertNameSet.find(uniqueName) != this->m_customCertNameSet.end());
- size_t dotPos = rawCert.getName().rfind(".");
- std::string fileName = rawCert.getName();
- fileName.replace(dotPos + 1, std::string::npos, std::to_string(sameFileNameCnt));
- return fileName;
+ return uniqueName;
}
void AppCustomTrustAnchor::Impl::makeCustomBundle(void)
PKG_CHECK_MODULES(${TARGET_TRANSEC_LIB}_DEP
REQUIRED
klay
+ openssl
)
SET(${TARGET_TRANSEC_LIB}_SRCS
InitLib.cpp
Exception.cpp
+ Certificate.cpp
AppCustomTrustAnchor.cpp
)
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file Certificate.cpp
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+#include "Certificate.h"
+
+#include <cstdio>
+#include <vector>
+#include <memory>
+#include <stdexcept>
+
+#include <openssl/pem.h>
+
+namespace transec {
+
+namespace {
+
+using FilePtr = std::unique_ptr<FILE, decltype(&::fclose)>;
+using X509Ptr = std::unique_ptr<X509, decltype(&::X509_free)>;
+
+const int HASH_LENGTH = 8;
+
+} // namespace anonymous
+
+std::string Certificate::getSubjectNameHash(const std::string &path)
+{
+ FilePtr fp(fopen(path.c_str(), "r"), ::fclose);
+ if (fp == nullptr)
+ throw std::invalid_argument("Faild to open certificate.");
+
+ X509Ptr x509(::PEM_read_X509(fp.get(), NULL, NULL, NULL), ::X509_free);
+ if (x509 == nullptr) {
+ ::rewind(fp.get());
+ x509 = X509Ptr(::PEM_read_X509_AUX(fp.get(), NULL, NULL, NULL),
+ ::X509_free);
+ }
+
+ if (x509 == nullptr)
+ throw std::logic_error("Failed to read certificate.");
+
+ std::vector<char> buf(HASH_LENGTH + 1);
+ snprintf(buf.data(), buf.size(),
+ "%08lx", ::X509_subject_name_hash(x509.get()));
+
+ return std::string(buf.data(), HASH_LENGTH);
+}
+
+} // namespace transec
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file Certificate.h
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+#pragma once
+
+#include <string>
+
+namespace transec {
+
+class Certificate {
+public:
+ static std::string getSubjectNameHash(const std::string &path);
+};
+
+} // namespace transec
SET(TEST_SRCS
main.cpp
test-app-custom-trust-anchor.cpp
+ test-certificate.cpp
)
SET(TEST_TRANSEC_PATH "${CERT_SVC_TESTS}/transec")
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file test-certificate.cpp
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @version 0.1
+ * @brief Unit test program of Certificate
+ */
+
+#include <dpl/test/test_runner.h>
+
+#include <iostream>
+
+#include <Certificate.h>
+
+#include "test-resource.h"
+
+RUNNER_TEST_GROUP_INIT(T0600_CERTIFICATE)
+
+using namespace transec;
+
+RUNNER_TEST(T0601_GET_SUBJECT_NAME_HASH)
+{
+ try {
+ auto hash = Certificate::getSubjectNameHash(TEST_PEM_PATH);
+ RUNNER_ASSERT_MSG(hash.compare(TEST_PEM_HASH) == 0,
+ "Failed to get proper hash.");
+ } catch (const std::exception &e) {
+ std::cout << "std::exception occured." << e.what() << std::endl;
+ } catch (...) {
+ std::cout << "Unknown exception occured." << std::endl;
+ }
+}
#define DUMMY_CERTS_DIR "/home/dummy"
#define APP_CERTS_DIR TEST_TRANSEC_PATH "/certs"
+
+#define TEST_PEM_PATH APP_CERTS_DIR "/02265526.0"
+#define TEST_PEM_HASH "02265526"