1

I am trying to send a test request to the Swedish micro payment system Swish.

When running the code below, I get the error "SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])"

My OpenSSl version is 1.1.1j which means it supports TLS 1.2 which Swish requires.

What do I need to change to make it work?

import json
from requests_pkcs12 import put

url = "https://mss.cpc.getswish.net/swish-cpcapi/api/v2/paymentrequests/F628384EC1744F9BB1F871EA67CB8BA5"
clientP12 = "Swish_Merchant_TestCertificate_1234679304.p12"
signingCert = "Swish_Merchant_TestSigningCertificate_1234679304.pem"

payload = {
    "payeePaymentReference": "4",
    "callbackUrl": "https://mysite/API/on_swish_payment_done/?payeePaymentReference=4",
    "payerAlias": "0701234567",
    "payeeAlias": "1234679304",
    "amount": "100.00",
    "currency": "SEK"
}

headers = {'content-type': 'application/json'}

r = put(url,
        data=json.dumps(payload),
        headers=headers,
        pkcs12_filename=clientP12,
        pkcs12_password='swish',
        verify=signingCert
        )
Nelson
  • 43
  • 5
  • Added the tag python-requests as requests_pkcs12 (which I use in my code) is using that library. – Nelson Jul 17 '20 at 06:38
  • 1
    cert verification is not related to protocol version. verify= must contain the _cert of the root CA that (possibly indirectly) issued the server's cert_, and if your filename is even half-accurate, the file you are using is not any root CA much less the correct one. Since the correct root CA 'DigiCert Global Root CA' is in even my Ubuntu's rather out-of-date certifi 2018.1.18, most likely if you use the default verify=True it will work. – dave_thompson_085 Jul 17 '20 at 06:58
  • Thank you @dave_thompson_085 for your suggestion. I think you are pointing me in the right direction. I checked and saw that the "DigiCert Global Root CA" exists in my OSX installation. I now tried setting verify=True, but I got a new error: "SSLError("bad handshake: SysCallError(54, 'ECONNRESET')")". I also tried setting verify to a root CA provided by Swish (Swish_TLS_RootCA.pem) but that also gave me the ECONNRESET error. – Nelson Jul 17 '20 at 11:04
  • If by OSX you mean Keychain, python requests doesn't use that, it uses the python package certifi instead -- but DigiCert is wellknown and should be in _both_. Reset _might_ be caused if the server doesn't like your client cert (&key), but python doesn't have debugging capability here; try converting your 'testmerchant' cert&key to PEM with `openssl pcks12 -in testmerchant.p12 -out testmerchant.pem` then `openssl s_client -connect $host:$port -CAfile rootca.pem -cert testmerchant.pem -debug – dave_thompson_085 Jul 17 '20 at 20:15
  • @dave_thompson_085 Yes, i meant Keychain. Thanks, I did not know that python requests did not use it.I tried following your commands. I ran the commands you suggested and after the second command, I get the following output: 4493823424:error:02001002:system library:fopen:No such file or directory:crypto/bio/bss_file.c:69:fopen('rootca.pem','r') 4493823424:error:2006D080:BIO routines:BIO_new_file:no such file:crypto/bio/bss_file.c:76: 4493823424:error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib:crypto/x509/by_file.c:199: – Nelson Jul 17 '20 at 21:02
  • Use the names of your actual files, the filenames in my example were only placeholders to indicate _which_ file to use. (I probably should use $symbols for them also, but for decades I haven't and it's hard to change. Sorry.) – dave_thompson_085 Jul 20 '20 at 05:54

1 Answers1

1

I think you should use the Swish_TLS_RootCA.pem as verify. Afaik the signing certificate is only used to sign the payload for Swish Payouts