summaryrefslogtreecommitdiff
path: root/doc/rvi_certificates.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/rvi_certificates.md')
-rw-r--r--doc/rvi_certificates.md254
1 files changed, 254 insertions, 0 deletions
diff --git a/doc/rvi_certificates.md b/doc/rvi_certificates.md
new file mode 100644
index 0000000..1d46259
--- /dev/null
+++ b/doc/rvi_certificates.md
@@ -0,0 +1,254 @@
+<style type="text/css" media="print"> div.pb { page-break-before: always; } </style>
+Copyright (C) 2015-16 Jaguar Land Rover
+
+This document is licensed under Creative Commons
+Attribution-ShareAlike 4.0 International.
+
+# CREATING RVI CERTIFICATES
+
+This document describes how to generate the necessary certificates,
+keys and credentials needed for RVI Core. The example certificates
+are used in (rvi_protocol.md)[rvi_protocol.md].
+
+# STANDARDS USED
+[1] JSON Web Token RFC7519- JWT (link)[https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32]<br>
+[2] base64url - (link)[https://en.wikipedia.org/wiki/Base64)<br>
+[3] Transport Layer Security (TLS) - (link)[https://en.wikipedia.org/wiki/Transport_Layer_Security]<br>
+[4] X.509 Certificates - (link)[https://en.wikipedia.org/wiki/X.509]<br>
+
+For all examples below the following certificates are used:
+
+## Sample root certificate
+The self signed root certificate used in the examples throughout this
+document was generated using the following commands:
+
+```Shell
+# Create root key pair
+openssl genrsa -out insecure_root_key.pem 1024
+
+# Create a self-signed root CA certificate, signed by the root key created above
+openssl req -x509 -new -nodes -key insecure_root_key.pem -days 365 -out insecure
+_root_cert.crt
+```
+
+The content of the sample ```insecure_root_key.pem``` private key
+file, which has no password protection, is:
+
+```
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDg5A1uZ5F36vQEYbMWCV4wY4OVmicYWEjjl/8YPA01tsz4x68i
+/NnlMNalqpGCIZ0AwqGI5DZAWWoR400L3SAmYD6sWj2L9ViIAPk3ceDU8olYrf/N
+wj78wVoG7qqNLgMoBNM584nlY4jy8zJ0Ka9WFBS2aDtB3Aulc1Q8ZfhuewIDAQAB
+AoGAfD+C7CxsQkSc7I7N0q76SuGwIUc5skmUe6nOViVXZwXH2Or55+qqt+VzsbO7
+EJphk7n0ZR0wm/zKjXd3acaRq5j3fOyXip9fDoNj+oUKAowDJ9vub0NOPpU2bgb0
+xDnDeR0BRVBOTWqrkDeDPBSxw5RlJunesDkamAmj4VXHHgECQQDzqDtaEuEZ7x7d
+kJKCmfGyP01s+YPlquDgogzAeMAsz17TFt8JS4RO0rX71+lmx7qqpRqIxVXIsR58
+NI2Th7tRAkEA7Eh1C1WahLCxojQOam/l7GyE+2ignZYExqonOOvsk6TG0LcFm7W9
+x39ouTlfChM26f8VYAsPxIrvsDlI1DDCCwJBAITmA8lzdrgQhwNOsbrugLg6ct63
+kcuZUqLzgIUS168ZRJ1aYjjNqdLcd0pwT+wxkI03FKv5Bns6sGgKuhX3+KECQFm/
+Z93HRSrTZpViynr5R88WpShNZHyW5/eB1+YSDslB1FagvhuX2570MRXxybys8bXN
+sxPI/9M6prI8AALBBmMCQD+2amH2Y9ukJy10WuYei943mrCsp1oosWjcoMADRCpj
+ZA2UwSzj67PBc5umDIAlhVRMX0zH/gLj54rfIkH5zLk=
+-----END RSA PRIVATE KEY-----
+```
+
+The root key above is checked in as ```priv/keys/insecure_root_key.pem```.
+
+<div class="pb"></div>
+
+The content of the sample ```insecure_root_cert.crt``` file is:
+
+```
+-----BEGIN CERTIFICATE-----
+MIICUjCCAbugAwIBAgIJAMI080XZPsPUMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNV
+BAYTAlVTMQ8wDQYDVQQIDAZPcmVnb24xETAPBgNVBAcMCFBvcnRsYW5kMQ8wDQYD
+VQQKDAZHRU5JVkkwHhcNMTUxMTI3MjMxMTQ0WhcNMTYxMTI2MjMxMTQ0WjBCMQsw
+CQYDVQQGEwJVUzEPMA0GA1UECAwGT3JlZ29uMREwDwYDVQQHDAhQb3J0bGFuZDEP
+MA0GA1UECgwGR0VOSVZJMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDg5A1u
+Z5F36vQEYbMWCV4wY4OVmicYWEjjl/8YPA01tsz4x68i/NnlMNalqpGCIZ0AwqGI
+5DZAWWoR400L3SAmYD6sWj2L9ViIAPk3ceDU8olYrf/Nwj78wVoG7qqNLgMoBNM5
+84nlY4jy8zJ0Ka9WFBS2aDtB3Aulc1Q8ZfhuewIDAQABo1AwTjAdBgNVHQ4EFgQU
+4Sz8rAMA+dHymJTlZSkap65qnfswHwYDVR0jBBgwFoAU4Sz8rAMA+dHymJTlZSka
+p65qnfswDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQDFOapf3DNEcXgp
+1u/g8YtBW24QsyB+RRavA9oKcFiIaHMkbJyUsOergwOXxBYhduuwVzQQo9P5nR0W
+RdUfwtE0GuaiC8WUmjR//vKwakj9Bjuu73ldYj9ji9+eXsL/gtpGWTIlHeGugpFs
+mVrUm0lY/n2ilJQ1hzBZ9lFLq0wfjw==
+-----END CERTIFICATE-----
+```
+
+The root certificate above is checked in as ```priv/certificates/insecure_root_cert.crt```.
+
+
+**DO NOT USE THE KEYS AND CERTIFICATES ABOVE IN PRODUCTION!<br>
+ANY PRODUCTION KEYS SHOULD BE GENERATED BY THE ORGANIZATION AND BE 4096 BITS LONG.**
+
+## Sample device certificate
+
+The sample device x.509 certificate, signed by the root certificate above,
+was generated with the following command:
+
+```Shell
+# Create the device key. In production, increase the bit size to 4096+
+openssl genrsa -out insecure_device_key.pem 1024
+
+# Create a certificate signing request
+openssl req -new -key insecure_device_key.pem -out insecure_device_cert.csr
+
+# Sign the signing request and create the insecure_device_cert.crt file
+openssl x509 -req -days 365 -in insecure_device_cert.csr \
+ -CA insecure_root_cert.crt -CAkey insecure_root_key.pem \
+ -set_serial 01 -out insecure_device_cert.crt
+```
+
+
+The ```insecure_device_cert.csr``` intermediate certificate signing
+request can be deleted once the three steps above have been executed.
+
+<div class="pb"></div>
+
+The content of the sample ```insecure_device_key.pem``` private key
+file, which has no password protection, is:
+
+```
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQCbb4jPAESKxarj3NJsgfQbhfTHZAP9kmram2TFnkzlCRxq4wQx
+BDC0O85PAMgZou0armGGbOu0si4cpVRioerCQJXnMWx1MI+3GUktW5ijI3ui+tYC
+sMQZtjSBVNXFZdoyZU2lPVWITOMZOe8o9vJ5DcUmFj9b2xV9jQ19oh+2+QIDAQAB
+AoGAVCYV0rs6YEaTNbke0k+ocB4dXrTu1CCoaKEn9TS2PGiqUdOFOWQjWe/myS6L
+JhXmd0Ng2P2uvayY+jknbh5qkNeEgTDhXJlAjiXlCADYArhgib+evRHgKz7RLTjX
+tGklbmc7oECTEpjkchJC5XcJhXzHCIjroyOJvBuAVa+SeAECQQDNC+KW7fTKQpiG
+YNGIt5MxCMjRparLz0fWod9J9U56wrWzU9Rnb7h9iwzTEJUEcVl9z8rnUdWtYQ8X
+3lsz5cDhAkEAwg+kDWbLtXWlIvXhhla7q0+RfKb8vu/gXnkXJa6rcJdJztKRbP3b
+9fehVeu9m+1+abahjC1zmQimwd2QVc8BGQJADbtfCGaVPzpoho9TWQmaRO1mrYuf
+vZh7IiejEYvpHpWNn53cmrTDsTyvti7lG/APYzqYRxeW7M6UOS/+AaLAYQJAJbEW
+AwhZPphoB59MO2RzNPXSYyyn4IoEwTSxuz7uy4KG8mXRmyK/a0m6i06rWDLLn8q6
+G9jkH/AfO35GP3RiWQJBAJLWBlKpHf8TxT65jAwxBhd9ZOkC2w0WidbSYjX9wkkD
+38K7ZDm1LSIR69Ut6tdwotkytXvDniOMPY6ENar5IUs=
+-----END RSA PRIVATE KEY-----
+```
+
+The content of the sample ```insecure_device_cert.crt``` file is:
+
+```
+-----BEGIN CERTIFICATE-----
+MIIB8zCCAVwCAQEwDQYJKoZIhvcNAQELBQAwQjELMAkGA1UEBhMCVVMxDzANBgNV
+BAgMBk9yZWdvbjERMA8GA1UEBwwIUG9ydGxhbmQxDzANBgNVBAoMBkdFTklWSTAe
+Fw0xNTExMjcyMzE0NTJaFw0xNjExMjYyMzE0NTJaMEIxCzAJBgNVBAYTAlVTMQ8w
+DQYDVQQIDAZPcmVnb24xETAPBgNVBAcMCFBvcnRsYW5kMQ8wDQYDVQQKDAZHRU5J
+VkkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJtviM8ARIrFquPc0myB9BuF
+9MdkA/2SatqbZMWeTOUJHGrjBDEEMLQ7zk8AyBmi7RquYYZs67SyLhylVGKh6sJA
+lecxbHUwj7cZSS1bmKMje6L61gKwxBm2NIFU1cVl2jJlTaU9VYhM4xk57yj28nkN
+xSYWP1vbFX2NDX2iH7b5AgMBAAEwDQYJKoZIhvcNAQELBQADgYEAhbqVr9E/0M72
+9nc6DI+qgqsRSMfoyvA3Cmn/ECxl1ybGkuzO7sB8fGjgMQ9zzcb6q1uP3wGjPioq
+MymiYYjUmCTvzdvRBZ+6SDjrZfwUuYexiKqI9AP6XKaHlAL14+rK+6HN4uIkZcIz
+PwSMHih1bsTRpyY5Z3CUDcDJkYtVbYs=
+-----END CERTIFICATE-----
+```
+
+These files are checked into ```priv/certificates``` and ```priv/keys```.
+
+**DO NOT USE THE KEYS AND CERTIFICATES ABOVE IN PRODUCTION!<br>
+ANY PRODUCTION KEYS SHOULD BE GENERATED BY THE ORGANIZATION AND BE 4096 BITS LONG.**
+
+<div class="pb"></div>
+
+## RVI credentials format
+
+A credential is a JWT-encoded JSON structure, signed by the root X.509
+certificate's private key, describing the rights that the sender
+has. A received RVI credential is validated as follows.
+
+1. **Receive remote party's X.509 device certificate**<br>
+The TLS handshake process will exchange the X.509 certificates setup in
+the previous chapter.
+
+2. **Validate remote party's X.509 device certificate**<br>
+The received device X.509 certificate has its signature validated by the
+root X.509 certificate that is pre-provisioned in all RVI nodes.<br>
+The receiver now knows that the remote RVI node has an identiy
+generated by a trusted provsioning server using the private root key.
+
+3. **Receive one or more RVI credentials**<br>
+Each credential is encoded as JWT, signed by the root X.509 certificate.
+
+4. **Validate each RVI credential signature**<br>
+The root X.509 certificate is used to validate the signature of each
+received RVI credential. <br>
+A successful validation proves that the certificate was generated by a
+trusted provisioning server using the private root key.
+
+5. **Validate the credential-embedded X.509 device certificate**<br>
+Each received RVI credential will have its embedded device X.509
+certificate compared with the device X.509 certificate received in
+step 1 above.<br>
+A match proves that the certificate was generated by a trusted provisioning
+server explictly for the RVI node at the remote end.
+
+An RVI credential has the following format in its native JSON state:
+
+```JSON
+{
+ "create_timestamp": 1439925416,
+ "right_to_invoke": [
+ "jlr.com/vin/"
+ ],
+ "right_to_register": [
+ "jlr.com/backend/sota"
+ ],
+ "id": "insecure_cert",
+ "iss": "jaguarlandrover.com",
+ "device_cert": "",
+ "validity": {
+ "start": 1420099200,
+ "stop": 1925020799
+ }
+}
+```
+
+<div class="pb"></div>
+
+The members are as follows:
+
+Member | Description
+--------------------|---------------------
+create\_timestamp | Unix timestamp of when the credential was created
+right\_to\_invoke | A list of service prefixes that the sender has the right to invoke on any node that has registered matching services that start with the given string(s).
+right\_to\_register | A list of services that the sender has the right to to register for other nodes to invoke.
+id | A system-wide unique identifier for the credential.
+iss | The issuing organization.
+device_certificate | The PEM-encoded device X.509 certificate to match against the sender's TLS certificate.
+validity.start | The Unix timestamps when the credential becomes active.
+validity.stop | The Unix timestamps when the credential becomes inactive.
+
+## Generating RVI credentials
+
+To create a credential, tie it to a device X.509 certificate, and sign it with a root X.509 certificate private key, the following command is used:
+
+
+```Shell
+rvi_create_credential.py --cred_out="insecure_credential.json" \
+ --jwt_out='insecure_credential.jwt' \
+ --id="xxx" \
+ --issuer="genivi.org" \
+ --root_key=insecure_root_key.pem \
+ --device_cert=insecure_device_cert.crt \
+ --invoke='genivi.org/' \
+ --register='genivi.org/'
+```
+
+The following command line parameters are accepted:
+
+Parameter | Required | Description
+-------------- | -------- | ---------
+--cred\_out | No | Output file containing the JSON-formatted un-encoded credential.
+--jwt\_out | Yes | JWT-encoded, JSON-formatted, root keyp-signed credential.
+--issuer | Yes | Organization that issued the credential.
+--root\_key | Yes | Private, PEM-encoded root key to sign the credential. Must be the same key used to sign the root X.509 certificate.
+--device\_cert | Yes | The PEM-encoded device X.509 certificate to embed into the credential as the device_cert member.
+--invoke | Yes | Space separated list (within quotes) of RVI service prefixes that the owner of the credential has the right to invoke.
+--register | Yes | Space separated list (within quotes) of RVI service prefixes that the owner of the credential has the right to register for others to call (with the right credential).
+--start | No | The Unix timestamps when the credential becomes active.
+--stop | No | The Unix timestamps when the credential becomes inactive.
+
+The generated ```insecure_credential.json```
+and ```insecure_credential.jwt``` are checked into ```priv/credentials```.