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 Suite Teardown Cleanup Suite
8 Library OperatingSystem
9 Library RequestsLibrary
12 Resource ../../../libraries/ClusterManagement.robot
13 Resource ../../../variables/Variables.robot
14 Resource ../../../libraries/Utils.robot
15 Resource ../../../libraries/KarafKeywords.robot
16 Resource ../../../libraries/SSHKeywords.robot
19 ${RESTCONF_MONITORING_URI} /restconf/operational/ietf-restconf-monitoring:restconf-state
20 ${RESTCONF_MONITORING_URL} https://${ODL_SYSTEM_IP}:${RESTCONFPORT_TLS}${RESTCONF_MONITORING_URI}
23 Basic Unsecure Restconf Request
24 [Documentation] Tests a basic HTTP request, just to ensure that system is working fine with normal, unsecure reqs
25 Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
26 ${resp} RequestsLibrary.Get Request session ${RESTCONF_MONITORING_URI}
27 Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
30 TLS on Restconf without Server Cert
31 [Documentation] Tests an HTTPS request towards secure port with ODL secure config deactivated
32 PycURLLibrary.Set Url ${RESTCONF_MONITORING_URL}
33 PycURLLibrary.Add Header "Content-Type:application/json"
34 PycURLLibrary.Add Header Authorization:Basic YWRtaW46YWRtaW4=
35 PycURLLibrary.Request Method GET
36 Run Keyword And Expect Error error: (7, 'Failed *${RESTCONFPORT_TLS}* Connection refused') PycURLLibrary.Perform
37 PycURLLibrary.Log Response
40 [Documentation] Activates TLS configuration in ODL and restarts Karaf
42 # Check ODL was restarted properly
43 Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
44 ${resp} RequestsLibrary.Get Request session ${RESTCONF_MONITORING_URI}
46 Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
48 TLS on Restconf with Server Cert (Self-signed) (insecure)
49 [Documentation] Tests HTTPS request. Server certificate is self-signed, thus communication is insecure
50 Clean Up Certificates In Server
51 Generate Server Self-Signed Certificate
54 PycURLLibrary.Set Url ${RESTCONF_MONITORING_URL}
55 PycURLLibrary.Add Header "Content-Type:application/json"
56 PycURLLibrary.Add Header Authorization:Basic YWRtaW46YWRtaW4=
57 PycURLLibrary.Request Method GET
59 PycURLLibrary.Log Response
60 PycURLLibrary.Response Status Should Contain 200
61 ${resp} PycURLLibrary.Response
62 Should Contain ${resp} "restconf-state":{"capabilities":{"capability":["urn:ietf:params:restconf:capability:depth
64 TLS on Restconf with Server Cert (CA signed)
65 [Documentation] Tests HTTPS request with ODL TLS config by using CA signed certificates
66 Clean Up Certificates In Server
67 Generate Server CA Signed Certificate
69 PycURLLibrary.Set Url ${RESTCONF_MONITORING_URL}
70 PycURLLibrary.Add Header "Content-Type:application/json"
71 PycURLLibrary.Add Header Authorization:Basic YWRtaW46YWRtaW4=
72 PycURLLibrary.Request Method GET
74 PycURLLibrary.Log Response
75 PycURLLibrary.Response Status Should Contain 200
76 ${resp} PycURLLibrary.Response
77 Should Contain ${resp} "restconf-state":{"capabilities":{"capability":["urn:ietf:params:restconf:capability:depth
79 Activate Client Authentication
80 [Documentation] Activates client authentication in odl by means of certificates.
81 Enable Client TLS Authentication in ODL
82 # Check ODL was restarted properly
83 Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
84 ${resp} RequestsLibrary.Get Request session ${RESTCONF_MONITORING_URI}
86 Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
88 TLS on Restconf with Server & Client Certs (Self-signed)
89 [Documentation] Test HTTPS request with ODL TLS config and client authentication by using certificate
90 Clean Up Certificates In Server
91 Generate Server Self-Signed Certificate
92 Generate Client Self-Signed Certificate
94 PycURLLibrary.Set Url ${RESTCONF_MONITORING_URL}
95 PycURLLibrary.Add Header "Content-Type:application/json"
96 PycURLLibrary.Add Header Authorization:Basic YWRtaW46YWRtaW4=
97 PycURLLibrary.Client Certificate File ${USER_HOME}/clientcert.pem
98 PycURLLibrary.Private Key File ${USER_HOME}/clientkey.pem
99 PycURLLibrary.Request Method GET
100 PycURLLibrary.Perform
101 PycURLLibrary.Log Response
102 PycURLLibrary.Response Status Should Contain 200
103 ${resp} PycURLLibrary.Response
104 Should Contain ${resp} "restconf-state":{"capabilities":{"capability":["urn:ietf:params:restconf:capability:depth
106 TLS on Restconf with Server & Client Certs (CA signed)
107 [Documentation] Tests HTTPS request with ODL TLS config and client authentication by using CA signed certificates
108 Clean Up Certificates In Server
109 Generate Server CA Signed Certificate
110 Generate Client CA Signed Certificate
112 PycURLLibrary.Set Url ${RESTCONF_MONITORING_URL}
113 PycURLLibrary.Add Header "Content-Type:application/json"
114 PycURLLibrary.Add Header Authorization:Basic YWRtaW46YWRtaW4=
115 PycURLLibrary.Client Certificate File ${USER_HOME}/client_ca_signed-cert.pem
116 PycURLLibrary.Private Key File ${USER_HOME}/client_ca_signed-key.pem
117 PycURLLibrary.Request Method GET
118 PycURLLibrary.Perform
119 PycURLLibrary.Log Response
120 PycURLLibrary.Response Status Should Contain 200
121 ${resp} PycURLLibrary.Response
122 Should Contain ${resp} "restconf-state":{"capabilities":{"capability":["urn:ietf:params:restconf:capability:depth
124 Restconf HTTPS/TLS Jolokia with server and client certificates CA signed
125 [Documentation] Tests HTTPS request with ODL TLS config and client authentication by using CA signed certificates for Jolokia
126 Clean Up Certificates In Server
127 Generate Server CA Signed Certificate
128 Generate Client CA Signed Certificate
130 PycURLLibrary.Set Url https://${ODL_SYSTEM_IP}:${RESTCONFPORT_TLS}/${JOLOKIA_CONF_SHARD_MANAGER_URI}
131 PycURLLibrary.Add Header "Content-Type:application/json"
132 PycURLLibrary.Add Header Authorization:Basic YWRtaW46YWRtaW4=
133 PycURLLibrary.Client Certificate File ${USER_HOME}/client_ca_signed-cert.pem
134 PycURLLibrary.Private Key File ${USER_HOME}/client_ca_signed-key.pem
135 PycURLLibrary.Request Method GET
136 PycURLLibrary.Perform
137 PycURLLibrary.Log Response
138 PycURLLibrary.Response Status Should Contain 200
139 ${resp} PycURLLibrary.Response
140 Should Contain ${resp} "request":{"mbean":"org.opendaylight.controller:Category=ShardManager,name=shard-manager-config,type=DistributedConfigDatastore"
143 Log Certificates in Keystore
144 [Documentation] Shows content of keystore
145 ${output} Run Command On Remote System ${ODL_SYSTEM_IP} ${JAVA_HOME}/bin/keytool -list -storepass 123456 -keystore ${KEYSTORE_PATH}
148 Clean Up Certificates In Server
149 [Documentation] Cleans keystore content (only for private keys and trusted certificates)
150 Log Certificates in Keystore
151 Run Command On Remote System ${ODL_SYSTEM_IP} ${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
152 Log Certificates in Keystore
154 Generate Server Self-Signed Certificate
155 [Documentation] Generates a self-signed certificate, stores it into keystore and restarts jetty to load changes
156 ${KEYSTORE_DIR}= Split Path ${KEYSTORE_PATH}
157 Run Command On Remote System ${ODL_SYSTEM_IP} mkdir -p ${KEYSTORE_DIR[0]}
158 Log Certificates in Keystore
159 # Generate with openssl
160 Run Command On Remote System ${ODL_SYSTEM_IP} 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"
161 # Convert to pkcs12 (including public and private key together)
162 Run Command On Remote System ${ODL_SYSTEM_IP} openssl pkcs12 -export -in servercert.pem -inkey serverkey.pem -out server.p12 -name odl -passin pass:myPass -passout pass:myPass
163 # Import Certifcate into keystore
164 Run Command On Remote System ${ODL_SYSTEM_IP} ${JAVA_HOME}/bin/keytool -importkeystore -deststorepass 123456 -destkeypass myPass -destkeystore ${KEYSTORE_PATH} -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass myPass -alias odl
165 Log Certificates in Keystore
168 Generate Client Self-Signed Certificate
169 [Documentation] Generates a client self-signed certificate, stores it into the keystore (as trusted cert) and
170 ... restarts jettty to load changes
171 ${KEYSTORE_DIR}= Split Path ${KEYSTORE_PATH}
172 Run Command On Remote System ${ODL_SYSTEM_IP} mkdir -p ${KEYSTORE_DIR[0]}
173 Log Certificates in Keystore
174 # Generate with openssl
175 # Note -nodes is used to avoid passphrase in private key. Also -passout pass:myPass is skipped. This is due to a
176 # limitation in pycurl library that does not support key pem files with passphrase in automatic mode (it asks for it)
177 Run 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"
178 # Import client's cert as trusted
179 Copy File To Odl System ${ODL_SYSTEM_IP} ${USER_HOME}/clientcert.pem
180 Run Command On Remote System ${ODL_SYSTEM_IP} ${JAVA_HOME}/bin/keytool -import -trustcacerts -file clientcert.pem -keystore ${KEYSTORE_PATH} -storepass 123456 -noprompt
181 Log Certificates in Keystore
184 Generate Server CA Signed Certificate
185 [Documentation] Generates a server certificate and signs it with own root CA
186 #Generates Root CA key and certificate (note this has to be self-signed)
187 Log Certificates in Keystore
188 Run openssl genrsa -out ${USER_HOME}/rootCA.key 2048
189 Run 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"
191 Run openssl genrsa -out ${USER_HOME}/server.key 2048
192 Run 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"
194 Run 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
195 # Convert to pkcs12 (including public and private key together)
196 Run 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
197 Copy File To Odl System ${ODL_SYSTEM_IP} ${USER_HOME}/server.p12
198 # Import Certifcate into keystore
199 ${KEYSTORE_DIR}= Split Path ${KEYSTORE_PATH}
200 Run Command On Remote System ${ODL_SYSTEM_IP} mkdir -p ${KEYSTORE_DIR[0]}
201 Run Command On Remote System ${ODL_SYSTEM_IP} ${JAVA_HOME}/bin/keytool -importkeystore -deststorepass 123456 -destkeypass myPass -destkeystore ${KEYSTORE_PATH} -srckeystore ${USER_HOME}/server.p12 -srcstoretype PKCS12 -srcstorepass myPass -alias odl
202 Log Certificates in Keystore
205 Generate Client CA Signed Certificate
206 [Documentation] Generates a client certificate and signs it with own root CA
207 #Generates Root CA key and certificate (note this has to be self-signed)
208 Log Certificates in Keystore
209 Run openssl genrsa -out ${USER_HOME}/rootCA_for_clients-key.pem 2048
210 Run 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"
212 Run openssl genrsa -out ${USER_HOME}/client_ca_signed-key.pem 2048
213 Run 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"
215 Run 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
216 Copy File To Odl System ${ODL_SYSTEM_IP} ${USER_HOME}/rootCA_for_clients-cert.pem
217 # Import RootCA Certifcate into keystore
218 ${KEYSTORE_DIR}= Split Path ${KEYSTORE_PATH}
219 Run Command On Remote System ${ODL_SYSTEM_IP} mkdir -p ${KEYSTORE_DIR[0]}
220 Run Command On Remote System ${ODL_SYSTEM_IP} ${JAVA_HOME}/bin/keytool -import -trustcacerts -file rootCA_for_clients-cert.pem -keystore ${KEYSTORE_PATH} -storepass 123456 -noprompt
221 Log Certificates in Keystore
225 [Documentation] Remove TLS configuration in custom.properties
226 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.osgi.service.http.secure.enabled=/d' ${CUSTOMPROP}
227 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.keystore=/d' ${CUSTOMPROP}
228 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.password=/d' ${CUSTOMPROP}
229 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.keypassword=/d' ${CUSTOMPROP}
230 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.clientauthneeded=/d' ${CUSTOMPROP}
234 [Documentation] Add new secure configuration in custom.properties
235 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.osgi.service.http.secure.enabled=/d' ${CUSTOMPROP}
236 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.keystore=/d' ${CUSTOMPROP}
237 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.password=/d' ${CUSTOMPROP}
238 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.keypassword=/d' ${CUSTOMPROP}
239 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.clientauthneeded=/d' ${CUSTOMPROP}
240 Run Command On Remote System ${ODL_SYSTEM_IP} echo "org.osgi.service.http.secure.enabled=true">> ${CUSTOMPROP}
241 Run Command On Remote System ${ODL_SYSTEM_IP} echo "org.ops4j.pax.web.ssl.keystore=${KEYSTORE_RELATIVE_PATH}">> ${CUSTOMPROP}
242 Run Command On Remote System ${ODL_SYSTEM_IP} echo "org.ops4j.pax.web.ssl.password=myPass">> ${CUSTOMPROP}
243 Run Command On Remote System ${ODL_SYSTEM_IP} echo "org.ops4j.pax.web.ssl.keypassword=123456">> ${CUSTOMPROP}
246 Enable Client TLS Authentication in ODL
247 [Documentation] Add custom.properties configuration to enable client auth
248 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.osgi.service.http.secure.enabled=/d' ${CUSTOMPROP}
249 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.keystore=/d' ${CUSTOMPROP}
250 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.password=/d' ${CUSTOMPROP}
251 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.keypassword=/d' ${CUSTOMPROP}
252 Run Command On Remote System ${ODL_SYSTEM_IP} sed -i '/org.ops4j.pax.web.ssl.clientauthneeded=/d' ${CUSTOMPROP}
253 Run Command On Remote System ${ODL_SYSTEM_IP} echo "org.osgi.service.http.secure.enabled=true">> ${CUSTOMPROP}
254 Run Command On Remote System ${ODL_SYSTEM_IP} echo "org.ops4j.pax.web.ssl.keystore=${KEYSTORE_RELATIVE_PATH}">> ${CUSTOMPROP}
255 Run Command On Remote System ${ODL_SYSTEM_IP} echo "org.ops4j.pax.web.ssl.password=myPass">> ${CUSTOMPROP}
256 Run Command On Remote System ${ODL_SYSTEM_IP} echo "org.ops4j.pax.web.ssl.keypassword=123456">> ${CUSTOMPROP}
257 Run Command On Remote System ${ODL_SYSTEM_IP} echo "org.ops4j.pax.web.ssl.clientauthneeded=true">> ${CUSTOMPROP}
261 [Documentation] Cleans TLS configuration and restart Karaf system to reload
262 KarafKeywords.Setup Karaf Keywords
263 Clean Up Certificates In Server
265 Install a Feature odl-jolokia
268 [Documentation] Deletes pending sessions in case there were any