Implementation of primitives in CertificateImpl class.
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Mon, 14 Jul 2014 14:15:15 +0000 (16:15 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 12 Sep 2014 12:58:58 +0000 (14:58 +0200)
Now you can extrat values of Subject/Issuer fiels directly from
CertificateImpl class.

Change-Id: I521df36d1fddd384ace13a5e338f3914221f5dbe

src/include/ckm/ckm-error.h
src/include/ckm/ckm-type.h
src/manager/common/certificate-impl.cpp
src/manager/common/certificate-impl.h
src/manager/service/ocsp.cpp
src/manager/service/ocsp.h

index 2aeb435..457906e 100644 (file)
@@ -87,14 +87,15 @@ extern "C" {
 /*! \brief   indicating that provided file doesn't exists or cannot be accessed in the file system */
 #define CKM_API_ERROR_FILE_ACCESS_DENIED -18
 
-#define CKM_API_OCSP_STATUS_GOOD                0
-#define CKM_API_OCSP_STATUS_UNKNOWN             -21
-#define CKM_API_OCSP_STATUS_REVOKED             -22
-#define CKM_API_OCSP_STATUS_NET_ERROR           -23
-#define CKM_API_OCSP_STATUS_INVALID_URL         -24
-#define CKM_API_OCSP_STATUS_INVALID_RESPONSE    -25
-#define CKM_API_OCSP_STATUS_REMOTE_ERROR        -26
-#define CKM_API_OCSP_STATUS_INTERNAL_ERROR      -27
+#define CKM_API_OCSP_STATUS_GOOD                (1<<0)
+#define CKM_API_OCSP_STATUS_UNSUPPORTED         (1<<1)
+#define CKM_API_OCSP_STATUS_UNKNOWN             (1<<2)
+#define CKM_API_OCSP_STATUS_REVOKED             (1<<3)
+#define CKM_API_OCSP_STATUS_NET_ERROR           (1<<4)
+#define CKM_API_OCSP_STATUS_INVALID_URL         (1<<5)
+#define CKM_API_OCSP_STATUS_INVALID_RESPONSE    (1<<6)
+#define CKM_API_OCSP_STATUS_REMOTE_ERROR        (1<<7)
+#define CKM_API_OCSP_STATUS_INTERNAL_ERROR      (1<<8)
 
 /*! \brief   indicating the error with unknown reason */
 #define CKM_API_ERROR_UNKNOWN -255
index a054918..89b00e0 100644 (file)
@@ -53,6 +53,11 @@ enum class ElipticCurve : int {
     secp384r1
 };
 
+enum class CertificateFieldId : int {
+    ISSUER,
+    SUBJECT
+};
+
 struct Policy {
     Policy(const std::string &pass = std::string(), bool extract = true, bool rest = false)
       : password(pass)
index 3e446ef..d2a26a9 100644 (file)
@@ -19,6 +19,7 @@
  * @brief       Key implementation.
  */
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
 #include <openssl/pem.h>
 
 #include <dpl/log/log.h>
@@ -109,10 +110,8 @@ RawBuffer CertificateImpl::getDER(void) const {
     unsigned char *rawDer = NULL;
     int size = i2d_X509(m_x509, &rawDer);
     if (!rawDer || size <= 0) {
-        // TODO
         LogError("i2d_X509 failed");
-//        ThrowMsg(Exception::OpensslInternalError,
-//          "i2d_X509 failed");
+        return RawBuffer();
     }
 
     RawBuffer output(
@@ -140,6 +139,113 @@ GenericKey CertificateImpl::getGenericKey() const {
     return GenericKey();
 }
 
+X509_NAME *getX509Name(X509 *x509, CertificateFieldId type) {
+    if (!x509)
+        return NULL;
+
+    if (type == CertificateFieldId::ISSUER)
+        return X509_get_issuer_name(x509);
+    else if (type == CertificateFieldId::SUBJECT)
+        return X509_get_subject_name(x509);
+
+    LogError("Invalid param. Unknown CertificateFieldId");
+    return NULL;
+}
+
+std::string CertificateImpl::getOneLine(CertificateFieldId type) const
+{
+    X509_NAME *name = getX509Name(m_x509, type);
+    if (!name)
+        return std::string();
+    static const int MAXB = 1024;
+    char buffer[MAXB];
+    X509_NAME_oneline(name, buffer, MAXB);
+    return std::string(buffer);
+}
+
+std::string CertificateImpl::getField(CertificateFieldId type, int fieldNid) const {
+    X509_NAME *subjectName = getX509Name(m_x509, type);
+    X509_NAME_ENTRY *subjectEntry = NULL;
+
+    if (!subjectName)
+        return std::string();
+
+    int entryCount = X509_NAME_entry_count(subjectName);
+
+    for (int i = 0; i < entryCount; ++i) {
+        subjectEntry = X509_NAME_get_entry(subjectName, i);
+
+        if (!subjectEntry) {
+            continue;
+        }
+
+        int nid = OBJ_obj2nid(
+            static_cast<ASN1_OBJECT*>(
+                    X509_NAME_ENTRY_get_object(subjectEntry)));
+
+        if (nid != fieldNid) {
+            continue;
+        }
+
+        ASN1_STRING* pASN1Str = subjectEntry->value;
+
+        unsigned char* pData = NULL;
+        int nLength = ASN1_STRING_to_UTF8(&pData, pASN1Str);
+
+        if (nLength < 0) {
+            LogError("Reading field error.");
+            return std::string();
+        }
+
+        std::string output(reinterpret_cast<char*>(pData), nLength);
+        OPENSSL_free(pData);
+        return output;
+    }
+    return std::string();
+}
+
+std::string CertificateImpl::getCommonName(CertificateFieldId type) const {
+    return getField(type, NID_commonName);
+}
+
+std::string CertificateImpl::getCountryName(CertificateFieldId type) const {
+    return getField(type, NID_countryName);
+}
+
+std::string CertificateImpl::getStateOrProvinceName(CertificateFieldId type) const {
+    return getField(type, NID_stateOrProvinceName);
+}
+
+std::string CertificateImpl::getLocalityName(CertificateFieldId type) const {
+    return getField(type, NID_localityName);
+}
+
+std::string CertificateImpl::getOrganizationName(CertificateFieldId type) const {
+    return getField(type, NID_organizationName);
+}
+
+std::string CertificateImpl::getOrganizationalUnitName(CertificateFieldId type) const {
+    return getField(type, NID_organizationalUnitName);
+}
+
+std::string CertificateImpl::getEmailAddres(CertificateFieldId type) const {
+    return getField(type, NID_pkcs9_emailAddress);
+}
+
+std::string CertificateImpl::getOCSPURL() const {
+    if (!m_x509)
+        return std::string();
+
+    STACK_OF(OPENSSL_STRING) *aia = X509_get1_ocsp(m_x509);
+
+    if (NULL == aia)
+        return std::string();
+
+    std::string result(sk_OPENSSL_STRING_value(aia, 0));
+    X509_email_free(aia);   // TODO is it correct?
+    return result;
+}
+
 CertificateImpl::~CertificateImpl() {
     LogDebug("free cert start ptr: " << (void*)m_x509);
     X509_free(m_x509);
index d364056..6a65f12 100644 (file)
@@ -49,6 +49,17 @@ public:
     GenericKey::EvpShPtr getEvpShPtr() const;
     GenericKey getGenericKey() const;
 
+    std::string getOneLine(CertificateFieldId type) const;
+    std::string getField(CertificateFieldId type, int fieldNid) const;
+    std::string getCommonName(CertificateFieldId type) const;
+    std::string getCountryName(CertificateFieldId type) const;
+    std::string getStateOrProvinceName(CertificateFieldId type) const;
+    std::string getLocalityName(CertificateFieldId type) const;
+    std::string getOrganizationName(CertificateFieldId type) const;
+    std::string getOrganizationalUnitName(CertificateFieldId type) const;
+    std::string getEmailAddres(CertificateFieldId type) const;
+    std::string getOCSPURL() const;
+
     X509* getX509() const;
 
     virtual ~CertificateImpl();
index 1934385..9db3eb0 100644 (file)
@@ -37,8 +37,6 @@
 /* Maximum leeway in validity period: default 5 minutes */
 #define MAX_VALIDITY_PERIOD     (5 * 60)
 
-#define CKM_DEF_STRING_LEN             256
-
 namespace CKM {
 
 OCSPModule::OCSPModule() {
@@ -50,8 +48,7 @@ OCSPModule::~OCSPModule(){
 }
 
 int OCSPModule::verify(const CertificateImplVector &certificateChain) {
-    char url[CKM_DEF_STRING_LEN];
-    int result = -1;
+    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");
@@ -63,21 +60,31 @@ int OCSPModule::verify(const CertificateImplVector &certificateChain) {
             LogDebug("Error. Broken certificate chain.");
             return CKM_API_OCSP_STATUS_INTERNAL_ERROR;
         }
+
         X509 *cert   = certificateChain[i].getX509();
         X509 *issuer = certificateChain[i+1].getX509();
-        extractAIAUrl(cert, url);
-        result = ocsp_verify(cert, issuer, systemCerts, url);
+        std::string url = certificateChain[i].getOCSPURL();
+
+        if (url.empty()) {
+            LogDebug("Certificate does not provide OCSP extension.");
+            unsupported = true;
+            continue;
+        }
+
+        int result = ocsp_verify(cert, issuer, systemCerts, url);
+
         if(result != CKM_API_OCSP_STATUS_GOOD) {
             LogDebug("Fail to OCSP certification checking: " << result);
             return result;
         }
     }
 
+    if (unsupported)
+        return CKM_API_OCSP_STATUS_UNSUPPORTED;
     return CKM_API_OCSP_STATUS_GOOD;
 }
 
-
-int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCerts, char *url) {
+int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCerts, const std::string &constUrl) {
        OCSP_REQUEST *req = NULL;
        OCSP_RESPONSE *resp = NULL;
        OCSP_BASICRESP *bs = NULL;
@@ -97,12 +104,14 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
        //    const char *reason_str = NULL;0
        X509_STORE *trustedStore=NULL;
 
-       if (!OCSP_parse_url(url, &host, &port, &path, &use_ssl)) {
+    std::vector<char> url(constUrl.begin(), constUrl.end());
+
+    if (!OCSP_parse_url(url.data(), &host, &port, &path, &use_ssl)) {
                /* report error */
                return CKM_API_OCSP_STATUS_INVALID_URL;
        }
 
-       cbio = BIO_new_connect(host);
+    cbio = BIO_new_connect(host);
        if (cbio == NULL) {
                /*BIO_printf(bio_err, "Error creating connect BIO\n");*/
                /* report error */
@@ -340,16 +349,5 @@ int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCert
     }
 }
 
-void OCSPModule::extractAIAUrl(X509 *cert, char *url) {
-       STACK_OF(OPENSSL_STRING) *aia = NULL;
-       aia = X509_get1_ocsp(cert);
-       if(aia == NULL) {
-               return;
-       }
-       strcpy(url, sk_OPENSSL_STRING_value(aia, 0));
-       X509_email_free(aia);
-       return;
-}
-
 } // namespace CKM
 
index d924a22..512b7a7 100644 (file)
@@ -28,7 +28,6 @@
 
 namespace CKM {
 
-
 class OCSPModule {
 public:
        OCSPModule();
@@ -38,10 +37,8 @@ public:
        // OK, UNKNOWN, REVOKED, NO_NETWORK, TIMEOUT
     int verify(const CertificateImplVector &certificateChain);
 private:
-    int ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCerts, char *url);
-    void extractAIAUrl(X509 *cert, char *url);
+    int ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *systemCerts, const std::string &url);
     STACK_OF(X509) *systemCerts;
-
 };
 
 } // namespace CKM