2 Documentation Test suite for Securing RESTCONF communication.
3 ... Note this suite requires PycURLLibrary to handle client certificates. While Requests library is able
4 ... to handle server certificates well, it lacks capabilities to deal with client certificates.
5 ... TODO: Investigate the possibility to incorporate this into TemplatedRequests
7 Library OperatingSystem
8 Library RequestsLibrary
11 Resource ../../../libraries/ClusterManagement.robot
12 Resource ../../../variables/Variables.robot
13 Resource ../../../libraries/Utils.robot
14 Resource ../../../libraries/KarafKeywords.robot
15 Resource ../../../libraries/SSHKeywords.robot
17 Suite Setup Init Suite
18 Suite Teardown Cleanup Suite
22 ${RESTCONF_MONITORING_URI} /restconf/operational/ietf-restconf-monitoring:restconf-state
23 ${RESTCONF_MONITORING_URL} https://${ODL_SYSTEM_IP}:${RESTCONFPORT_TLS}${RESTCONF_MONITORING_URI}
27 Basic Unsecure Restconf Request
28 [Documentation] Tests a basic HTTP request, just to ensure that system is working fine with normal, unsecure reqs
29 Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
30 ${resp} RequestsLibrary.GET On Session session ${RESTCONF_MONITORING_URI} expected_status=anything
31 Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
34 TLS on Restconf without Server Cert
35 [Documentation] Tests an HTTPS request towards secure port with ODL secure config deactivated
36 PycURLLibrary.Set Url ${RESTCONF_MONITORING_URL}
37 PycURLLibrary.Add Header "Content-Type:application/json"
38 PycURLLibrary.Add Header Authorization:Basic YWRtaW46YWRtaW4=
39 PycURLLibrary.Request Method GET
40 Run Keyword And Expect Error
41 ... error: (7, 'Failed *${RESTCONFPORT_TLS}* Connection refused')
42 ... PycURLLibrary.Perform
43 PycURLLibrary.Log Response
46 [Documentation] Activates TLS configuration in ODL and restarts Karaf
48 # Check ODL was restarted properly
49 Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
50 ${resp} RequestsLibrary.GET On Session session ${RESTCONF_MONITORING_URI} expected_status=anything
52 Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
54 TLS on Restconf with Server Cert (Self-signed) (insecure)
55 [Documentation] Tests HTTPS request. Server certificate is self-signed, thus communication is insecure
56 Clean Up Certificates In Server
57 Generate Server Self-Signed Certificate
60 PycURLLibrary.Set Url ${RESTCONF_MONITORING_URL}
61 PycURLLibrary.Add Header "Content-Type:application/json"
62 PycURLLibrary.Add Header Authorization:Basic YWRtaW46YWRtaW4=
63 PycURLLibrary.Request Method GET
65 PycURLLibrary.Log Response
66 PycURLLibrary.Response Status Should Contain 200
67 ${resp} PycURLLibrary.Response
70 ... "restconf-state":{"capabilities":{"capability":["urn:ietf:params:restconf:capability:depth
72 TLS on Restconf with Server Cert (CA signed)
73 [Documentation] Tests HTTPS request with ODL TLS config by using CA signed certificates
74 Clean Up Certificates In Server
75 Generate Server CA Signed Certificate
77 PycURLLibrary.Set Url ${RESTCONF_MONITORING_URL}
78 PycURLLibrary.Add Header "Content-Type:application/json"
79 PycURLLibrary.Add Header Authorization:Basic YWRtaW46YWRtaW4=
80 PycURLLibrary.Request Method GET
82 PycURLLibrary.Log Response
83 PycURLLibrary.Response Status Should Contain 200
84 ${resp} PycURLLibrary.Response
87 ... "restconf-state":{"capabilities":{"capability":["urn:ietf:params:restconf:capability:depth
89 Activate Client Authentication
90 [Documentation] Activates client authentication in odl by means of certificates.
91 Enable Client TLS Authentication in ODL
92 # Check ODL was restarted properly
93 Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
94 ${resp} RequestsLibrary.GET On Session session ${RESTCONF_MONITORING_URI} expected_status=anything
96 Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
98 TLS on Restconf with Server & Client Certs (Self-signed)
99 [Documentation] Test HTTPS request with ODL TLS config and client authentication by using certificate
100 Clean Up Certificates In Server
101 Generate Server Self-Signed Certificate
102 Generate Client Self-Signed Certificate
104 PycURLLibrary.Set Url ${RESTCONF_MONITORING_URL}
105 PycURLLibrary.Add Header "Content-Type:application/json"
106 PycURLLibrary.Add Header Authorization:Basic YWRtaW46YWRtaW4=
107 PycURLLibrary.Client Certificate File ${USER_HOME}/clientcert.pem
108 PycURLLibrary.Private Key File ${USER_HOME}/clientkey.pem
109 PycURLLibrary.Request Method GET
110 PycURLLibrary.Perform
111 PycURLLibrary.Log Response
112 PycURLLibrary.Response Status Should Contain 200
113 ${resp} PycURLLibrary.Response
116 ... "restconf-state":{"capabilities":{"capability":["urn:ietf:params:restconf:capability:depth
118 TLS on Restconf with Server & Client Certs (CA signed)
119 [Documentation] Tests HTTPS request with ODL TLS config and client authentication by using CA signed certificates
120 Clean Up Certificates In Server
121 Generate Server CA Signed Certificate
122 Generate Client CA Signed Certificate
124 PycURLLibrary.Set Url ${RESTCONF_MONITORING_URL}
125 PycURLLibrary.Add Header "Content-Type:application/json"
126 PycURLLibrary.Add Header Authorization:Basic YWRtaW46YWRtaW4=
127 PycURLLibrary.Client Certificate File ${USER_HOME}/client_ca_signed-cert.pem
128 PycURLLibrary.Private Key File ${USER_HOME}/client_ca_signed-key.pem
129 PycURLLibrary.Request Method GET
130 PycURLLibrary.Perform
131 PycURLLibrary.Log Response
132 PycURLLibrary.Response Status Should Contain 200
133 ${resp} PycURLLibrary.Response
136 ... "restconf-state":{"capabilities":{"capability":["urn:ietf:params:restconf:capability:depth
138 Restconf HTTPS/TLS Jolokia with server and client certificates CA signed
139 [Documentation] Tests HTTPS request with ODL TLS config and client authentication by using CA signed certificates for Jolokia
140 Clean Up Certificates In Server
141 Generate Server CA Signed Certificate
142 Generate Client CA Signed Certificate
144 PycURLLibrary.Set Url https://${ODL_SYSTEM_IP}:${RESTCONFPORT_TLS}/${JOLOKIA_CONF_SHARD_MANAGER_URI}
145 PycURLLibrary.Add Header "Content-Type:application/json"
146 PycURLLibrary.Add Header Authorization:Basic YWRtaW46YWRtaW4=
147 PycURLLibrary.Client Certificate File ${USER_HOME}/client_ca_signed-cert.pem
148 PycURLLibrary.Private Key File ${USER_HOME}/client_ca_signed-key.pem
149 PycURLLibrary.Request Method GET
150 PycURLLibrary.Perform
151 PycURLLibrary.Log Response
152 PycURLLibrary.Response Status Should Contain 200
153 ${resp} PycURLLibrary.Response
156 ... "request":{"mbean":"org.opendaylight.controller:Category=ShardManager,name=shard-manager-config,type=DistributedConfigDatastore"
160 Log Certificates in Keystore
161 [Documentation] Shows content of keystore
162 ${output} Run Command On Remote System
164 ... ${JAVA_HOME}/bin/keytool -list -storepass 123456 -keystore ${KEYSTORE_PATH}
167 Clean Up Certificates In Server
168 [Documentation] Cleans keystore content (only for private keys and trusted certificates)
169 Log Certificates in Keystore
170 Run Command On Remote System
172 ... ${JAVA_HOME}/bin/keytool -list -keystore ${KEYSTORE_PATH} -storepass 123456|egrep -e "(trustedCertEntry|PrivateKeyEntry)"|cut -d"," -f1|xargs -I[] ${JAVA_HOME}/bin/keytool -delete -alias [] -keystore ${KEYSTORE_PATH} -storepass 123456
173 Log Certificates in Keystore
175 Generate Server Self-Signed Certificate
176 [Documentation] Generates a self-signed certificate, stores it into keystore and restarts jetty to load changes
177 ${KEYSTORE_DIR} Split Path ${KEYSTORE_PATH}
178 Run Command On Remote System ${ODL_SYSTEM_IP} mkdir -p ${KEYSTORE_DIR[0]}
179 Log Certificates in Keystore
180 # Generate with openssl
181 Run Command On Remote System
183 ... openssl req -x509 -newkey rsa:4096 -passout pass:myPass -keyout serverkey.pem -out servercert.pem -days 365 -subj "/C=ES/ST=Madrid/L=Madrid/O=OpenDayLight/OU=AAA/CN=OpenDayLight/emailAddress=unknown@unknown.com"
184 # Convert to pkcs12 (including public and private key together)
185 Run Command On Remote System
187 ... openssl pkcs12 -export -in servercert.pem -inkey serverkey.pem -out server.p12 -name odl -passin pass:myPass -passout pass:myPass
188 # Import Certifcate into keystore
189 Run Command On Remote System
191 ... ${JAVA_HOME}/bin/keytool -importkeystore -deststorepass 123456 -destkeypass myPass -destkeystore ${KEYSTORE_PATH} -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass myPass -alias odl
192 Log Certificates in Keystore
195 Generate Client Self-Signed Certificate
196 [Documentation] Generates a client self-signed certificate, stores it into the keystore (as trusted cert) and
197 ... restarts jettty to load changes
198 ${KEYSTORE_DIR} Split Path ${KEYSTORE_PATH}
199 Run Command On Remote System ${ODL_SYSTEM_IP} mkdir -p ${KEYSTORE_DIR[0]}
200 Log Certificates in Keystore
201 # Generate with openssl
202 # Note -nodes is used to avoid passphrase in private key. Also -passout pass:myPass is skipped. This is due to a
203 # limitation in pycurl library that does not support key pem files with passphrase in automatic mode (it asks for it)
205 ... openssl req -x509 -newkey rsa:4096 -nodes -keyout ${USER_HOME}/clientkey.pem -out ${USER_HOME}/clientcert.pem -days 365 -subj "/C=ES/ST=Madrid/L=Madrid/O=OpenDayLight/OU=AAA/CN=MiguelAngelMunoz/emailAddress=myemail@unknown.com"
206 # Import client's cert as trusted
207 Copy File To Odl System ${ODL_SYSTEM_IP} ${USER_HOME}/clientcert.pem
208 Run Command On Remote System
210 ... ${JAVA_HOME}/bin/keytool -import -trustcacerts -file clientcert.pem -keystore ${KEYSTORE_PATH} -storepass 123456 -noprompt
211 Log Certificates in Keystore
214 Generate Server CA Signed Certificate
215 [Documentation] Generates a server certificate and signs it with own root CA
216 #Generates Root CA key and certificate (note this has to be self-signed)
217 Log Certificates in Keystore
218 Run openssl genrsa -out ${USER_HOME}/rootCA.key 2048
220 ... openssl req -x509 -new -nodes -key ${USER_HOME}/rootCA.key -sha256 -days 1024 -out ${USER_HOME}/rootCA.pem -subj "/C=ES/ST=Madrid/L=Madrid/O=FakeCA/OU=FakeCA_ODL/CN=www.fakeca.com/emailAddress=unknown@fakeca.com"
222 Run openssl genrsa -out ${USER_HOME}/server.key 2048
224 ... openssl req -new -key ${USER_HOME}/server.key -out ${USER_HOME}/server.csr -subj "/C=ES/ST=Madrid/L=Madrid/O=OpenDayLight/OU=AAA/CN=${ODL_SYSTEM_IP}/emailAddress=unknown@unknown.com"
227 ... openssl x509 -req -in ${USER_HOME}/server.csr -CA ${USER_HOME}/rootCA.pem -CAkey ${USER_HOME}/rootCA.key -CAcreateserial -out ${USER_HOME}/server.crt -days 500 -sha256
228 # Convert to pkcs12 (including public and private key together)
230 ... openssl pkcs12 -export -in ${USER_HOME}/server.crt -inkey ${USER_HOME}/server.key -out ${USER_HOME}/server.p12 -name odl -passin pass:myPass -passout pass:myPass
231 Copy File To Odl System ${ODL_SYSTEM_IP} ${USER_HOME}/server.p12
232 # Import Certifcate into keystore
233 ${KEYSTORE_DIR} Split Path ${KEYSTORE_PATH}
234 Run Command On Remote System ${ODL_SYSTEM_IP} mkdir -p ${KEYSTORE_DIR[0]}
235 Run Command On Remote System
237 ... ${JAVA_HOME}/bin/keytool -importkeystore -deststorepass 123456 -destkeypass myPass -destkeystore ${KEYSTORE_PATH} -srckeystore ${USER_HOME}/server.p12 -srcstoretype PKCS12 -srcstorepass myPass -alias odl
238 Log Certificates in Keystore
241 Generate Client CA Signed Certificate
242 [Documentation] Generates a client certificate and signs it with own root CA
243 #Generates Root CA key and certificate (note this has to be self-signed)
244 Log Certificates in Keystore
245 Run openssl genrsa -out ${USER_HOME}/rootCA_for_clients-key.pem 2048
247 ... openssl req -x509 -new -nodes -key ${USER_HOME}/rootCA_for_clients-key.pem -sha256 -days 1024 -out ${USER_HOME}/rootCA_for_clients-cert.pem -subj "/C=ES/ST=Madrid/L=Madrid/O=FakeCA_ForClient/OU=FakeCA_ForClient/CN=www.fakecaforclients.com/emailAddress=unknown@fakecaforclients.com"
249 Run openssl genrsa -out ${USER_HOME}/client_ca_signed-key.pem 2048
251 ... openssl req -new -key ${USER_HOME}/client_ca_signed-key.pem -out ${USER_HOME}/client_ca_signed.csr -subj "/C=ES/ST=Madrid/L=Madrid/O=OpenDayLight/OU=RestClient/CN=RestClient/emailAddress=unknown@unknownclient.com"
254 ... openssl x509 -req -in ${USER_HOME}/client_ca_signed.csr -CA ${USER_HOME}/rootCA_for_clients-cert.pem -CAkey ${USER_HOME}/rootCA_for_clients-key.pem -CAcreateserial -out ${USER_HOME}/client_ca_signed-cert.pem -days 500 -sha256
255 Copy File To Odl System ${ODL_SYSTEM_IP} ${USER_HOME}/rootCA_for_clients-cert.pem
256 # Import RootCA Certifcate into keystore
257 ${KEYSTORE_DIR} Split Path ${KEYSTORE_PATH}
258 Run Command On Remote System ${ODL_SYSTEM_IP} mkdir -p ${KEYSTORE_DIR[0]}
259 Run Command On Remote System
261 ... ${JAVA_HOME}/bin/keytool -import -trustcacerts -file rootCA_for_clients-cert.pem -keystore ${KEYSTORE_PATH} -storepass 123456 -noprompt
262 Log Certificates in Keystore
266 [Documentation] Remove TLS configuration in custom.properties
267 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.osgi.service.http.secure.enabled=/d' ${CUSTOMPROP}
268 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.keystore=/d' ${CUSTOMPROP}
269 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.password=/d' ${CUSTOMPROP}
270 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.keypassword=/d' ${CUSTOMPROP}
271 Run Command On Remote System
273 ... sed -i '/org.ops4j.pax.web.ssl.clientauthneeded=/d' ${CUSTOMPROP}
277 [Documentation] Add new secure configuration in custom.properties
278 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.osgi.service.http.secure.enabled=/d' ${CUSTOMPROP}
279 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.keystore=/d' ${CUSTOMPROP}
280 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.password=/d' ${CUSTOMPROP}
281 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.keypassword=/d' ${CUSTOMPROP}
282 Run Command On Remote System
284 ... sed -i '/org.ops4j.pax.web.ssl.clientauthneeded=/d' ${CUSTOMPROP}
285 Run Command On Remote System
287 ... echo "org.osgi.service.http.secure.enabled=true">> ${CUSTOMPROP}
288 Run Command On Remote System
290 ... echo "org.ops4j.pax.web.ssl.keystore=${KEYSTORE_RELATIVE_PATH}">> ${CUSTOMPROP}
291 Run Command On Remote System ${ODL_SYSTEM_IP} echo "org.ops4j.pax.web.ssl.password=myPass">> ${CUSTOMPROP}
292 Run Command On Remote System ${ODL_SYSTEM_IP} echo "org.ops4j.pax.web.ssl.keypassword=123456">> ${CUSTOMPROP}
295 Enable Client TLS Authentication in ODL
296 [Documentation] Add custom.properties configuration to enable client auth
297 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.osgi.service.http.secure.enabled=/d' ${CUSTOMPROP}
298 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.keystore=/d' ${CUSTOMPROP}
299 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.password=/d' ${CUSTOMPROP}
300 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.keypassword=/d' ${CUSTOMPROP}
301 Run Command On Remote System
303 ... sed -i '/org.ops4j.pax.web.ssl.clientauthneeded=/d' ${CUSTOMPROP}
304 Run Command On Remote System
306 ... echo "org.osgi.service.http.secure.enabled=true">> ${CUSTOMPROP}
307 Run Command On Remote System
309 ... echo "org.ops4j.pax.web.ssl.keystore=${KEYSTORE_RELATIVE_PATH}">> ${CUSTOMPROP}
310 Run Command On Remote System ${ODL_SYSTEM_IP} echo "org.ops4j.pax.web.ssl.password=myPass">> ${CUSTOMPROP}
311 Run Command On Remote System ${ODL_SYSTEM_IP} echo "org.ops4j.pax.web.ssl.keypassword=123456">> ${CUSTOMPROP}
312 Run Command On Remote System
314 ... echo "org.ops4j.pax.web.ssl.clientauthneeded=true">> ${CUSTOMPROP}
318 [Documentation] Cleans TLS configuration and restart Karaf system to reload
319 KarafKeywords.Setup Karaf Keywords
320 Clean Up Certificates In Server
322 Install a Feature odl-jolokia
325 [Documentation] Deletes pending sessions in case there were any