This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the web-development category.
Last Updated: 2024-11-23
Ten customers did not receive their items in Oxbridge Notes one day, the biggest downtime in about years. The error in Rollbar was this:
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)
What does this mean? Why did it happen?
I discovered that the PayPal gem (which I still rely on for payment) included its own certs:
DigiCertHighAssuranceEVRootCA.pem
DigiCertSHA2ExtendedValidationServerCA.pem
paypal.crt
and then used these for SSL
def default_ca_file
File.expand_path("../../../../../data/paypal.crt", __FILE__)
end
# Apply ssl configuration to http object
def configure_ssl(http)
http.tap do |https|
https.use_ssl = true
https.ca_file = default_ca_file
...
end
end
But then those certs in this library expired... and PayPal did not update the gem because it was deprecated. So my code, using an expired cert, failed.
The quickest was to tell PayPal not to use the bundled SSL certs at all. Then it just used the standard HTTP system
PayPal::SDK.configure(
mode: ...,
client_id: ...,
client_secret: ...,
# Deliberately set ca_file to nil so the system's Cert Authority is used,
# instead of the bundled paypal.crt file which is out-of-date due to:
# https://www.paypal.com/va/smarthelp/article/discontinue-use-of-verisign-g5-root-certificates-ts2240
ssl_options: { ca_file: nil }
)
Avoid using bundled certs because they might expire.