Closed FrancoisNoyez closed 2 years ago
To be clear: unencrypted .pem for mTLS connections work just fine. The issue is that if the .pem file does NOT contain a private key, the code fails -- this occurs with one-way TLS, when only the certificates are included. The usual solution is to get the OS to recognize the certificates, but if this is not an option, some approach is needed to get Python to recognize them for this particular TLS connection.
As such, simply checking for the wallet_password
value being None
is insufficient. I'll give it some more thought as to how this can be accomplished!
Hi Anthony,
Ok, I see. Sorry for me using the wrong terminology here, I don't have speific knowledge about encryption protocols in general, and TLS connection in particular. I have updated the title of the issue, but not my first post.
Hm, ok. I agree that, ideally, the change that I suggested is not enough, insofar as the behavior of the function / of the library needs to be consistent overall, and that this change would need to be properly advertised / we would need to let people know how it works. But maybe you think that this is insufficient for other reasons. In that case, I'm not sure to understand why. Would it be possible for you to explain this, please?
Anyway, thank you for considering it.
Looking further into this, I suspect it may be possible to just do this:
try:
ssl_context.load_cert_chain(pem_file_name,
password=params._get_wallet_password())
except ssl.SSLError:
pass
In other words, try to load the certificate chain from the supplied PEM file and simply ignore the error if it is unsuccessful. The error (as noted) isn't really all that helpful anyway! If one-way TLS is set up, it will work, and if 2-way TLS is required, a different error will be raised. I'm just checking internally to see what that looks like with an older database. Stay tuned!
Hi Anthony, So, was it possible for you to assess whether the change that you suggested to implement would be possible without breaking compatibility with older databases?
Not yet, unfortunately. I'm still waiting but will prod internally again. :-)
I was finally able to test with an older database. When supplying an invalid password for an encrypted PEM file, instead of this error
oracledb.exceptions.OperationalError: DPY-6005: cannot connect to database. Connection failed with "[SSL] PEM lib (_ssl.c:3895)"
you will now get
oracledb.exceptions.OperationalError: DPY-6005: cannot connect to database. Connection failed with "[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:997)"
And for your case, you can now supply a PEM file containing just certificates and this will be used to validate the server without requiring the OS to recognize the server certificate.
This patch will go into the next release of python-oracledb. Thanks for your patience!
Hi Anthony,
Awesome, thank you! I have tested out the code currently associated to the top of the 'main' branch (commit bb694028), and it works for me / for my use case. Thank you for having taken this in consideration. If I understand properly, this will part of the 1.1.2 version? Or the 1.2.0 version? Is there a way for me to be warned when a new version of this library will be released, or should I just regularly check the state of the repository for this project?
You're welcome. This will likely become part of 1.1.2, but it depends on a number of factors. You can "watch" this repository -- just for new releases if that is all you're interested in!
Nice, did not know about this functionality of github, thank you! Then it's all set, all that's left to do is to wait for the release : )
Should I let you close this issue, once the release has occurred? Or should I do it myself?
I usually add one more comment when the release is made and then close it, but if you prefer to close it now, that's fine, too!
Ok, then no, I would prefer that you do as you usually do : )
This is part of oracledb 1.2.0 which was just released.
Got it, I saw that, now things work great on my end, thank you : ) !
Hi Francois,
I'try to connect to an AWS RDS Oracle Instance but always get get the error mentioned above.
I copied the contents of https://truststore.pki.rds.amazonaws.com/eu-central-1/eu-central-1-bundle.pem into a file called ewallet.pem and set the appropriate wallet_location in the connect method.
But I still get the SSL-Handshake error.
This is my code:
connection = oracledb.connect(user='<usernam>', password=userpwd, host='...', port='..', protocol='tcps', sid='...', ssl_server_dn_match=False, wallet_location='path_to_ewallet_pem')
I'am using oracledb version 1.3.1.
Can you provide a running example please?
Thanks a lot
Hi @rudolfnoe ,
I'm sorry, but I'm not a maintainer of this library, and now that the need that I had opened this issue for has been met, I have forgotten much about it. To solve your issue, I would suggest to perform some experiments and review the documentation, and if that's not enough, then I would suggest opening an issue in this repository, by giving full context and info regarding the experiments that you would have performed.
Hi @FrancoisNoyez, I solved the problem myself. The cause was a mismatch in the available cipher suites. AWS RDS applies the cipher SSL_RSA_WITH_AES_256_CBC_SHA by default which is not available in the default security context of the python SSL library as it assessed as insecure. When changing the RDS Cipher to a more secure one like TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 it works.
Hi @rudolfnoe I see, glad for you! Out of curiosity, how did you do, in order to perform the change of cipher? Is it something that you did within the python code? Or something done in the environment in which the python program runs?
Hi @FrancoisNoyez, see my answer in https://github.com/oracle/python-oracledb/discussions/138
Hi @rudolfnoe Got it, thank you!
Hello @rudolfnoe i have the same error as you can i know what is the final oracledb.connect() string you passed? i did not understand how to use the ssl_context param in the new version
Talking about version 1.1.0.
The current version does not allow to use unencrypted .pem file for mTLS connection, for which the following code, found at line 134 of the 'src/oracledb/impl/thin/crypto.pyx' module, fails in that case:
Things work if we make this code line conditional, for instance on whether a password to decrypt the certificate is actually provided:
Cf this discussion on the forum: something like that is necessary when one is using the Oracle Cloud functionality of the Amazon Cloud service, and notably when one is not admin of the server actually hosting the Oracle database.