OpenLEADR / openleadr-python

Python library for OpenADR
https://openleadr.org/docs
Apache License 2.0
133 stars 51 forks source link

help with TLS #78

Closed bbartling closed 3 years ago

bbartling commented 3 years ago

If I use to generate a certificate + private key pair, with the following command on Linux:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

This will generate two files (key.pem and cert.pem) and require myself to input a passphrase that encrypts/decrypts the private key; can someone give me a hint how to generate a ca .cert? Beginner level explanation from the documentation in the quote below that I understand at a high level. I am trying to follow:

messages should ideally be signed using an X509 certificate keypair. This allows both parties to verify that the message came from the correct party, and that it was not tampered with in transport. It does not provide message encryption; for that, a transport-level encryption (TLS) should be used

In the git repo, if I run generate_certs.sh on my local git clone in the virtual env I see all of the files generated:

image

I can make this framework communication work with HTTP but I am a bit confused on what all is need for TLS HTTPS where there is some information on message signing.

When I configure the server/client apps, what do I all need to include for TLS security and I think also application level security as I think open ADR certs are used for authentication as well...? The generate_certs.sh doesn't prompt for a passphrase.

For the server if I use this configuration below:

# Create the server object
server = OpenADRServer(vtn_id='cloud_vtn_tls',
                       http_host='0.0.0.0',
                       cert='./certificates/dummy_vtn.pem',
                       key='./certificates/dummy_vtn.pem',
                       http_cert='./certificates/dummy_vtn.pem',
                       http_key='./certificates/dummy_vtn.pem',
                       ven_lookup=ven_lookup_function,
                       http_ca_file='./certificates/dummy_ca.crt',
                       )

And client:

# Create the client object
client = OpenADRClient(ven_name='dan_ven1',
                         vtn_url='https://11.12.13.14:8080/OpenADR2/Simple/2.0b',
                         cert='./certificates/dummy_ven.crt',
                         key='./certificates/dummy_ven.key',
                         ca_file='./certificates/dummy_ca.crt',
                         vtn_fingerprint='59:4D:D8:CD:35:8E:E7:F7:86:94')

When I run the server script this will error out as I think I am missing the passphrase, but how to generate a passphrase with generate_certs.sh:

(python_env) bbartling@localhost:/var/lib/openleadr-python$ python vtntestcerts.py
Traceback (most recent call last):
  File "/var/lib/openleadr-python/vtntestcerts.py", line 59, in <module>
    server = OpenADRServer(vtn_id='cloud_vtn_tls',
  File "/var/lib/openleadr-python/openleadr/server.py", line 109, in __init__
    self.ssl_context.load_cert_chain(http_cert, http_key, http_key_passphrase)
FileNotFoundError: [Errno 2] No such file or directory

Any tips greatly appreciated. It seems like I am missing a passphrase but the generate_certs.sh doesnt prompt for one. I also dont know what I need to do for the "Please make sure the line RANDFILE = ... is commented out in your /etc/ssl/openssl.conf." message either.

00javad00 commented 3 years ago

Seems there are two mistakes in your OpenADRServer session: 1) you assigned a wrong path of /certificates/dummy_vtn.pem to all of http_cert, http_key, VTN's key and cert, and 2) more importantly there is no pem file in the directory. Note that you may use pem files, but the best practice is using two pems for https session and VTN server. The first pem is for https encryption and the latter is for authentication.

bbartling commented 3 years ago

@00javad00 thanks for all the info, any chance you could help me further? Sorry I am junior level at best with web development which I am learning, my work experience is all HVAC system PLC logic building automation technician work that is completely different than writing code.

What would be the correct path to all my certs, key, and http cert? Or how would I fix that? Curious to see how you spotted that error.

I understand at a high level for open ADR TLS is the transport layer security but open ADR also uses certs for authentication of VEN to VTN too which I think is like application level security. I think that is what you mean by this below where I should have to separate certs/pems one for authentication and one for TLS:

The first pem is for https encryption and the latter is for authentication.

Some tutorial to point me in the direction would be great, or if a response could be dummed down to my level of understanding I think I could finally get it. For example:

  1. In your VEN certs directory run the open SSL command ........ to generate pem, key, ca, etc....
  2. Start your VEN and copy the fingerprint
  3. On your VTN certs directory run the open SSL command ........... to generate pem, key, ca, etc....
  4. Paste VEN finger print into your VEN lookup dictionary
  5. Start VTN

Thanks for any help and tips greatly appreciated...

00javad00 commented 3 years ago

1- Read the entire of this thread to get a better understanding over path in python. 2- The shared screenshot of your directory shows the folder doesn't contain any pem file. 3- For the security files, you may ignore CA certificate for testing (eventually it depends to VTN owner policy and the CA root requirements) and download the official OpenADR certificates from Kyrio. If you are running VTN and VEN, then you would need a separate certificate for each. 4- Fingerprint will be generated automatically via fingerprint.py service. 5- Before starting VTN or VEN make sure you can read certificate files from your API.

import os.path
if os.path.exists(PATH_TO_CERT_FILE): # replace the path here
  print("Path exists")

6- last but not least, there are tons of online free python courses, try to read and learn...being solution maker is more valuable than being a solution finder. Hope it helps

bbartling commented 3 years ago

@00javad00 Thanks for the all tips! I totally understand what you say about being a solution maker! That takes a lot of experience to get to that level, wow.

When I download VEN & VTN certs (separately for VEN & VTN) from Kyro in pem format, there is a couple different files that come inside the .zip

Would I just need the _privkey.pem and _cert.pem? For example on the client to test with TLS:

client = OpenADRClient(ven_name='ven1',
                         vtn_url='https://192.168.0.105:8080/OpenADR2/Simple/2.0b',
                         cert='./certificates/TEST_RSA_VEN_cert.pem',
                         key='./certificates/TEST_RSA_VEN_privkey.pem',
                         vtn_fingerprint='2E:EF:3B:A4:29:71:96:D7:2E:C7')

And server something like this with the Kyro certs:

# Create the server object
server = OpenADRServer(vtn_id='vtn_tls',
                       http_host='0.0.0.0',
                       cert='./certificates/TEST_RSA_VTN_cert.pem',
                       key='./certificates/TEST_RSA_VTN_privkey.pem',
                       ven_lookup=ven_lookup_function
                       )

On the client side, Ill get an error:

Could not connect to server with URL https://194.195.214.85:8080/OpenADR2/Simple/2.0b:
ClientConnectorSSLError: Cannot connect to host 194.195.214.85:8080 ssl:default [[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1129)]
No VEN ID received from the VTN, aborting
00javad00 commented 3 years ago

1-How about http_cert and http_key on the server side? 2- Make sure the vtn_fingerprint is matched with the server fingerprint, and 3- The vtn_url IP is set to 192.168.0.105 but the log shows the client is pointing to 194.195.214.85