设备证书的openssl验证失败

时间:2019-07-20 01:33:10

标签: c++ openssl ssl-certificate x509certificate

我有两个证书。一个是由Digicert(全球CA)“ www.lu.org_ssl_certificate_INTERMEDIATE”签名的中间证书,另一个是由该中间证书签名的组织“ www.lu.org_ssl_certificate”的证书。我拥有组织证书的私钥“ www.lu.org_private_key.key”。我必须创建一个新的x509证书(设备证书),该证书将由组织证书及其私钥签名。该证书将在设备上保留并用于验证。使用设备证书时,我无法验证证书链。相同的代码可用于验证组织证书。

我正在使用以下命令从Windows终端在openssl中生成设备证书。

  1. openssl genrsa -out device_key.key 2048(生成私钥)
  2. openssl req -new -sha256 -key device_key.key -out device_csr.csr(生成证书签名请求)
  3. openssl x509 -req -in device_csr.csr -CA www.lu.org_ssl_certificate.cer -CAkey www.lu.org_private_key.key -CAcreateserial -out device_cert.cer -days 365 -sha256(生成x509证书)
    int verify_cb(int ok, X509_STORE_CTX* ctx)
    {
        if (!ok)
        {
            /* check the error code and current cert*/
            X509* currentCert = X509_STORE_CTX_get_current_cert(ctx);
            int certError = X509_STORE_CTX_get_error(ctx);
            int depth = X509_STORE_CTX_get_error_depth(ctx);
            std::cout << "Error depth: " << depth << "certError: " << certError << std::endl;
            std::cout << X509_verify_cert_error_string(certError) << std::endl;
        }

        return ok;
    }

    X509* load_cert_from_file(const char* sFilePath)
    {
        std::unique_ptr< BIO, std::function<void(BIO*)>> cert(BIO_new(BIO_s_file()), [](BIO* b) { BIO_free(b); });

        if (BIO_read_filename(cert.get(), sFilePath) <= 0)
            return NULL;

        return PEM_read_bio_X509_AUX(cert.get(), NULL, NULL, NULL);
    }

    bool CheckCertificateValidity(const std::string& sDeviceCert)
    {

        std::string sRootCA = "CAcert.pem"; // global digicert cert
        std::string sLuCert = "www.lu.org_ssl_certificate.cer"; // organisation cert 
        std::string sInterCert = "www.lu.org_ssl_certificate_INTERMEDIATE.cer"; // Intermediate cert 

        // Load all the certificates in the memory from the file...
        std::unique_ptr< X509, std::function<void(X509*)>> zRootCA(NULL, [](X509* b) { X509_free(b); });
        X509* zRootCA_ptr = zRootCA.get();
        zRootCA_ptr = load_cert_from_file(sRootCA.c_str());
        if (!zRootCA_ptr)
            return false;

        std::unique_ptr< X509, std::function<void(X509*)>> zInterCert(NULL, [](X509* b) { X509_free(b); });
        X509* zInterCert_ptr = zInterCert.get();
        zInterCert_ptr = load_cert_from_file(sInterCert.c_str());
        if (!zInterCert_ptr)
            return false;

        std::unique_ptr< X509, std::function<void(X509*)>> zLuCert(NULL, [](X509* b) { X509_free(b); });
        X509* zLuCert_ptr = zLuCert.get();
        zLuCert_ptr = load_cert_from_file(sLuCert.c_str());
        if (!zLuCert_ptr)
            return false;

        std::unique_ptr< X509, std::function<void(X509*)>> zDeviceCert(NULL, [](X509* b) { X509_free(b); });
        X509* zDeviceCert_ptr = zDeviceCert.get();
        zDeviceCert_ptr = load_cert_from_file(sDeviceCert.c_str());
        if (!zDeviceCert_ptr)
            return false;

        /*
        1. Create a certificate store using X509_STORE_CTX_new for one time certificate validation.
        2. Create a X509_STORE for storing intermediate cerificates and root certificates
        3. Add certificates to store
        4. Add certificate to be verified.
        5. Do the verification.
        */
        std::unique_ptr< X509_STORE_CTX, std::function<void(X509_STORE_CTX*)>> ctx(X509_STORE_CTX_new(), [](X509_STORE_CTX* b) { X509_STORE_CTX_free(b); });
        std::unique_ptr< X509_STORE, std::function<void(X509_STORE*)>> store(X509_STORE_new(), [](X509_STORE* b) { X509_STORE_free(b); });
        X509_STORE_add_cert(store.get(), zRootCA_ptr);
        X509_STORE_add_cert(store.get(), zInterCert_ptr);
        X509_STORE_add_cert(store.get(), zLuCert_ptr);

        X509_STORE_set_verify_cb(store.get(), verify_cb);

        X509_STORE_CTX_init(ctx.get(), store.get(), zDeviceCert_ptr, NULL);


        int status = X509_verify_cert(ctx.get());
        if (status == 1)
        {
            std::cout << "Certificate verified ok" << std::endl;
            return true;
        }
        else
        {
            std::cout << "Certificate verified failed" << std::endl;
            return false;
        }
    }

    int main(int argc, char* argv[])
    {
        std::string sDeviceCert = "device_cert.cer";
        if (!CheckCertificateValidity(sDeviceCert))
            std::cout << "Certificate verification failed.." << std::endl;
        return 0;
    }

运行设备证书的代码会给我一个错误“错误深度:0certError:20无法获取本地颁发者证书”。

我认为代码是正确的,因为当输入的是组织证书“ www.lu.org_ssl_certificate.cer”时,我可以验证证书链。我不知何故无法正确生成设备证书。这里的任何建议都会有所帮助。

0 个答案:

没有答案