/*! \brief indicating that request give to database returned no result */
#define CKM_API_ERROR_DB_ALIAS_UNKNOWN -15
+/*! \brief indicating that CA certificate(s) were unknown and chain could not be created */
+#define CKM_API_ERROR_VERIFICATION_FAILED -16
+
/*! \brief indicating the error with unknown reason */
#define CKM_API_ERROR_UNKNOWN -255
/** @}*/
// used to pass password and raw key data
typedef std::vector<unsigned char> RawBuffer;
+typedef std::vector<RawBuffer> RawBufferVector;
typedef std::string Alias;
typedef std::vector<Alias> AliasVector;
//
// // this fuction will return chains of certificates and check it with openssl
// // status : OK, INCOMPLETE_CHAIN, VERIFICATION_FAILED
-// int getCertiticateChain(
-// const Certificate &certificate,
-// const CertificateVector &untrustedCertificates,
-// CertificateVector &certificateChainVector);
-//
-// int getCertificateChain(
-// const Certificate &certificate,
-// const AliasVector &untrustedCertificates,
-// CertificateVector &certificateChainVector);
-//
+ int getCertificateChain(
+ const Certificate &certificate,
+ const CertificateVector &untrustedCertificates,
+ CertificateVector &certificateChainVector);
+
+ int getCertificateChain(
+ const Certificate &certificate,
+ const AliasVector &untrustedCertificates,
+ CertificateVector &certificateChainVector);
+
// int strictCACheck(const CertificateVector &certificateVector);
//
// // This function will check all certificates in chain except Root CA.
${COMMON_PATH}/common/message-buffer.cpp
${COMMON_PATH}/common/smack-check.cpp
${COMMON_PATH}/common/certificate-impl.cpp
+ ${COMMON_PATH}/common/certificate-store.cpp
${COMMON_PATH}/common/generic-key.cpp
${COMMON_PATH}/dpl/log/src/abstract_log_provider.cpp
${COMMON_PATH}/dpl/log/src/dlog_log_provider.cpp
}
void* Certificate::getX509() {
- // TODO
+ if (m_impl)
+ return m_impl->getX509();
return NULL;
}
const Alias &privateKeyAlias,
const Alias &publicKeyAlias,
const Policy &policyPrivateKey,
- const Policy &policyPublicKey)
+ const Policy &policyPublicKey)
{
m_counter++;
int my_counter = m_counter;
Serialization::Serialize(send, PolicySerializable(policyPublicKey));
Serialization::Serialize(send, privateKeyAlias);
Serialization::Serialize(send, publicKeyAlias);
-
-
int retCode = sendToServer(
SERVICE_SOCKET_CKM_STORAGE,
int command;
int counter;
-
Deserialization::Deserialize(recv, command);
Deserialization::Deserialize(recv, counter);
Deserialization::Deserialize(recv, retCode);
-
+
if (counter != my_counter) {
return CKM_API_ERROR_UNKNOWN;
}
const Alias &privateKeyAlias,
const Alias &publicKeyAlias,
const Policy &policyPrivateKey,
- const Policy &policyPublicKey)
+ const Policy &policyPublicKey)
{
m_counter++;
int my_counter = m_counter;
Serialization::Serialize(send, PolicySerializable(policyPublicKey));
Serialization::Serialize(send, privateKeyAlias);
Serialization::Serialize(send, publicKeyAlias);
-
int retCode = sendToServer(
SERVICE_SOCKET_CKM_STORAGE,
Deserialization::Deserialize(recv, command);
Deserialization::Deserialize(recv, counter);
Deserialization::Deserialize(recv, retCode);
-
+
if (counter != my_counter) {
return CKM_API_ERROR_UNKNOWN;
}
return retCode;
});
}
+
+template <class T>
+int getCertChain(
+ LogicCommand command,
+ int counter,
+ const Certificate &certificate,
+ const T &sendData,
+ CertificateVector &certificateChainVector)
+{
+ return try_catch([&] {
+
+ MessageBuffer send, recv;
+ Serialization::Serialize(send, static_cast<int>(command));
+ Serialization::Serialize(send, counter);
+ Serialization::Serialize(send, certificate.getDER());
+ Serialization::Serialize(send, sendData);
+
+ int retCode = sendToServer(
+ SERVICE_SOCKET_CKM_STORAGE,
+ send.Pop(),
+ recv);
+
+ if (CKM_API_SUCCESS != retCode) {
+ return retCode;
+ }
+
+ int retCommand;
+ int retCounter;
+ RawBufferVector rawBufferVector;
+
+ Deserialization::Deserialize(recv, retCommand);
+ Deserialization::Deserialize(recv, retCounter);
+ Deserialization::Deserialize(recv, retCode);
+ Deserialization::Deserialize(recv, rawBufferVector);
+
+ if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) {
+ return CKM_API_ERROR_UNKNOWN;
+ }
+
+ if (retCode != CKM_API_SUCCESS) {
+ return retCode;
+ }
+
+ for (auto &e: rawBufferVector)
+ certificateChainVector.push_back(Certificate(e, DataFormat::FORM_DER));
+
+ return retCode;
+ });
+}
+
+int Manager::ManagerImpl::getCertificateChain(
+ const Certificate &certificate,
+ const CertificateVector &untrustedCertificates,
+ CertificateVector &certificateChainVector)
+{
+ RawBufferVector rawBufferVector;
+
+ for (auto &e: untrustedCertificates) {
+ rawBufferVector.push_back(e.getDER());
+ }
+
+ return getCertChain(
+ LogicCommand::GET_CHAIN_CERT,
+ ++m_counter,
+ certificate,
+ rawBufferVector,
+ certificateChainVector);
+}
+
+int Manager::ManagerImpl::getCertificateChain(
+ const Certificate &certificate,
+ const AliasVector &untrustedCertificates,
+ CertificateVector &certificateChainVector)
+{
+ (void) certificate;
+ (void) untrustedCertificates;
+ (void) certificateChainVector;
+ return CKM_API_ERROR_UNKNOWN;
+}
+
} // namespace CKM
const Policy &policyPrivateKey = Policy(),
const Policy &policyPublicKey = Policy());
+ int getCertificateChain(
+ const Certificate &certificate,
+ const CertificateVector &untrustedCertificates,
+ CertificateVector &certificateChainVector);
+
+ int getCertificateChain(
+ const Certificate &certificate,
+ const AliasVector &untrustedCertificates,
+ CertificateVector &certificateChainVector);
+
protected:
int saveBinaryData(
const Alias &alias,
int removeBinaryData(
const Alias &alias,
DBDataType dataType);
-
+
int getBinaryData(
const Alias &alias,
DBDataType sendDataType,
{
return m_impl->createKeyPairECDSA(type, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
}
+
+int Manager::getCertificateChain(
+ const Certificate &certificate,
+ const CertificateVector &untrustedCertificates,
+ CertificateVector &certificateChainVector)
+{
+ return m_impl->getCertificateChain(certificate, untrustedCertificates, certificateChainVector);
+}
+
+int Manager::getCertificateChain(
+ const Certificate &certificate,
+ const AliasVector &untrustedCertificates,
+ CertificateVector &certificateChainVector)
+{
+ return m_impl->getCertificateChain(certificate, untrustedCertificates, certificateChainVector);
+}
+
} // namespace CKM
LogError("Unknown certificate format");
}
-// if (!m_x509) {
-// // TODO
-// LogError("Internal Openssl error in d2i_X509 function.");
+ if (!m_x509) {
+ // TODO
+ LogError("Error in parsing certificate.");
// ThrowMsg(Exception::OpensslInternalError,
// "Internal Openssl error in d2i_X509 function.");
-// }
+ }
}
+CertificateImpl::CertificateImpl(X509 *x509)
+ : m_x509(X509_dup(x509))
+{}
+
CertificateImpl::CertificateImpl(const CertificateImpl &second){
- m_x509 = X509_dup(second.m_x509);
+ m_x509 = X509_dup(second.m_x509);
+}
+
+CertificateImpl::CertificateImpl(CertificateImpl &&second) {
+ m_x509 = second.m_x509;
+ second.m_x509 = NULL;
}
+CertificateImpl& CertificateImpl::operator=(CertificateImpl &&second) {
+ if (this == &second)
+ return *this;
+ X509_free(m_x509);
+ m_x509 = second.m_x509;
+ second.m_x509 = NULL;
+ return *this;
+}
CertificateImpl& CertificateImpl::operator=(const CertificateImpl &second) {
- m_x509 = X509_dup(second.m_x509);
- return *this;
+ if (this == &second)
+ return *this;
+ X509_free(m_x509);
+ m_x509 = X509_dup(second.m_x509);
+ return *this;
+}
+
+X509* CertificateImpl::getX509() const {
+ return m_x509;
}
RawBuffer CertificateImpl::getDER(void) const {
}
CertificateImpl::~CertificateImpl() {
+ LogDebug("free cert start ptr: " << (void*)m_x509);
X509_free(m_x509);
+ LogDebug("free cert end");
}
} // namespace CKM
class CertificateImpl {
public:
CertificateImpl(){}
+ CertificateImpl(X509* x509);
CertificateImpl(const RawBuffer &data, DataFormat format);
CertificateImpl(const CertificateImpl &);
+ CertificateImpl(CertificateImpl &&);
CertificateImpl& operator=(const CertificateImpl &);
+ CertificateImpl& operator=(CertificateImpl &&);
RawBuffer getDER() const;
bool empty() const;
- ~CertificateImpl();
+ X509* getX509() const;
+ virtual ~CertificateImpl();
protected:
X509* m_x509;
};
--- /dev/null
+/* Copyright (c) 2000 - 2013 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-stack.cpp
+ * @author Barlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief Certificate Stack Implmentation.
+ */
+#include <openssl/x509.h>
+
+#include <dpl/log/log.h>
+
+#include <certificate-store.h>
+#include <ckm/ckm-error.h>
+#include <ckm/ckm-type.h>
+
+namespace CKM {
+
+CertificateStore::CertificateStore()
+ : m_store(X509_STORE_new())
+{}
+
+int CertificateStore::loadFile(const std::string &path) {
+ if (!m_store) {
+ LogError("CertificateStore is not initialized!");
+ return CKM_API_ERROR_UNKNOWN;
+ }
+
+ auto lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_file());
+
+ if (!lookup) {
+ LogError("Error in X509_STORE_add_lookup");
+ return CKM_API_ERROR_UNKNOWN;
+ }
+
+ if (!X509_LOOKUP_load_file(lookup, path.c_str(), X509_FILETYPE_PEM)) {
+ LogError("Error in X509_LOOKUP_load_file");
+ return CKM_API_ERROR_UNKNOWN;
+ }
+ return CKM_API_SUCCESS;
+}
+
+int CertificateStore::setSystemCertificateDir(const char *path) {
+ if (!m_store) {
+ LogError("CertificateStore is not initialized!");
+ return CKM_API_ERROR_UNKNOWN;
+ }
+
+ auto lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_hash_dir());
+
+ if (!lookup) {
+ LogError("Error in X509_STORE_add_lookup");
+ return CKM_API_ERROR_UNKNOWN;
+ }
+
+ if (!X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM)) {
+ LogError("Error in X509_LOOKUP_add_dir");
+ return CKM_API_ERROR_UNKNOWN;
+ }
+ return CKM_API_SUCCESS;
+}
+
+int CertificateStore::verifyCertificate(
+ const CertificateImpl &cert,
+ const CertificateImplVector &untrustedVector,
+ CertificateImplVector &chainVector)
+{
+ STACK_OF(X509) *untrusted = NULL;
+
+ if (!untrustedVector.empty()) {
+ untrusted = sk_X509_new_null();
+ for (auto &e : untrustedVector)
+ sk_X509_push(untrusted, e.getX509());
+ }
+
+ X509_STORE_CTX *csc = X509_STORE_CTX_new();
+ if (!csc) {
+ LogError("failed to create csc");
+ return CKM_API_ERROR_UNKNOWN;
+ }
+
+ if (0 == X509_STORE_CTX_init(csc, m_store, cert.getX509(), untrusted)) {
+ LogError("failed to X509_STORE_CTX_init");
+ return CKM_API_ERROR_UNKNOWN;
+ }
+
+ int result = X509_verify_cert(csc); // 1 == ok; 0 == fail; -1 == error
+
+ LogDebug("Verification result: " << result);
+
+ if (result > 0) {
+ STACK_OF(X509) *chain = X509_STORE_CTX_get_chain(csc);
+ for (int i = 0; i < sk_X509_num(chain); ++i) {
+ X509* cert = (X509*)sk_X509_value(chain, i);
+ chainVector.push_back(CertificateImpl(cert));
+ }
+ }
+
+ X509_STORE_CTX_free(csc);
+ if (untrusted) {
+ // we don't want to free certificates because we did not create copies
+ // sk_X509_pop_free(untrusted, X509_free);
+ sk_X509_free(untrusted);
+ }
+
+ if (result == 1)
+ return CKM_API_SUCCESS;
+ if (result == 0)
+ return CKM_API_ERROR_VERIFICATION_FAILED;
+ return CKM_API_ERROR_UNKNOWN;
+}
+
+CertificateStore::~CertificateStore() {
+ if (m_store)
+ X509_STORE_free(m_store);
+}
+
+} // namespace CKM
--- /dev/null
+/* Copyright (c) 2000 - 2013 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-stack.h
+ * @author Barlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief Certificate Stack Implmentation.
+ */
+#include <certificate-impl.h>
+
+extern "C" {
+struct x509_store_st;
+typedef struct x509_store_st X509_STORE;
+}
+
+namespace CKM {
+
+class CertificateStore {
+public:
+ CertificateStore();
+ CertificateStore(const CertificateStore &) = delete;
+ CertificateStore(CertificateStore &&) = delete;
+ CertificateStore& operator=(CertificateStore &&) = delete;
+ CertificateStore& operator=(const CertificateStore &) = delete;
+ virtual ~CertificateStore();
+
+ int loadFile(const std::string &path);
+
+ int setSystemCertificateDir(const char *path);
+
+ int verifyCertificate(
+ const CertificateImpl &cert,
+ const CertificateImplVector &untrustedVector,
+ CertificateImplVector &chainVector);
+
+protected:
+ X509_STORE *m_store;
+};
+
+} // namespace CKM
+
SAVE,
REMOVE,
CREATE_KEY_PAIR_RSA,
- CREATE_KEY_PAIR_ECDSA
+ CREATE_KEY_PAIR_ECDSA,
+ GET_CHAIN_CERT,
+ GET_CHAIN_ALIAS
};
// Do not use DB_KEY_FIRST and DB_KEY_LAST in the code.
#include <ckm-logic.h>
#include <generic-key.h>
+namespace {
+const char * const CERT_SYSTEM_DIR = "/etc/ssl/certs";
+} // anonymous namespace
+
namespace CKM {
-CKMLogic::CKMLogic(){
+CKMLogic::CKMLogic()
+{
int retCode = FileSystem::init();
// TODO what can I do when init went wrong? exit(-1) ??
if (retCode) {
LogError("Fatal error in FileSystem::init()");
}
+
+ if (CKM_API_SUCCESS != m_certStore.setSystemCertificateDir(CERT_SYSTEM_DIR)) {
+ LogError("Fatal error in CertificateStore::setSystemCertificateDir. Chain creation will not work");
+ }
}
CKMLogic::~CKMLogic(){}
return response.Pop();
}
+RawBuffer CKMLogic::getCertificateChain(
+ Credentials &cred,
+ int commandId,
+ const RawBuffer &certificate,
+ const RawBufferVector &untrustedRawCertVector)
+{
+ (void)cred;
+
+ CertificateImpl cert(certificate, DataFormat::FORM_DER);
+ CertificateImplVector untrustedCertVector;
+ CertificateImplVector chainVector;
+ RawBufferVector chainRawVector;
+
+ for (auto &e: untrustedRawCertVector)
+ untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
+
+ int retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
+
+ if (retCode == CKM_API_SUCCESS) {
+ for (auto &e : chainVector)
+ chainRawVector.push_back(e.getDER());
+ }
+
+ MessageBuffer response;
+ Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_CHAIN_CERT));
+ Serialization::Serialize(response, commandId);
+ Serialization::Serialize(response, retCode);
+ Serialization::Serialize(response, chainRawVector);
+ return response.Pop();
+}
+
+RawBuffer CKMLogic::getCertificateChain(
+ Credentials &cred,
+ int commandId,
+ const RawBuffer &certificate,
+ const AliasVector &aliasVector)
+{
+ (void) cred;
+ (void) commandId;
+ (void) certificate;
+ (void) aliasVector;
+
+ MessageBuffer response;
+ Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_CHAIN_ALIAS));
+ Serialization::Serialize(response, commandId);
+ Serialization::Serialize(response, static_cast<int>(CKM_API_SUCCESS));
+ Serialization::Serialize(response, RawBufferVector());
+ return response.Pop();
+}
+
} // namespace CKM
#include <db-crypto.h>
#include <key-provider.h>
#include <DBCryptoModule.h>
+#include <certificate-store.h>
namespace CKM {
const PolicySerializable &policyPrivate,
const PolicySerializable &policyPublic);
+ RawBuffer getCertificateChain(
+ Credentials &cred,
+ int commandId,
+ const RawBuffer &certificate,
+ const RawBufferVector &untrustedCertificates);
+
+ RawBuffer getCertificateChain(
+ Credentials &cred,
+ int commandId,
+ const RawBuffer &certificate,
+ const AliasVector &aliasVector);
+
private:
+
int saveDataHelper(
Credentials &cred,
DBDataType dataType,
const PolicySerializable &policyPublic);
std::map<uid_t, UserData> m_userDataMap;
+ CertificateStore m_certStore;
};
} // namespace CKM
int tmpDataType;
Alias alias;
std::string user;
- LogicCommand sc;
Deserialization::Deserialize(buffer, command);
Deserialization::Deserialize(buffer, commandId);
- sc = static_cast<LogicCommand>(command);
-
- switch(sc) {
+ switch(static_cast<LogicCommand>(command)) {
case LogicCommand::SAVE:
{
RawBuffer rawData;
policyPrivateKey,
policyPublicKey);
}
+ case LogicCommand::GET_CHAIN_CERT:
+ {
+ RawBuffer certificate;
+ RawBufferVector rawBufferVector;
+ Deserialization::Deserialize(buffer, certificate);
+ Deserialization::Deserialize(buffer, rawBufferVector);
+ return m_logic->getCertificateChain(
+ cred,
+ commandId,
+ certificate,
+ rawBufferVector);
+ }
+ case LogicCommand::GET_CHAIN_ALIAS:
+ {
+ RawBuffer certificate;
+ AliasVector aliasVector;
+ Deserialization::Deserialize(buffer, certificate);
+ Deserialization::Deserialize(buffer, aliasVector);
+ return m_logic->getCertificateChain(
+ cred,
+ commandId,
+ certificate,
+ aliasVector);
+ }
default:
// TODO
throw 1; // broken protocol