Implementation of PKCS12 class.
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Wed, 20 Aug 2014 15:00:02 +0000 (17:00 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 12 Sep 2014 12:59:28 +0000 (14:59 +0200)
Change-Id: Ie377ced1fafb8f406211c264697f0c8219f04f03

packaging/key-manager.spec
src/CMakeLists.txt
src/include/ckm/ckm-manager.h
src/include/ckm/ckm-pkcs12.h [new file with mode: 0644]
src/manager/common/certificate-impl.cpp
src/manager/common/certificate-impl.h
src/manager/common/pkcs12-impl.cpp [new file with mode: 0644]
src/manager/common/pkcs12-impl.h [new file with mode: 0644]

index f9834f1..c22e44b 100755 (executable)
@@ -197,6 +197,7 @@ fi
 %{_includedir}/ckm/ckm/ckm-error.h
 %{_includedir}/ckm/ckm/ckm-key.h
 %{_includedir}/ckm/ckm/ckm-password.h
+%{_includedir}/ckm/ckm/ckm-pkcs12.h
 %{_includedir}/ckm/ckm/ckm-raw-buffer.h
 %{_includedir}/ckm/ckm/ckm-type.h
 %{_includedir}/ckm/ckmc/ckmc-manager.h
index e3dabac..38b6907 100644 (file)
@@ -89,6 +89,7 @@ SET(KEY_MANAGER_CLIENT_SOURCES
     ${KEY_MANAGER_PATH}/common/certificate-impl.cpp
     ${KEY_MANAGER_PATH}/common/certificate-store.cpp
     ${KEY_MANAGER_PATH}/common/generic-key.cpp
+    ${KEY_MANAGER_PATH}/common/pkcs12-impl.cpp
     ${KEY_MANAGER_PATH}/dpl/log/src/abstract_log_provider.cpp
     ${KEY_MANAGER_PATH}/dpl/log/src/dlog_log_provider.cpp
     ${KEY_MANAGER_PATH}/dpl/log/src/log.cpp
@@ -190,6 +191,7 @@ INSTALL(FILES
     ${KEY_MANAGER_SRC_PATH}/include/ckm/ckm-error.h
     ${KEY_MANAGER_SRC_PATH}/include/ckm/ckm-key.h
     ${KEY_MANAGER_SRC_PATH}/include/ckm/ckm-password.h
+    ${KEY_MANAGER_SRC_PATH}/include/ckm/ckm-pkcs12.h
     ${KEY_MANAGER_SRC_PATH}/include/ckm/ckm-raw-buffer.h
     ${KEY_MANAGER_SRC_PATH}/include/ckm/ckm-type.h
     DESTINATION /usr/include/ckm/ckm
index c78d3ea..8e62afe 100644 (file)
 // Central Key Manager namespace
 namespace CKM {
 
-/*
-class Pkcs12 {
-public:
-       Pkcs12();
-       Pkcs12(const RawBuffer &rawData, const RawBuffer &password = RawBuffer());
-
-       Pkcs12(const Pkcs12 &pkcs);
-       Pkcs12(Pkcs12 &&pkcs);
-       Pkcs12& operator=(const Pkcs12 &pkcs);
-       Pkcs12& operator=(Pkcs12 &&pkcs);
-
-       Key getKey(const RawBuffer &password = RawBuffer());
-       Certificate getCertificate(); // this is connected with Key
-
-       // check the API in openssl and translate it 1 to 1.
-
-       CertificateShPtrVector getCertificateShPtrVector();
-
-       bool empty();
-       virtual ~Pkcs12();
-private:
-       class Pkcs12Impl;
-       Pkcs12Impl *m_impl;
-};
-*/
-
 class Manager;
 typedef std::shared_ptr<Manager> ManagerShPtr;
 
diff --git a/src/include/ckm/ckm-pkcs12.h b/src/include/ckm/ckm-pkcs12.h
new file mode 100644 (file)
index 0000000..cdb4613
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co.
+ *
+ *  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        ckm-pkcs12.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Main header file for client library.
+ */
+#pragma once
+
+#include <vector>
+#include <memory>
+
+#include <ckm/ckm-certificate.h>
+#include <ckm/ckm-error.h>
+#include <ckm/ckm-key.h>
+#include <ckm/ckm-type.h>
+
+// Central Key Manager namespace
+namespace CKM {
+
+class PKCS12;
+typedef std::shared_ptr<PKCS12> PKCS12ShPtr;
+
+class PKCS12 {
+public:
+    virtual KeyShPtr getKey() const = 0;
+
+    virtual CertificateShPtr getCertificate() const = 0;
+
+    virtual CertificateShPtrVector getCaCertificateShPtrVector() const = 0;
+
+    virtual bool empty() const = 0;
+
+    virtual ~PKCS12(){}
+
+    static PKCS12ShPtr create(const RawBuffer &rawData, const Password &password = Password());
+};
+
+} // namespace CKM
+
index 71caf7e..f8adbf3 100644 (file)
@@ -70,9 +70,13 @@ CertificateImpl::CertificateImpl(const RawBuffer &der, DataFormat format)
     }
 }
 
-CertificateImpl::CertificateImpl(X509 *x509)
-  : m_x509(X509_dup(x509))
-{}
+CertificateImpl::CertificateImpl(X509 *x509, bool duplicate)
+{
+    if (duplicate)
+        m_x509 = X509_dup(x509);
+    else
+        m_x509 = x509;
+}
 
 CertificateImpl::CertificateImpl(const CertificateImpl &second){
     m_x509 = X509_dup(second.m_x509);
index 4dc6fc1..62ebfbb 100644 (file)
@@ -33,7 +33,7 @@ namespace CKM {
 class CertificateImpl : public Certificate {
 public:
     CertificateImpl(){}
-    CertificateImpl(X509* x509);
+    explicit CertificateImpl(X509* x509, bool duplicate = true);
     CertificateImpl(const RawBuffer &data, DataFormat format);
     CertificateImpl(const CertificateImpl &);
     CertificateImpl(CertificateImpl &&);
diff --git a/src/manager/common/pkcs12-impl.cpp b/src/manager/common/pkcs12-impl.cpp
new file mode 100644 (file)
index 0000000..255a752
--- /dev/null
@@ -0,0 +1,133 @@
+/* Copyright (c) 2014 Samsung Electronics Co.
+ *
+ *  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        pkcs12-impl.cpp
+ * @author      Barlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Certificate Implmentation.
+ */
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+#include <openssl/x509.h>
+
+#include <dpl/log/log.h>
+
+#include <pkcs12-impl.h>
+
+#include <certificate-impl.h>
+#include <generic-key.h>
+
+namespace CKM {
+namespace {
+
+typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr;
+
+} // anonymous namespace
+
+PKCS12Impl::PKCS12Impl(const RawBuffer &buffer, const Password &password)
+{
+    EVP_PKEY *pkey = NULL;
+    X509 *cert = NULL;
+    STACK_OF(X509) *ca = NULL;
+    ::PKCS12 *pkcs12 = NULL;
+
+    BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
+    LogDebug("Start to parse PKCS12");
+
+    int result = BIO_write(bio.get(), buffer.data(), buffer.size());
+    if (result != static_cast<int>(buffer.size())) {
+        LogError("BIO_write failed. result = " << result << " Expected: " << buffer.size());
+        return;
+    }
+
+    pkcs12 = d2i_PKCS12_bio(bio.get(), NULL);
+
+    if (pkcs12 == NULL) {
+        LogDebug("d2i_PKCS12_bio failed.");
+        return;
+    }
+
+    if (!PKCS12_verify_mac(pkcs12, password.c_str(), password.size())) {
+        LogDebug("Pkcs12 verify failed. Wrong password");
+        return;
+    }
+
+    if (!PKCS12_parse(pkcs12, password.c_str(), &pkey, &cert, &ca)) {
+        LogError("PKCS12_parse failed");
+        return;
+    }
+
+    if (pkey) {
+        GenericKey::EvpShPtr ptr(pkey, EVP_PKEY_free);
+        if (EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA) {
+            m_pkey = std::make_shared<GenericKey>(ptr, KeyType::KEY_RSA_PRIVATE);
+        } else if (EVP_PKEY_type(pkey->type) == EVP_PKEY_EC) {
+            m_pkey = std::make_shared<GenericKey>(ptr, KeyType::KEY_ECDSA_PRIVATE);
+        } else {
+            LogError("Unsupported private key type.");
+            EVP_PKEY_free(pkey);
+        }
+    }
+
+    if (cert) {
+        m_cert = std::make_shared<CertificateImpl>(cert, false);
+    }
+
+    if (ca) {
+        while (sk_X509_num(ca) > 0) {
+            X509 *top = sk_X509_pop(ca);
+            m_ca.push_back(std::make_shared<CertificateImpl>(top, false));
+        }
+
+        sk_X509_pop_free(ca, X509_free);
+    }
+}
+
+KeyShPtr PKCS12Impl::getKey() const {
+    return m_pkey;
+}
+
+CertificateShPtr PKCS12Impl::getCertificate() const {
+    return m_cert;
+}
+
+CertificateShPtrVector PKCS12Impl::getCaCertificateShPtrVector() const {
+    return m_ca;
+}
+
+bool PKCS12Impl::empty() const {
+    return m_pkey.get() == NULL && m_cert.get() == NULL && m_ca.empty();
+}
+
+PKCS12Impl::~PKCS12Impl()
+{}
+
+PKCS12ShPtr PKCS12::create(const RawBuffer &rawBuffer, const Password &password) {
+    try {
+        auto output = std::make_shared<PKCS12Impl>(rawBuffer, password);
+        if (output->empty())
+            output.reset();
+        return output;
+    } catch (const std::bad_alloc &e) {
+        LogDebug("Bad alloc was caught during PKCS12 creation");
+    } catch (...) {
+        LogError("Critical error: Unknown exception was caught during PCKS12Impl creation!");
+    }
+    return PKCS12ShPtr();
+}
+
+} // namespace CKM
+
diff --git a/src/manager/common/pkcs12-impl.h b/src/manager/common/pkcs12-impl.h
new file mode 100644 (file)
index 0000000..3ec8fc3
--- /dev/null
@@ -0,0 +1,52 @@
+/* Copyright (c) 2014 Samsung Electronics Co.
+ *
+ *  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        pkcs12-impl.h
+ * @author      Barlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Certificate Implmentation.
+ */
+#pragma once
+
+#include <memory>
+#include <vector>
+
+#include <ckm/ckm-pkcs12.h>
+
+namespace CKM {
+
+class PKCS12Impl : public PKCS12 {
+public:
+    PKCS12Impl(const RawBuffer &buffer, const Password &password);
+
+    PKCS12Impl(const PKCS12Impl &) = delete;
+    PKCS12Impl(PKCS12Impl &&) = delete;
+    PKCS12Impl& operator=(const PKCS12Impl &) = delete;
+    PKCS12Impl& operator=(PKCS12Impl &&) = delete;
+
+    virtual KeyShPtr getKey() const;
+    virtual CertificateShPtr getCertificate() const;
+    virtual CertificateShPtrVector getCaCertificateShPtrVector() const;
+    virtual bool empty() const;
+
+    virtual ~PKCS12Impl();
+protected:
+    KeyShPtr m_pkey;
+    CertificateShPtr m_cert;
+    CertificateShPtrVector m_ca;
+};
+
+} // namespace CKM
+