c-jimenez/open-ocpp

Regarding the issue of the root certificate being unable to verify the certificate,

JamesLebron opened this issue · 3 comments

Dear author, hello.

I have encountered some issues regarding certificate-related functionality, particularly regarding the problem of root certificate verification for certificates.

  1. Currently, I have two certificates: 1.pem (containing certificate A) and 2.pem (containing certificates B and C). The complete certificate chain is A/B/C (with C being the top-level CA).

  2. When I attempt to verify 1.pem using 2.pem (root), I receive a failure result (from the return value of the Certificate::verify function in Certificate.cpp).

  3. I have tried swapping the order of certificates B and C in 2.pem, but I still receive a failure result (from the return value of the Certificate::verify function in Certificate.cpp).

  4. In the same operating system and environment, I have tried using the openssl command for verification:

openssl verify -CAfile 2.pem 1.pem

I have tried both swapping and not swapping the order of certificates B and C in 2.pem, and in both cases, the verification succeeds.

Dear author, could you please provide me with some suggestions for modification?

Below is the PEM content of the certificates:

[1.pem]
-----BEGIN CERTIFICATE-----
MIIGfzCCBOegAwIBAgIRAP90I3tYvw8Yh0nkJvGU0qwwDQYJKoZIhvcNAQEMBQAw
WTELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs
IEluYy4xIzAhBgNVBAMTGlRydXN0QXNpYSBSU0EgRFYgVExTIENBIEcyMB4XDTIz
MDgwMTAwMDAwMFoXDTI0MDgzMDIzNTk1OVowGjEYMBYGA1UEAxMPd3lldmNoYXJn
ZXIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArCXBTauJGBG1
ZI/eoR5OAPIXCGd9stkFbAaNRTsqmJ3JjoZve8u0xvl9r2sw4Ya9YoyYN5+Sxbvr
awu2jUeYOTG8k30lcw9vpB/k/btsvNuWBDJRklj9LKgzbmBrXFHBSmVPlen7SFu4
nttZctlIrGWByete9jn69y5UArlOGw6mXYBDromIcbH0Dw36uCTzGXFqQt03VWjC
tInUaX9WiLdELvUjZZPXYNq+RiXAzNGtNK9rNZJky7wqjOD4i3PLi9zfEeqG75ti
kIcwC4qFhli6Dz/EmaObwe1868caG+rS+DFO4mf7fY7c04Zj7EhM0E7undvQ1VQz
FxcSz4fbjQIDAQABo4IC/zCCAvswHwYDVR0jBBgwFoAUXzp8ERB+DGdxYdyLo7UA
A2f1VxwwHQYDVR0OBBYEFJUXz+oJyWpOfsZvi7itDfO1OanPMA4GA1UdDwEB/wQE
AwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD
AjBJBgNVHSAEQjBAMDQGCysGAQQBsjEBAgIxMCUwIwYIKwYBBQUHAgEWF2h0dHBz
Oi8vc2VjdGlnby5jb20vQ1BTMAgGBmeBDAECATB9BggrBgEFBQcBAQRxMG8wQgYI
KwYBBQUHMAKGNmh0dHA6Ly9jcnQudHJ1c3QtcHJvdmlkZXIuY24vVHJ1c3RBc2lh
UlNBRFZUTFNDQUcyLmNydDApBggrBgEFBQcwAYYdaHR0cDovL29jc3AudHJ1c3Qt
cHJvdmlkZXIuY24wLwYDVR0RBCgwJoIPd3lldmNoYXJnZXIuY29tghN3d3cud3ll
dmNoYXJnZXIuY29tMIIBfwYKKwYBBAHWeQIEAgSCAW8EggFrAWkAdgB2/4g/Crb7
lVHCYcz1h7o0tKTNuyncaEIKn+ZnTFo6dAAAAYmurIGzAAAEAwBHMEUCIQDC1Iup
XhCHSihbyuf6qG9/ZxKwLJxv6tksbw8j59WKUAIgeuk5jjvH6dJERSSxKSjDvx56
aiQKm0jEtCdtnRfHBQcAdgDatr9rP7W2Ip+bwrtca+hwkXFsu1GEhTS9pD0wSNf7
qwAAAYmurIIFAAAEAwBHMEUCIQDBCvCY8TF6hgp0XqDH+Jir8SscT3WF5RSqGnP9
3bgq9QIgLv9V1ldDmN0XdNg1SiyQcXOmafMSd8SgLShH5E+RprcAdwDuzdBk1dsa
zsVct520zROiModGfLzs3sNRSFlGcR+1mwAAAYmurIHiAAAEAwBIMEYCIQCWj7fn
AUbktgKJ26mscZ6Va/wHNKodEYR3XKT4JgdXfAIhAItFRZM2rAnKOKHsz7TOJKNy
4WZx6rzPNMr5sVh9V50sMA0GCSqGSIb3DQEBDAUAA4IBgQCLgSNYEZeZpMY9/Vlc
ctinjIAExRjbaaTd78pBq8ziev7JT9MhOkmSgsTSE/vT0nIzYoXZHUC1iTz944Xe
+keYFbkYxp1zJ4secQlJPTCz+W4ZvOAGBrY9JJAUjddR8sKUrpKWD0NRh18OvcBD
cRayN3Yxaps6OgElHS2AI4vZq3Vp7fejxphyK+zm19U/vQn+97QQicCsnKrJmLaZ
lsdlWkV3ywAOVGLvIzbv3QG5IrpHrfncN32KXKPWxxtggvK4C+hvt6JmePiXBNo4
REEjoTGoe83GaTTl9R5kRv1T3Se3N0jyu3+joa35nUqFG/iLyDpbhLTqwOXncvaS
L4yvJFHUDEzFurcW7+8kBThbmQVcuy7tvPjbbB0wMKsFov4QOIerOneYyGOMRTtZ
YkUiU2x4GfgGjJLZKF52AWeaq4SIWhHwcGq6d/6OCpbd1e5eZCAFCuO8Qx+iGe0j
enlZVTijr2BLYPdxbzhQsoTqCSFdJku4uhNFEtgpSYKUxoU=
-----END CERTIFICATE-----
[2.pem]
-----BEGIN CERTIFICATE-----
MIIFBzCCA++gAwIBAgIRALIM7VUuMaC/NDp1KHQ76aswDQYJKoZIhvcNAQELBQAw
ezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0yMjAxMTAwMDAwMDBaFw0y
ODEyMzEyMzU5NTlaMFkxCzAJBgNVBAYTAkNOMSUwIwYDVQQKExxUcnVzdEFzaWEg
VGVjaG5vbG9naWVzLCBJbmMuMSMwIQYDVQQDExpUcnVzdEFzaWEgUlNBIERWIFRM
UyBDQSBHMjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKjGDe0GSaBs
Yl/VhMaTM6GhfR1TAt4mrhN8zfAMwEfLZth+N2ie5ULbW8YvSGzhqkDhGgSBlafm
qq05oeESrIJQyz24j7icGeGyIZ/jIChOOvjt4M8EVi3O0Se7E6RAgVYcX+QWVp5c
Sy+l7XrrtL/pDDL9Bngnq/DVfjCzm5ZYUb1PpyvYTP7trsV+yYOCNmmwQvB4yVjf
IIpHC1OcsPBntMUGeH1Eja4D+qJYhGOxX9kpa+2wTCW06L8T6OhkpJWYn5JYiht5
8exjAR7b8Zi3DeG9oZO5o6Qvhl3f8uGU8lK1j9jCUN/18mI/5vZJ76i+hsgdlfZB
Rh5lmAQjD80M9TY+oD4MYUqB5XrigPfFAUwXFGehhlwCVw7y6+5kpbq/NpvM5Ba8
SeQYUUuMA8RXpTtGlrrTPqJryfa55hTuX/ThhX4gcCVkbyujo0CYr+Uuc14IOyNY
1fD0/qORbllbgV41wiy/2ZUWZQUodqHWkjT1CwIMbQOY5jmrSYGBwwIDAQABo4IB
JjCCASIwHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYDVR0OBBYE
FF86fBEQfgxncWHci6O1AANn9VccMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8E
CDAGAQH/AgEAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAiBgNVHSAE
GzAZMA0GCysGAQQBsjEBAgIxMAgGBmeBDAECATBDBgNVHR8EPDA6MDigNqA0hjJo
dHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNy
bDA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9k
b2NhLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAHMUom5cxIje2IiFU7mOCsBr2F6CY
eU5cyfQ/Aep9kAXYUDuWsaT85721JxeXFYkf4D/cgNd9+hxT8ZeDOJrn+ysqR7NO
2K9AdqTdIY2uZPKmvgHOkvH2gQD6jc05eSPOwdY/10IPvmpgUKaGOa/tyygL8Og4
3tYyoHipMMnS4OiYKakDJny0XVuchIP7ZMKiP07Q3FIuSS4omzR77kmc75/6Q9dP
v4wa90UCOn1j6r7WhMmX3eT3Gsdj3WMe9bYD0AFuqa6MDyjIeXq08mVGraXiw73s
Zale8OMckn/BU3O/3aFNLHLfET2H2hT6Wb3nwxjpLIfXmSVcVd8A58XH0g==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
-----END CERTIFICATE-----

Hello,

I just made the following test with your certificates and everything was fine, the verification was successful :

Certificate cert(std::filesystem::path("1.pem"));
CHECK(cert.isValid());

Certificate ca_certs(std::filesystem::path("2.pem"));
CHECK(ca_certs.isValid());

CHECK(cert.verify(ca_certs.certificateChain()));

How did you make your verification using the Certificate class?

Dear author, hello.

  1. I used the approach you provided, "constructing a Certificate from a file path," and the result was consistent with yours. The verification passed.

  2. Therefore, I continued to investigate and found that the problem lies in the following code: DefaultChargePointEventsHandler::checkFirmwareSigningCertificate.

ocpp::types::UpdateFirmwareStatusEnumType DefaultChargePointEventsHandler::checkFirmwareSigningCertificate(
    const ocpp::x509::Certificate& signing_certificate)
{
    UpdateFirmwareStatusEnumType ret = UpdateFirmwareStatusEnumType::InvalidCertificate;

    cout << "Check of firmware signing certificate requested : subject = " << signing_certificate.subjectString()
         << " - issuer = " << signing_certificate.issuerString() << endl;

    // Load all installed Manufacturer CA certificates
    std::vector<Certificate> ca_certificates;
    for (auto const& dir_entry : std::filesystem::directory_iterator{m_working_dir})
    {
        if (!dir_entry.is_directory())
        {
            std::string filename = dir_entry.path().filename().string();
            if (ocpp::helpers::startsWith(filename, "fw_") && ocpp::helpers::endsWith(filename, ".pem"))
            {
                ca_certificates.emplace_back(dir_entry.path());
            }
        }
    }
    if (!ca_certificates.empty())
    {
        // Check signing certificate
        if (signing_certificate.verify(ca_certificates))
        {
            ret = UpdateFirmwareStatusEnumType::Accepted;
        }
    }
    else
    {
        cout << "No manufacturer CA installed" << endl;
    }

    return ret;
}
  1. I made the following modifications to the code, and the verification passed.
   if (!ca_certificates.empty())
    {
        bool verify_result = false;
        // Check signing certificate
        for (auto cer : ca_certificates)
        {
            verify_result = signing_certificate.verify(cer.certificateChain());
            if (verify_result)
            {
                ret = UpdateFirmwareStatusEnumType::Accepted;
                break;
            }
        }
    }
    else
    {
        LOG_DEBUG << "No manufacturer CA installed";
    }

However, I have encountered another issue, which I will submit to you as a new issue later. Could you please provide some guidance?

Hi,
Thank you for your findings and your proposal that I have integrated in #149
Regards