Add OCSP check CAPI
authorkyungwook tak <k.tak@samsung.com>
Thu, 20 Nov 2014 01:40:39 +0000 (10:40 +0900)
committerMaciej J. Karpiuk <m.karpiuk2@samsung.com>
Tue, 17 Feb 2015 11:02:44 +0000 (12:02 +0100)
Change-Id: I41876e3c8a3ea33c1a9eb200bc9467571b83940b

src/include/ckmc/ckmc-manager.h
src/include/ckmc/ckmc-type.h
src/manager/client-capi/ckmc-manager.cpp
src/manager/client-capi/ckmc-type-converter.cpp
src/manager/client-capi/ckmc-type-converter.h
src/manager/service/ocsp.cpp

index 7e4d788..3c9d3ae 100644 (file)
@@ -779,6 +779,31 @@ int ckmc_get_cert_chain(const ckmc_cert_s *cert, const ckmc_cert_list_s *untrust
  */
 int ckmc_get_cert_chain_with_alias(const ckmc_cert_s *cert, const ckmc_alias_list_s *untrustedcerts, ckmc_cert_list_s **ppcert_chain_list);
 
+
+/**
+ * @brief Perform OCSP which checks certificate is whether revoked or not
+ *
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/keymanager
+ *
+ * @param[in] pcert_chain_list   Certificate chain to perform OCSP check
+ * @param[out] ocsp_status       The pointer to status result of OCSP check
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ *
+ * @retval #CKMC_ERROR_NONE                 Successful
+ * @retval #CKMC_ERROR_INVALID_PARAMETER    Input parameter is invalid
+ * @retval #CKMC_ERROR_PERMISSION_DENIED    Failed to access key manager
+ *
+ * @pre User is already logged in and the user key is already loaded into memory in plain text form.
+ *
+ * @see ckmc_get_cert_chain())
+ * @see ckmc_cert_list_all_free()
+ */
+int ckmc_ocsp_check(const ckmc_cert_list_s *pcert_chain_list, ckmc_ocsp_status_e *ocsp_status);
+
+
 /**
  * @deprecated, see ckmc_set_permission()
  * @brief Allows another application to access client's application data
index b392137..5cc7b7e 100644 (file)
@@ -179,6 +179,22 @@ typedef struct __ckmc_cert_list {
 } ckmc_cert_list_s;
 
 /**
+ * @brief Enumeration for OCSP status.
+ * @since_tizen 3.0
+ */
+typedef enum __ckmc_ocsp_status {
+    CKMC_OCSP_STATUS_GOOD = 0,          /**< OCSP status is good */
+    CKMC_OCSP_STATUS_REVOKED,           /**< certificate is revoked */
+    CKMC_OCSP_STATUS_UNKNOWN,           /**< unknown error */
+    CKMC_OCSP_ERROR_UNSUPPORTED,        /**< certificate does not provide OCSP extension */
+    CKMC_OCSP_ERROR_INVALID_URL,        /**< invalid URL in certificate OCSP extension */
+    CKMC_OCSP_ERROR_INVALID_RESPONSE,   /**< invalid response from OCSP server */
+    CKMC_OCSP_ERROR_REMOTE,             /**< OCSP remote server error */
+    CKMC_OCSP_ERROR_NET,                /**< network connection error */
+    CKMC_OCSP_ERROR_INTERNAL            /**< OpenSSL API error */
+} ckmc_ocsp_status_e;
+
+/**
  * @brief The structure for PKCS12 used in key manager CAPI.
  * @since_tizen 2.3
  */
index b9e6159..3cfa1bd 100644 (file)
@@ -701,6 +701,38 @@ int ckmc_get_cert_chain_with_alias(const ckmc_cert_s *cert, const ckmc_alias_lis
 }
 
 KEY_MANAGER_CAPI
+int ckmc_ocsp_check(const ckmc_cert_list_s *pcert_chain_list, ckmc_ocsp_status_e *ocsp_status)
+{
+    if (pcert_chain_list == NULL
+        || pcert_chain_list->cert == NULL
+        || pcert_chain_list->cert->raw_cert == NULL
+        || pcert_chain_list->cert->cert_size <= 0
+        || ocsp_status == NULL) {
+        return CKMC_ERROR_INVALID_PARAMETER;
+    }
+
+    int ret = CKMC_ERROR_UNKNOWN;
+    int tmpOcspStatus = -1;
+    CKM::ManagerShPtr mgr = CKM::Manager::create();
+    CKM::CertificateShPtrVector ckmCertChain;
+    const ckmc_cert_list_s *current = NULL;
+    const ckmc_cert_list_s *next = pcert_chain_list;
+
+    do {
+        current = next;
+        next = current->next;
+        if (current->cert == NULL)
+            continue;
+
+        ckmCertChain.push_back(_toCkmCertificate(current->cert));
+    } while (next != NULL);
+
+    ret = mgr->ocspCheck(ckmCertChain, tmpOcspStatus);
+    *ocsp_status = to_ckmc_ocsp_status(tmpOcspStatus);
+    return to_ckmc_error(ret);
+}
+
+KEY_MANAGER_CAPI
 int ckmc_allow_access(const char *alias, const char *accessor, ckmc_access_right_e granted)
 {
     return ckmc_set_permission(alias, accessor, static_cast<int>(granted));
index 25ca29b..e9531ed 100644 (file)
 #include <ckmc-type-converter.h>
 
 int to_ckm_error(int ckmc_error) {
-       switch(ckmc_error) {
-       case CKMC_ERROR_NONE:                  return CKM_API_SUCCESS;
-       case CKMC_ERROR_SOCKET:                return CKM_API_ERROR_SOCKET;
-       case CKMC_ERROR_BAD_REQUEST:           return CKM_API_ERROR_BAD_REQUEST;
-       case CKMC_ERROR_BAD_RESPONSE:          return CKM_API_ERROR_BAD_RESPONSE;
-       case CKMC_ERROR_SEND_FAILED:           return CKM_API_ERROR_SEND_FAILED;
-       case CKMC_ERROR_RECV_FAILED:           return CKM_API_ERROR_RECV_FAILED;
-       case CKMC_ERROR_AUTHENTICATION_FAILED: return CKM_API_ERROR_AUTHENTICATION_FAILED;
-       case CKMC_ERROR_INVALID_PARAMETER:     return CKM_API_ERROR_INPUT_PARAM;
-       case CKMC_ERROR_BUFFER_TOO_SMALL:      return CKM_API_ERROR_BUFFER_TOO_SMALL;
-       case CKMC_ERROR_OUT_OF_MEMORY:         return CKM_API_ERROR_OUT_OF_MEMORY;
-       case CKMC_ERROR_PERMISSION_DENIED:     return CKM_API_ERROR_ACCESS_DENIED;
-       case CKMC_ERROR_SERVER_ERROR:          return CKM_API_ERROR_SERVER_ERROR;
-       case CKMC_ERROR_DB_LOCKED:             return CKM_API_ERROR_DB_LOCKED;
-       case CKMC_ERROR_DB_ERROR:              return CKM_API_ERROR_DB_ERROR;
-       case CKMC_ERROR_DB_ALIAS_EXISTS:       return CKM_API_ERROR_DB_ALIAS_EXISTS;
-       case CKMC_ERROR_DB_ALIAS_UNKNOWN:      return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
-       case CKMC_ERROR_VERIFICATION_FAILED:   return CKM_API_ERROR_VERIFICATION_FAILED;
-       case CKMC_ERROR_INVALID_FORMAT:        return CKM_API_ERROR_INVALID_FORMAT;
-       case CKMC_ERROR_FILE_ACCESS_DENIED:    return CKM_API_ERROR_FILE_ACCESS_DENIED;
-       case CKMC_ERROR_NOT_EXPORTABLE:        return CKM_API_ERROR_NOT_EXPORTABLE;
-       case CKMC_ERROR_UNKNOWN:               return CKM_API_ERROR_UNKNOWN;
-       }
-       return CKMC_ERROR_UNKNOWN;
+    switch(ckmc_error) {
+    case CKMC_ERROR_NONE:                  return CKM_API_SUCCESS;
+    case CKMC_ERROR_SOCKET:                return CKM_API_ERROR_SOCKET;
+    case CKMC_ERROR_BAD_REQUEST:           return CKM_API_ERROR_BAD_REQUEST;
+    case CKMC_ERROR_BAD_RESPONSE:          return CKM_API_ERROR_BAD_RESPONSE;
+    case CKMC_ERROR_SEND_FAILED:           return CKM_API_ERROR_SEND_FAILED;
+    case CKMC_ERROR_RECV_FAILED:           return CKM_API_ERROR_RECV_FAILED;
+    case CKMC_ERROR_AUTHENTICATION_FAILED: return CKM_API_ERROR_AUTHENTICATION_FAILED;
+    case CKMC_ERROR_INVALID_PARAMETER:     return CKM_API_ERROR_INPUT_PARAM;
+    case CKMC_ERROR_BUFFER_TOO_SMALL:      return CKM_API_ERROR_BUFFER_TOO_SMALL;
+    case CKMC_ERROR_OUT_OF_MEMORY:         return CKM_API_ERROR_OUT_OF_MEMORY;
+    case CKMC_ERROR_PERMISSION_DENIED:     return CKM_API_ERROR_ACCESS_DENIED;
+    case CKMC_ERROR_SERVER_ERROR:          return CKM_API_ERROR_SERVER_ERROR;
+    case CKMC_ERROR_DB_LOCKED:             return CKM_API_ERROR_DB_LOCKED;
+    case CKMC_ERROR_DB_ERROR:              return CKM_API_ERROR_DB_ERROR;
+    case CKMC_ERROR_DB_ALIAS_EXISTS:       return CKM_API_ERROR_DB_ALIAS_EXISTS;
+    case CKMC_ERROR_DB_ALIAS_UNKNOWN:      return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
+    case CKMC_ERROR_VERIFICATION_FAILED:   return CKM_API_ERROR_VERIFICATION_FAILED;
+    case CKMC_ERROR_INVALID_FORMAT:        return CKM_API_ERROR_INVALID_FORMAT;
+    case CKMC_ERROR_FILE_ACCESS_DENIED:    return CKM_API_ERROR_FILE_ACCESS_DENIED;
+    case CKMC_ERROR_NOT_EXPORTABLE:        return CKM_API_ERROR_NOT_EXPORTABLE;
+    case CKMC_ERROR_UNKNOWN:               return CKM_API_ERROR_UNKNOWN;
+    }
+    return CKMC_ERROR_UNKNOWN;
 }
 
 int to_ckmc_error(int ckm_error) {
-       switch(ckm_error) {
-       case CKM_API_SUCCESS:                     return CKMC_ERROR_NONE;
-       case CKM_API_ERROR_SOCKET:                return CKMC_ERROR_SOCKET;
-       case CKM_API_ERROR_BAD_REQUEST:           return CKMC_ERROR_BAD_REQUEST;
-       case CKM_API_ERROR_BAD_RESPONSE:          return CKMC_ERROR_BAD_RESPONSE;
-       case CKM_API_ERROR_SEND_FAILED:           return CKMC_ERROR_SEND_FAILED;
-       case CKM_API_ERROR_RECV_FAILED:           return CKMC_ERROR_RECV_FAILED;
-       case CKM_API_ERROR_AUTHENTICATION_FAILED: return CKMC_ERROR_AUTHENTICATION_FAILED;
-       case CKM_API_ERROR_INPUT_PARAM:           return CKMC_ERROR_INVALID_PARAMETER;
-       case CKM_API_ERROR_BUFFER_TOO_SMALL:      return CKMC_ERROR_BUFFER_TOO_SMALL;
-       case CKM_API_ERROR_OUT_OF_MEMORY:         return CKMC_ERROR_OUT_OF_MEMORY;
-       case CKM_API_ERROR_ACCESS_DENIED:         return CKMC_ERROR_PERMISSION_DENIED;
-       case CKM_API_ERROR_SERVER_ERROR:          return CKMC_ERROR_SERVER_ERROR;
-       case CKM_API_ERROR_DB_LOCKED:             return CKMC_ERROR_DB_LOCKED;
-       case CKM_API_ERROR_DB_ERROR:              return CKMC_ERROR_DB_ERROR;
-       case CKM_API_ERROR_DB_ALIAS_EXISTS:       return CKMC_ERROR_DB_ALIAS_EXISTS;
-       case CKM_API_ERROR_DB_ALIAS_UNKNOWN:      return CKMC_ERROR_DB_ALIAS_UNKNOWN;
-       case CKM_API_ERROR_VERIFICATION_FAILED:   return CKMC_ERROR_VERIFICATION_FAILED;
-       case CKM_API_ERROR_INVALID_FORMAT:        return CKMC_ERROR_INVALID_FORMAT;
-       case CKM_API_ERROR_FILE_ACCESS_DENIED:    return CKMC_ERROR_FILE_ACCESS_DENIED;
+    switch(ckm_error) {
+    case CKM_API_SUCCESS:                     return CKMC_ERROR_NONE;
+    case CKM_API_ERROR_SOCKET:                return CKMC_ERROR_SOCKET;
+    case CKM_API_ERROR_BAD_REQUEST:           return CKMC_ERROR_BAD_REQUEST;
+    case CKM_API_ERROR_BAD_RESPONSE:          return CKMC_ERROR_BAD_RESPONSE;
+    case CKM_API_ERROR_SEND_FAILED:           return CKMC_ERROR_SEND_FAILED;
+    case CKM_API_ERROR_RECV_FAILED:           return CKMC_ERROR_RECV_FAILED;
+    case CKM_API_ERROR_AUTHENTICATION_FAILED: return CKMC_ERROR_AUTHENTICATION_FAILED;
+    case CKM_API_ERROR_INPUT_PARAM:           return CKMC_ERROR_INVALID_PARAMETER;
+    case CKM_API_ERROR_BUFFER_TOO_SMALL:      return CKMC_ERROR_BUFFER_TOO_SMALL;
+    case CKM_API_ERROR_OUT_OF_MEMORY:         return CKMC_ERROR_OUT_OF_MEMORY;
+    case CKM_API_ERROR_ACCESS_DENIED:         return CKMC_ERROR_PERMISSION_DENIED;
+    case CKM_API_ERROR_SERVER_ERROR:          return CKMC_ERROR_SERVER_ERROR;
+    case CKM_API_ERROR_DB_LOCKED:             return CKMC_ERROR_DB_LOCKED;
+    case CKM_API_ERROR_DB_ERROR:              return CKMC_ERROR_DB_ERROR;
+    case CKM_API_ERROR_DB_ALIAS_EXISTS:       return CKMC_ERROR_DB_ALIAS_EXISTS;
+    case CKM_API_ERROR_DB_ALIAS_UNKNOWN:      return CKMC_ERROR_DB_ALIAS_UNKNOWN;
+    case CKM_API_ERROR_VERIFICATION_FAILED:   return CKMC_ERROR_VERIFICATION_FAILED;
+    case CKM_API_ERROR_INVALID_FORMAT:        return CKMC_ERROR_INVALID_FORMAT;
+    case CKM_API_ERROR_FILE_ACCESS_DENIED:    return CKMC_ERROR_FILE_ACCESS_DENIED;
     case CKM_API_ERROR_NOT_EXPORTABLE:        return CKMC_ERROR_NOT_EXPORTABLE;
-       case CKM_API_ERROR_UNKNOWN:               return CKMC_ERROR_UNKNOWN;
-       }
-       return CKMC_ERROR_UNKNOWN;
+    case CKM_API_ERROR_UNKNOWN:               return CKMC_ERROR_UNKNOWN;
+    }
+    return CKMC_ERROR_UNKNOWN;
+}
+
+ckmc_ocsp_status_e to_ckmc_ocsp_status(int ckm_ocsp_status) {
+    switch(ckm_ocsp_status) {
+    case CKM_API_OCSP_STATUS_GOOD:             return CKMC_OCSP_STATUS_GOOD;
+    case CKM_API_OCSP_STATUS_UNSUPPORTED:      return CKMC_OCSP_ERROR_UNSUPPORTED;
+    case CKM_API_OCSP_STATUS_REVOKED:          return CKMC_OCSP_STATUS_REVOKED;
+    case CKM_API_OCSP_STATUS_NET_ERROR:        return CKMC_OCSP_ERROR_NET;
+    case CKM_API_OCSP_STATUS_INVALID_URL:      return CKMC_OCSP_ERROR_INVALID_URL;
+    case CKM_API_OCSP_STATUS_INVALID_RESPONSE: return CKMC_OCSP_ERROR_INVALID_RESPONSE;
+    case CKM_API_OCSP_STATUS_REMOTE_ERROR:     return CKMC_OCSP_ERROR_REMOTE;
+    case CKM_API_OCSP_STATUS_INTERNAL_ERROR:   return CKMC_OCSP_ERROR_INTERNAL;
+    default:                                   return CKMC_OCSP_STATUS_UNKNOWN;
+    }
 }
 
index 661d913..26618b2 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <ckm/ckm-error.h>
 #include <ckmc/ckmc-error.h>
+#include <ckmc/ckmc-type.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -32,6 +33,7 @@ extern "C" {
 
 int to_ckmc_error(int ckm_error);
 int to_ckm_error(int ckmc_error);
+ckmc_ocsp_status_e to_ckmc_ocsp_status(int ckm_ocsp_status);
 
 #ifdef __cplusplus
 }
index b392715..a8a43ea 100644 (file)
@@ -20,9 +20,8 @@
  * @brief       OCSP implementation.
  */
 
+#include <string>
 #include <ocsp.h>
-#include <stdio.h>
-#include <string.h>
 #include <openssl/pem.h>
 #include <openssl/ocsp.h>
 #include <openssl/err.h>
@@ -71,13 +70,13 @@ int OCSPModule::verify(const CertificateImplVector &certificateChain) {
     bool unsupported = false; // ocsp is unsupported in certificate in chain (except root CA)
 
     if((systemCerts = loadSystemCerts(CKM_SYSTEM_CERTS_PATH)) == NULL) {
-        LogDebug("Error in loadSystemCerts function");
+        LogError("Error in loadSystemCerts function");
         return CKM_API_OCSP_STATUS_INTERNAL_ERROR;
     }
 
     for(unsigned int i=0; i < certificateChain.size() -1; i++) {// except root certificate
         if (certificateChain[i].empty() || certificateChain[i+1].empty()) {
-            LogDebug("Error. Broken certificate chain.");
+            LogError("Error. Broken certificate chain.");
             return CKM_API_OCSP_STATUS_INTERNAL_ERROR;
         }
 
@@ -86,7 +85,7 @@ int OCSPModule::verify(const CertificateImplVector &certificateChain) {
         std::string url = certificateChain[i].getOCSPURL();
 
         if (url.empty()) {
-            LogDebug("Certificate does not provide OCSP extension.");
+            LogError("Certificate in certchain[" << i << "] does not provide OCSP extension.");
             unsupported = true;
             continue;
         }
@@ -94,7 +93,8 @@ int OCSPModule::verify(const CertificateImplVector &certificateChain) {
         int result = ocsp_verify(cert, issuer, systemCerts, url);
 
         if(result != CKM_API_OCSP_STATUS_GOOD) {
-            LogDebug("Fail to OCSP certification checking: " << result);
+            LogError("Fail to OCSP certification check. Errorcode=[" << result <<
+                "], on certChain[" << i << "]");
             return result;
         }
     }