--- /dev/null
+/*
+ * Copyright (c) 2020 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
+ */
+
+#include <unordered_map>
+#include <fstream>
+#include <iterator>
+
+#include <boost_macros_wrapper.h>
+#include <test_common.h>
+
+#include <ckm/ckm-raw-buffer.h>
+#include <pkcs12-impl.h>
+#include <data-type.h>
+#include <protocols.h>
+#include <message-buffer.h>
+
+using namespace CKM;
+
+namespace {
+
+const RawBuffer& loadPkcs12(const std::string& path)
+{
+ static std::unordered_map<std::string, RawBuffer> pkcs12_map;
+
+ auto it = pkcs12_map.find(path);
+ if (it != pkcs12_map.end())
+ return it->second;
+
+ std::ifstream ifs(std::string(PKCS12_TEST_DIR) + path, std::ios::binary);
+ BOOST_REQUIRE(ifs);
+
+ ifs.unsetf(std::ios::skipws);
+ ifs.seekg(0, std::ios::end);
+ RawBuffer data;
+ data.reserve(ifs.tellg());
+ ifs.seekg(0, std::ios::beg);
+
+ data.insert(data.begin(),
+ std::istream_iterator<decltype(data)::value_type>(ifs),
+ std::istream_iterator<decltype(data)::value_type>());
+
+ return pkcs12_map.emplace(path, std::move(data)).first->second;
+}
+
+constexpr char PASSWORD[] = "secret";
+
+}
+
+BOOST_AUTO_TEST_SUITE(PKCS12_TEST)
+
+POSITIVE_TEST_CASE(create)
+{
+ const struct {
+ std::string path;
+ KeyType keyType;
+ } pkcsInfo[] = {
+ { "rsa.p12", KeyType::KEY_RSA_PRIVATE },
+ { "dsa.p12", KeyType::KEY_DSA_PRIVATE },
+ { "ecdsa.p12", KeyType::KEY_ECDSA_PRIVATE }
+ };
+
+ for (auto& info : pkcsInfo) {
+ PKCS12ShPtr pkcs;
+ BOOST_REQUIRE_NO_THROW(pkcs = PKCS12::create(loadPkcs12(info.path), PASSWORD));
+ BOOST_REQUIRE(pkcs);
+ BOOST_REQUIRE(!pkcs->empty());
+
+ KeyShPtr key;
+ BOOST_REQUIRE_NO_THROW(key = pkcs->getKey());
+ BOOST_REQUIRE(key && !key->empty());
+ BOOST_REQUIRE(key->getType() == info.keyType);
+
+ CertificateShPtr cert;
+ BOOST_REQUIRE_NO_THROW(cert = pkcs->getCertificate());
+ BOOST_REQUIRE(cert && !cert->empty());
+
+ CertificateShPtrVector cas;
+ BOOST_REQUIRE_NO_THROW(cas = pkcs->getCaCertificateShPtrVector());
+ BOOST_REQUIRE(!cas.empty());
+
+ PKCS12Impl pkcsImpl;
+ BOOST_REQUIRE_NO_THROW(pkcsImpl = PKCS12Impl(key, cert, cas));
+
+ BOOST_REQUIRE(!pkcsImpl.empty());
+ }
+}
+
+NEGATIVE_TEST_CASE(create)
+{
+ PKCS12ShPtr pkcs;
+
+ RawBuffer brokenPkcs = loadPkcs12("rsa.p12");
+ brokenPkcs.pop_back();
+ BOOST_REQUIRE_NO_THROW(pkcs = PKCS12::create(brokenPkcs, PASSWORD));
+ BOOST_REQUIRE(!pkcs);
+
+ BOOST_REQUIRE_NO_THROW(pkcs = PKCS12::create(loadPkcs12("rsa.p12"), "wrong pw"));
+ BOOST_REQUIRE(!pkcs);
+
+ BOOST_REQUIRE_NO_THROW(pkcs = PKCS12::create(loadPkcs12("rsa.p12"), ""));
+ BOOST_REQUIRE(!pkcs);
+
+ BOOST_REQUIRE_NO_THROW(pkcs = PKCS12::create(RawBuffer(), ""));
+ BOOST_REQUIRE(!pkcs);
+
+ BOOST_REQUIRE_NO_THROW(pkcs = PKCS12::create(RawBuffer(10), ""));
+ BOOST_REQUIRE(!pkcs);
+}
+
+NEGATIVE_TEST_CASE(empty)
+{
+ PKCS12Impl empty;
+ BOOST_REQUIRE(empty.empty());
+ BOOST_REQUIRE(!empty.getKey());
+ BOOST_REQUIRE(!empty.getCertificate());
+ BOOST_REQUIRE(empty.getCaCertificateShPtrVector().empty());
+}
+
+POSITIVE_TEST_CASE(pkcs12Serializable)
+{
+ RawBuffer der;
+
+ auto checkPkcs = [&](const PKCS12Serializable& ps) {
+ MessageBuffer msg;
+ msg.Push(MessageBuffer::Serialize(ps).Pop());
+ PKCS12Serializable deserialized(msg);
+ BOOST_REQUIRE(!deserialized.empty());
+
+ KeyShPtr deserializedKey;
+ BOOST_REQUIRE_NO_THROW(deserializedKey = deserialized.getKey());
+ BOOST_REQUIRE(deserializedKey && !deserializedKey->empty());
+ BOOST_REQUIRE(deserializedKey->getType() == KeyType::KEY_RSA_PRIVATE);
+ BOOST_REQUIRE(deserializedKey->getDER() == der);
+ };
+
+ PKCS12ShPtr pkcs;
+ BOOST_REQUIRE_NO_THROW(pkcs = PKCS12::create(loadPkcs12("rsa.p12"), PASSWORD));
+ BOOST_REQUIRE(pkcs);
+
+ KeyShPtr key;
+ BOOST_REQUIRE_NO_THROW(key = pkcs->getKey());
+ BOOST_REQUIRE(key && !key->empty());
+ BOOST_REQUIRE(key->getType() == KeyType::KEY_RSA_PRIVATE);
+ der = key->getDER();
+
+ PKCS12Serializable ps;
+ BOOST_REQUIRE_NO_THROW(ps = PKCS12Serializable(*pkcs));
+ checkPkcs(ps);
+
+ PKCS12Serializable ps2;
+ BOOST_REQUIRE_NO_THROW(ps2 = PKCS12Serializable(key,
+ pkcs->getCertificate(),
+ pkcs->getCaCertificateShPtrVector()));
+ checkPkcs(ps2);
+}
+
+NEGATIVE_TEST_CASE(pkcs12Serializable)
+{
+ auto checkEmptiness = [](const PKCS12Serializable& ps) {
+ MessageBuffer msg;
+ msg.Push(MessageBuffer::Serialize(ps).Pop());
+ PKCS12Serializable deserialized(msg);
+ BOOST_REQUIRE(deserialized.empty());
+ };
+
+ PKCS12Impl pkcs;
+
+ pkcs = PKCS12Impl(RawBuffer(), "");
+ PKCS12Serializable ps(pkcs);
+ checkEmptiness(ps);
+
+ pkcs = PKCS12Impl(RawBuffer(20), "");
+ PKCS12Serializable ps2(pkcs);
+ checkEmptiness(ps2);
+
+ pkcs = PKCS12Impl(loadPkcs12("rsa.p12"), "wrong pw");
+ PKCS12Serializable ps3(pkcs);
+ checkEmptiness(ps3);
+
+ PKCS12Serializable ps4;
+ checkEmptiness(ps4);
+}
+
+BOOST_AUTO_TEST_SUITE_END()