Add TLS testing to nbd-tester-client.c
authorAlex Bligh <alex@alex.org.uk>
Mon, 11 Apr 2016 16:46:35 +0000 (17:46 +0100)
committerWouter Verhelst <w@uter.be>
Thu, 3 Nov 2016 18:07:41 +0000 (19:07 +0100)
This commit adds TLS testing to nbd-tester-client and 'make check'.
If TLS is not compiled in, then the test is skipped.

Signed-off-by: Alex Bligh <alex@alex.org.uk>
(cherry picked from commit 48065afaa8dee3eda6221660200ac473becf5c0e)
[wouter: update to make it apply in the face of handshake test]
Signed-off-by: Wouter Verhelst <w@uter.be>
14 files changed:
nbd.h
tests/run/Makefile.am
tests/run/certs/README.md [new file with mode: 0644]
tests/run/certs/ca-cert.pem [new file with mode: 0644]
tests/run/certs/ca-key.pem [new file with mode: 0644]
tests/run/certs/ca.info [new file with mode: 0644]
tests/run/certs/client-cert.pem [new file with mode: 0644]
tests/run/certs/client-key.pem [new file with mode: 0644]
tests/run/certs/client.info [new file with mode: 0644]
tests/run/certs/server-cert.pem [new file with mode: 0644]
tests/run/certs/server-key.pem [new file with mode: 0644]
tests/run/certs/server.info [new file with mode: 0644]
tests/run/nbd-tester-client.c
tests/run/simple_test

diff --git a/nbd.h b/nbd.h
index 732c605..90c97a6 100644 (file)
--- a/nbd.h
+++ b/nbd.h
@@ -59,6 +59,8 @@ enum {
 #define NBD_REPLY_MAGIC 0x67446698
 /* Do *not* use magics: 0x12560953 0x96744668. */
 
+#define NBD_OPT_REPLY_MAGIC 0x3e889045565a9LL
+
 /*
  * This is the packet used for communication between client and
  * server. All data are in network byte order.
index bc05321..7f4e4b1 100644 (file)
@@ -1,6 +1,11 @@
+if GNUTLS
+TLSSRC = $(top_srcdir)/crypto-gnutls.c $(top_srcdir)/crypto-gnutls.h $(top_srcdir)/buffer.c $(top_srcdir)/buffer.h
+else
+TLSSRC =
+endif
 TESTS_ENVIRONMENT=$(srcdir)/simple_test
 TESTS = cfg1 cfgmulti cfgnew cfgsize write flush integrity dirconfig list \
-       rowrite tree rotree unix integrityhuge handshake
+       rowrite tree rotree unix integrityhuge handshake tls tlshuge
 check_PROGRAMS = nbd-tester-client
 ## Various Automake versions don't play nice with files in parent
 ## directories, so instead work with a local copy
@@ -20,7 +25,7 @@ endif
 nbd_tester_client_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@
 nbd_tester_client_CPPFLAGS = -I$(top_srcdir)
 nbd_tester_client_LDADD = @GLIB_LIBS@
-EXTRA_DIST = integrity-test.tr integrityhuge-test.tr simple_test
+EXTRA_DIST = integrity-test.tr integrityhuge-test.tr simple_test certs/client-key.pem certs/client-cert.pem certs/server-cert.pem certs/ca-cert.pem certs/ca.info certs/client.info certs/server-key.pem certs/ca-key.pem certs/server.info certs/README.md
 cfg1:
 cfgmulti:
 cfgnew:
@@ -36,3 +41,5 @@ tree:
 rotree:
 unix:
 handshake:
+tls:
+tlshuge:
diff --git a/tests/run/certs/README.md b/tests/run/certs/README.md
new file mode 100644 (file)
index 0000000..3a57c82
--- /dev/null
@@ -0,0 +1,69 @@
+This directory contains test certificates used for NBD's test suite.
+
+They are:
+
+* `client-key.pem` - client private key
+* `client-cert.pem` - client public key
+* `server-key.pem` - server private key
+* `server-cert.pem` - server public key
+* `ca-key.pem` - certificate authority private key
+* `ca-cert.pem` - certificate authority public key
+
+The `*.info` files are generated using the procedure below.
+
+Certificates can be made using the procedure at: https://qemu.weilnetz.de/qemu-doc.html
+using GnuTLS's certtool tool.
+
+Here's how:
+
+First make a CA:
+
+    # certtool --generate-privkey > ca-key.pem
+
+And give it a public key:
+
+    # cat > ca.info <<EOF
+    cn = Name of your organization
+    ca
+    cert_signing_key
+    EOF
+    # certtool --generate-self-signed --load-privkey ca-key.pem --template ca.info --outfile ca-cert.pem
+
+Next issue a server certificate:
+
+    # cat > server.info <<EOF
+    organization = Name of your organization
+    cn = server.foo.example.com
+    tls_www_server
+    encryption_key
+    signing_key
+    EOF
+    # certtool --generate-privkey > server-key.pem
+    # certtool --generate-certificate --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem --load-privkey server-key.pem --template server.info --outfile server-cert.pem
+
+Note the `cn` needs to match the hostname that nbd-client uses to connect (or the hostname specified with `-H` on the command line).
+
+And finally issue a client certificate:
+
+    # cat > client.info <<EOF
+    country = GB
+    state = London
+    locality = London
+    organization = Name of your organization
+    cn = client.foo.example.com
+    tls_www_client
+    encryption_key
+    signing_key
+    EOF
+    # certtool --generate-privkey > client-key.pem
+    # certtool --generate-certificate --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem --load-privkey client-key.pem --template client.info --outfile client-cert.pem
+
+
+In contrast to the other files in this repository, the contents of this directory
+are not licensed under the GPLv2. To the extent possible by applicable law, I
+hereby waive all copyright and related or neighboring rights to the files in this
+directory and release them into the public domain.
+
+The purpose of releasing this into the public domain is to allow
+competing implementations of the NBD protocol without those
+implementations being considered derivative implementations.
diff --git a/tests/run/certs/ca-cert.pem b/tests/run/certs/ca-cert.pem
new file mode 100644 (file)
index 0000000..17d696d
--- /dev/null
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDSzCCAgOgAwIBAgIEVxYYwDANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwpB
+bGV4IEJsaWdoMB4XDTE2MDQxOTExMzg0MFoXDTI2MDQxNzExMzg0MFowFTETMBEG
+A1UEAxMKQWxleCBCbGlnaDCCAVIwDQYJKoZIhvcNAQEBBQADggE/ADCCAToCggEx
+ANspvmeoHnuXaYQlrqaAXtt1SLkXqj4HLEPj8gNc1Aqj5wnQrTFZwiqPzd7lZI+L
+uN/pWZ+0vFiZrjGJ4JtzIFJMR1Xe7iFw0YFDzxnQX9BWyA2G5LdKa4tyL1eIEK0r
+FAFKtzDn+t3NHKJQDRSzOruzyNxEqrGP8Amv5Cwgakob5Dw+GMMJM60unkrLG+PX
+Nv8+XcXdgF28PPUdewSuIXA+yRusakj9Oc9XalLMc3Bvx+GNeljawqQmrQmhGZEN
+cCU5gMSF911SaahqRdITC+Xy6puSV3v9om2qVuAezH7BBd3ZHMtKZFpA++99cdlJ
+9pzhyCPagsqz2KWayrlqcUH7Tk/yu4dOs7vFbzs+8frRvCfrae35/Q2gWPDfh+I3
+PLDZ8vfQvoTBAdVnO4CqgBkCAwEAAaNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNV
+HQ8BAf8EBQMDBwQAMB0GA1UdDgQWBBTJmh5kGpw4GOpTX6URYj4QgiRl2DANBgkq
+hkiG9w0BAQsFAAOCATEAKGdKt1fZOm9mlLmzsKyVT3+9LgeFO2dekmbWM2f9laAk
+v5JnU3JbVzgvvRKnsxRq8MjDrcBppeUyImHjeg52cEKhJ2xr3tJBNrA6j6+6K27P
+4C2Ny9vWb7C90KGSTBx7fn3vA53n/mWOjNgtXdpxKpBHsRJVQjB7rvQojvGrFYyA
+vjpED/I7MVsZmpuQq2RF/30+wN9g7fn2iXreOQ0kZQjfhuo5588/HmIhMU+e6/pP
+7gyd/8F/GHfCSS14l/3BvL5xBsyvci6aZ4ZAOtweYgoGRHCace8RRr4aqLWNIHZf
+7/UmE3m6TiSU3yheENVZjeTsypAgYOboOh+75vg6f0S592nupAywzW0zt/MjHVnI
+Q4sThawl8bbY3JrUUcqeFUWv7Qya0DQ7cjRamrAE9Q==
+-----END CERTIFICATE-----
diff --git a/tests/run/certs/ca-key.pem b/tests/run/certs/ca-key.pem
new file mode 100644 (file)
index 0000000..7070192
--- /dev/null
@@ -0,0 +1,32 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIFfAIBAAKCATEA2ym+Z6gee5dphCWupoBe23VIuReqPgcsQ+PyA1zUCqPnCdCt
+MVnCKo/N3uVkj4u43+lZn7S8WJmuMYngm3MgUkxHVd7uIXDRgUPPGdBf0FbIDYbk
+t0pri3IvV4gQrSsUAUq3MOf63c0colANFLM6u7PI3ESqsY/wCa/kLCBqShvkPD4Y
+wwkzrS6eSssb49c2/z5dxd2AXbw89R17BK4hcD7JG6xqSP05z1dqUsxzcG/H4Y16
+WNrCpCatCaEZkQ1wJTmAxIX3XVJpqGpF0hML5fLqm5JXe/2ibapW4B7MfsEF3dkc
+y0pkWkD7731x2Un2nOHII9qCyrPYpZrKuWpxQftOT/K7h06zu8VvOz7x+tG8J+tp
+7fn9DaBY8N+H4jc8sNny99C+hMEB1Wc7gKqAGQIDAQABAoIBMAJSDpSj5HtmsW9n
+WRJPv9FfNvTTbJIeutKsM52NVScYsFimV5Mdx28dGdmvQEbp0ecNs40mmYDu/aJu
+JTfteo03MWErd1uDdDXEF/RcGbZHw54AYeRpRWVoVoUnfmpgT07/3Bvd35uLcVnB
+nbssoPr9pBXlpJC1PLN+49xYv9oG3L42N8Zm5Epu44OuDglLTScw4UbNTy+O3+qQ
+q+P++j2Ysnt53a20J5XgdBpAksjydFOkN8OdZIdeAGXeHA0svwUdw8Z3BJzv/cB/
+KGI5BPTQh42BMGboog8k8uFUCA6P0ZkwAy4Cgf1801DRC+pBvBqeN3gBTRIpA6Rq
+p6RZTiTGTQF3gDbHHA7TJSIav+mv9aNZUFKtvu4QGqoT5qNz531gkdFi7eBwbA8V
+QjOnuAECgZkA65MCrjo4M2XzrVqKH2X8L6xd8eLYKlZEQrBJjZI6Ly0SK9wG5IRa
+bum62w8zJWZvk+a1985auXKA8gPeEbrpULNJv/OkSstqZhKFI+ckoJFmGu+cYqNv
+Al3/NeOYPeLW7v767XJhAdEfuBK3Ra7w+6qphRiLIbgK8MQuGxfYmgdu1hffjdOS
+WwNy2jyQby6p93nnKu7RxAECgZkA7ip1I+rSEpj3LkJvXt/9xC8SsAmjDEDpGxer
+oFkffj+jfIXNZN+kg6pvSO6stzvtjlgiWT/MLX9JYJW1eaTIVWBbmZ6D5R70jiUu
+RLI2bX1bFv50S9EN0wE/0IwoK7XfoScdRpJ4RJX8SV/Q7esPyKGHKbaHaeifYmkD
+rXehdE+gcQqoN4lTN7dnNYYBODwvosf3+1O+XBkCgZkAuZxCb25126GHxt3gmG6t
+rg5ckvqOIYWJERZ/TamaaJNVjvM1BxZ1fpBwZqtqPByi62DLnW2ctCNRD98WONgR
+f0FUaYaZu0jdE4GiH7C+fjkxvyVuDZYCIFZZgGdMC+7QNMz4fuAxKNJR8KHmf2Qg
+gdps6O52qWGuVRftz/EQ/APBQ7TZspCx7z4fX256yu90ggYtqvkylAECgZkA0YHx
+5/WidI+xKTVx6SDbiB/srYTctGPJa3bIGFcuGA39UAYYJ3uAqf5cxOiIcOu7zrMD
+DEXN49wL/XXU3TwyqsAH9Dv4RK6VbRGSAQZQUMKsRa7zONqe8ZYwv9D7aXAlWAsj
+erhQKe1SsG0kSpa0HMbTMsOJnYXv507/2DHbioidV7OLRMd9uA6TMQc/vWtccDK+
+l40UcMkCgZgNteR/raLb/9BV3p6MOVlueT9nJNbxLN46qA74SVzLDQ4HKDJvI1iR
+0sE3Vx3FZXxPebzEiSHbM1XvUamriG+PvSJ3E0Nd6RGrD6jfFNnqozXOOd9kcIQD
+IYtyv1mFKDj/577lE9YWazpmPvHwPCXtOePtSCwJTnbyyGcvYKKxTWsSq8MglJy7
+uKKoa0ZGCIwqa3zu4vM4ng==
+-----END RSA PRIVATE KEY-----
diff --git a/tests/run/certs/ca.info b/tests/run/certs/ca.info
new file mode 100644 (file)
index 0000000..f589848
--- /dev/null
@@ -0,0 +1,4 @@
+cn = Alex Bligh
+ca
+cert_signing_key
+expiration_days = 3650
diff --git a/tests/run/certs/client-cert.pem b/tests/run/certs/client-cert.pem
new file mode 100644 (file)
index 0000000..2622323
--- /dev/null
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID0DCCAoigAwIBAgIEVxYY2jANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwpB
+bGV4IEJsaWdoMB4XDTE2MDQxOTExMzkwNloXDTE3MDQxOTExMzkwNlowZzELMAkG
+A1UEBhMCR0IxIjAgBgNVBAoTGU5hbWUgb2YgeW91ciBvcmdhbml6YXRpb24xDzAN
+BgNVBAcTBkxvbmRvbjEPMA0GA1UECBMGTG9uZG9uMRIwEAYDVQQDEwlsb2NhbGhv
+c3QwggFSMA0GCSqGSIb3DQEBAQUAA4IBPwAwggE6AoIBMQC//QhizFHAJhffGMXc
+kXg8yJt2Aj4bGMVGbUuCGCQqQjwMQ3laKLKyQBPcAYiUrQenkuhdzlRmMoQiIDE/
+UGKQvgrpQS+bc2/om5tQHRJxZ2RESnu+zDmubdsmvnWWAabkfBbBXn9pq+RZvMMM
+8cpnDyMvv9dQb9mWPtnJSaCoZIKeL6VBBFtUxhWIz1SGN/GkxynsDWepZJ3YYtft
+MP5cduecYPBNbL543C7MjuhGKKjqHPCiVxZbf3HhWdZS5WeMytlPN7mLdaNgXD/Q
+L43cpFUQhmv/DdiGWIw6Iz3xUBrlI4vrfylbNGdCO1K6VDBNz/JIGNpExUcyXok+
+wxJ/DHjIYknPlCItHN9sym+gF4UWTqRw7FrEUX+3p38lZz5CcZidRYmiW9lIgZZ9
+d/xNAgMBAAGjdjB0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwIw
+DwYDVR0PAQH/BAUDAwegADAdBgNVHQ4EFgQU1hIpx3H8zyir+Mw8/GOzrrkdieMw
+HwYDVR0jBBgwFoAUyZoeZBqcOBjqU1+lEWI+EIIkZdgwDQYJKoZIhvcNAQELBQAD
+ggExAELOkm/uilBs1zYu0ZkigAk06PDp+ufF4FVu//FFDZb9U66Lk94XCXDW5mHg
+5Kx5B4kAqKzH5xWyIdcEmmap8TRZ5wkPOSwOkaMEjcm6JnWqjIcprZ34QIYQKJzX
+N+5SVZRKnpm7ClJe+cvkm8fskGW1swKHGPz3O4IQK4IVEhzu2B8Cr5E+s186fd8B
+x6e0CBRk8PjGX5R5rhJWWPqMQMKkJhxjj+NKtPF7833bXqiODHuhYv1cjHz/1mJW
+3dfRGDnQzIJX8Kq+blILbs/Fl815jvVp6kL7pqQa9ABHh+5XvKOvikP5VpyYGs2G
+qaZiL9fRLbK/QQ9777BW19+Cz8F0gjfQIlj16DmtRlF7GUmc+q8yVhrOoohyiZHC
+sy14maMc7AA/Bwv0eRtfkyGbLOg=
+-----END CERTIFICATE-----
diff --git a/tests/run/certs/client-key.pem b/tests/run/certs/client-key.pem
new file mode 100644 (file)
index 0000000..d119d52
--- /dev/null
@@ -0,0 +1,32 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIFewIBAAKCATEAv/0IYsxRwCYX3xjF3JF4PMibdgI+GxjFRm1LghgkKkI8DEN5
+WiiyskAT3AGIlK0Hp5LoXc5UZjKEIiAxP1BikL4K6UEvm3Nv6JubUB0ScWdkREp7
+vsw5rm3bJr51lgGm5HwWwV5/aavkWbzDDPHKZw8jL7/XUG/Zlj7ZyUmgqGSCni+l
+QQRbVMYViM9UhjfxpMcp7A1nqWSd2GLX7TD+XHbnnGDwTWy+eNwuzI7oRiio6hzw
+olcWW39x4VnWUuVnjMrZTze5i3WjYFw/0C+N3KRVEIZr/w3YhliMOiM98VAa5SOL
+638pWzRnQjtSulQwTc/ySBjaRMVHMl6JPsMSfwx4yGJJz5QiLRzfbMpvoBeFFk6k
+cOxaxFF/t6d/JWc+QnGYnUWJolvZSIGWfXf8TQIDAQABAoIBL0denj9xX505NqaO
+Dv/FFBgvJZuOOd2Dgn0rzrtjPg53kNr+OkkfLU7A2KEbRiqpfVmjbb4cIEPdg5aB
+YSKoP1E5/ym25yZimLdfy9zRnImLuzpSdgNM6CRvsjLfmoFTxowplPaiqmVzVkVb
+ESc+uynp9qqe0OvrUyJckEQY8CBT54/me7Laa8PtNGl8qW87shi58QZPSrnX3LP/
+Y7ojW0XngFsPWqmHBYxBWb3+PO/QuJYQzEb24E/E+4LOGuhTg8ylDqrcbnhzkHEH
+/XcG1sIltsHr6Ai20l+JG50KJ0zYMSGg48HuUZYegW+9AI8H7OgZIY8OlXHp5cuw
+lyZZeQm1/5EZIeirJoHp3dh42RkT5v44Xz1ocBMwZrdeuoJlmWHrbswTcKyO8Cfb
+UWvNXwKBmQDDg77I0O/7d4LlYEauP3adsG0mp+kV6tWxzMnv3c0aA8FkHUVoHK/9
+JWm+v5qJ5v3l8H9wA+non7RYcJjnATr4CtOnF3EFFDrcYL//nmWMJuayOtKiRhMq
+Dhub++qJaZm1lxaEt7KRaY7tQZ6ZrBo6EOWu0H0nky17xe3fFM93ORvWp7Mwkxkm
+b1BbtO/10JU0+sapWQdHTwKBmQD7YgUZRBTZcCHlvQ7u9oSnFM10pb2jBYxgSkiN
+99cimwyeRcWo0fdOROBeUREJ/KgRHY9u97cnYqJ/y4AiB1zna8NDyC8JxVOVjy8J
+Psma6n7G0A5KVMgELM+Vif5onNu9bcOd13puG7igv3GOC80jQ/IJW0dhatDtxmjB
+bqNcMTN7lix/UPV6mpbAIpgwg1I4k1NuaZvbowKBmQC/zzVRwCFf/ByPucc91Yci
+Jt6+qMZ0OSISv81xJJG+LucAt/LKtDI30QeQGlubZOG8PxhXJY/KJzv/898d6kgW
+5lBEwiugBvvEDqruNVB8kgGL40eX6dWNUa/mdNvgmZgx3Zs68xkdrYiJ3PGi44QL
+aV5cBbBzLeHWZxT54Wm0FnPoQDf8tKNc4KHehoFQEKUBB/H0XCJW4wKBmHxPBGZy
+HD1KDfklfHT+wqo8xzyfmR88ZyZWlXpezKv4ME00A4JwEfNKbAk33U0q+5E7JOqi
+5Jc9V04Ku9oX+gEWcQDbxSb3xVV38LKJsfhBbV+zEt3+/snRvvUbwArLRn5uAQXU
+wF4ipzIWeXjcrRx7RP0LfkjWIWrzamn85Bt62RKMOITc7Acs2s84TDnxNn9zmxZG
+cyQxAoGZAI4mAR8HYlyTfFzN5L0e4dPrTQbXBZHD/B+gPdjrsy+3/mnkxumotvsa
+Wa4ruXXLlkUQ+enYryax+c1ZW/2AdQ0EDGKIdKy/RwzvLeS0ZhGKhC7CJVK2ezCC
+X3u+0MmYMPxT7cmFj8q6eRgNpzCbsANKSqpzX+52jiiQxR0bE+cfWCNy7yBBYJCy
+z0QrsAtohslE1CjcXeXb
+-----END RSA PRIVATE KEY-----
diff --git a/tests/run/certs/client.info b/tests/run/certs/client.info
new file mode 100644 (file)
index 0000000..77ea1a3
--- /dev/null
@@ -0,0 +1,9 @@
+country = GB
+state = London
+locality = London
+organization = Name of your organization
+cn = localhost
+tls_www_client
+encryption_key
+signing_key
+expiration_days = 3650
\ No newline at end of file
diff --git a/tests/run/certs/server-cert.pem b/tests/run/certs/server-cert.pem
new file mode 100644 (file)
index 0000000..39206d4
--- /dev/null
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDoTCCAlmgAwIBAgIEVxYYzTANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwpB
+bGV4IEJsaWdoMB4XDTE2MDQxOTExMzg1M1oXDTI2MDQxNzExMzg1M1owODEiMCAG
+A1UEChMZTmFtZSBvZiB5b3VyIG9yZ2FuaXphdGlvbjESMBAGA1UEAxMJbG9jYWxo
+b3N0MIIBUjANBgkqhkiG9w0BAQEFAAOCAT8AMIIBOgKCATEA190qI8Ict55jeto3
+EumIxub2y/Ae9CWz5EAhUWQFVQc1IWxIl08Q2N2cFy89kagZ2DiDsScm6QZumiE/
+PyP7y5pXlSOn/DZ+p/K+i9LNznGHuEZQqYLIXwhsI+xEMa+KP65NgM/vAnpn5Zda
+JCSJR2pGL1Iajszix+n37M8jMMvEopo0Wjj+GjnIkm/PPLIfOXnrR+pBrE8np4p7
+JvcJnW3qFt+zy7GIo3f99wjkaMjEl0Eud5DpF9n0VcRItRfNCRLLTT7IOfcl6M+/
+dWGa/pIuKdhpoNmwZxzdGc9hQDlr+QLTpW8M1xzx0Mfq0rJIOfSpSSXw007iwAqD
+YVd8D3Ai6zmVY5CjRypzyngiAYc02QZHo80U15JoC71lgh5RTFSopXDClgBJ0grM
+BNXvtwIDAQABo3YwdDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMB
+MA8GA1UdDwEB/wQFAwMHoAAwHQYDVR0OBBYEFLkZ9EimCBJwP1HidVQzLyCOS2y1
+MB8GA1UdIwQYMBaAFMmaHmQanDgY6lNfpRFiPhCCJGXYMA0GCSqGSIb3DQEBCwUA
+A4IBMQBFmq3zn64V6+k+O141gwsyJ6me7ag4zitCIdx3moh/GVQ3Y746IMu3KMI2
+nxIdwyTahI97TsuIek9D/QDME7NylnHBSP+/h5ptV/zFFvYxAinCP8AHtca5WKBk
+TiB22V3Oq4Ywg5gVJucuM6O9j6LhvDv/9g4Jsy1SzPK1GLa/XhojFAcwVYfaCsax
+BiZkeMV/yLnoIi6MLUWf7qR7+b6XFKTedgAUT2j2C6VfNk8PBNG+uVAKThFWDrv6
+yf9zMD9aNRjYlwFFUwFE58OF9frSZJMS9abx6ELCBqv9ElFnGAH1J0/CPKFNuuIQ
+qgnOmhzjurvOge3mxpP37PRnYr/HgwtslIYR8vRTnBtZTvbL5lYE1bqIwlyXisdL
+daDNOxFgThSfts25XQxtTJPe0IEd
+-----END CERTIFICATE-----
diff --git a/tests/run/certs/server-key.pem b/tests/run/certs/server-key.pem
new file mode 100644 (file)
index 0000000..f69d359
--- /dev/null
@@ -0,0 +1,32 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIFewIBAAKCATEA190qI8Ict55jeto3EumIxub2y/Ae9CWz5EAhUWQFVQc1IWxI
+l08Q2N2cFy89kagZ2DiDsScm6QZumiE/PyP7y5pXlSOn/DZ+p/K+i9LNznGHuEZQ
+qYLIXwhsI+xEMa+KP65NgM/vAnpn5ZdaJCSJR2pGL1Iajszix+n37M8jMMvEopo0
+Wjj+GjnIkm/PPLIfOXnrR+pBrE8np4p7JvcJnW3qFt+zy7GIo3f99wjkaMjEl0Eu
+d5DpF9n0VcRItRfNCRLLTT7IOfcl6M+/dWGa/pIuKdhpoNmwZxzdGc9hQDlr+QLT
+pW8M1xzx0Mfq0rJIOfSpSSXw007iwAqDYVd8D3Ai6zmVY5CjRypzyngiAYc02QZH
+o80U15JoC71lgh5RTFSopXDClgBJ0grMBNXvtwIDAQABAoIBMEKCbcfruI5oukzx
+bDOjCdYC9rqaRudBsJ4clkduEmiC2n9sTid0oIO5MC1CjG1TBneE3iqYnhgBN9W8
+dbC+JQg0C1Uz0b/XiIm1tLj/IBNCDqeb3qGD3rnNLgiZdN98LxP04ANWzdUNIvLu
+AcOOEFAVMf/Fg9JI1Xz0HUP1BGo19mWFLqk30y8Aa8iWs5sHZLCAXJphVo/AmGZW
+GgpHXGohNeEuafE85J36qSXiyQ/J2kglWXdT0h1hbAyIRmN7BakOou1TAlDz9+2a
+IujOZgQrEnSeZlKv7aUKTUpTE4kwoKOQLZ3YB7cRma3CaDoZ6dSyDC9a1zTNeLjz
+sS0wn/46O+QkYQxNoxiBHj6vzWWplC+y6/c+7UZF5NDfogSQ7BZEKHiKK0zu1xTW
+8fQ3C8UCgZkA2J3qbwdi/Jtg22RSceIyaTwhe2UVhF9PKljx304vmH2lvbBEklHP
+eiB98FOLlu6AgxWqOi/BokFRzJHMszCRPCZFes4sbzts4PKiX8PAGVdoHXYjPdak
+lerAxS7W/lK5cn5wQyUsc7ljb45rA/J8T8tQ89o4qRMicGa/MHxagJVvUVX0Xev6
+3qPUTb8SOB1ye2oB5uSCxVUCgZkA/xw0abUUCFLYnWbxZjNshqK8r8KabviBsk5j
+4Li4UxQOzticw9k9UU3Ct9hgcQ8jVKBLXTxT+cwKCrc3ZTWwRrOkHct1IQM7L5hk
+LX5BKL6+XDaJCbRwr9+zkopOJ3TUOdFo7pWDJgRjTWhnYTMgSf+14/hceoD1KKMM
+aik3ru/FwJkQYFYLtNj3V1j4VuVHSOyOqbcaoNsCgZhMV3M8yBSpxDThfTzVKAvu
+LKP8MgbgTRrAaPJtace6bWXRMWMpUi3V88eOwFLs0Yd3K1aABT6v6WdjumqzKEW3
+NiG8gxcD6KSZrsltCLcV90kZQP5wl8oPj9l6ZOSeYxc6c7cq4toEuuyBb2bl0Drh
+gF06Y8keRUEY7g0pkFnxATlnJ+zkgPs8Je73q4RHRJGJTzX2Ysh3tQKBmQDe8A79
+sbjn7T5Pj362CYp1vhGWp0G+aH0vDUJLSCIMuCKYsMOOg3IKcyIO95CQPOJrOgmi
+WO4qBh1gb+yBDgIWRzbMstiRGPnIBizFdOgMa2R/wUjQqlcv2xZaoXLbGEW+oTpK
+BW6u8na1Vt/BGaTGBik2J/zpMXkNIi/fNlXrEq6GOT0OcyOXz2OXebDMf2FkYRXr
+SpCCsQKBmDbHnS3b4mQH7I6hDVCYT7zyQeyEwMjufkf/vnbsh4V6J5Sq2gtd9epl
+qsKCCTPZaGdkZoOO7CGFJawlzm7Htm9Y1bmZUTBHz61x/+cDPp8IL6qAMod23WSD
+8R/Rv9nJLJqH+LnQ/Bvfwl2eKyJquinbTgirdmdyDkmbsKJfHOKcCBtAYSnGWBg0
+hag+Jq3uH47luVKswO+V
+-----END RSA PRIVATE KEY-----
diff --git a/tests/run/certs/server.info b/tests/run/certs/server.info
new file mode 100644 (file)
index 0000000..da429d2
--- /dev/null
@@ -0,0 +1,6 @@
+organization = Name of your organization
+cn = localhost
+tls_www_server
+encryption_key
+signing_key
+expiration_days = 3650
index 0da3480..93065d4 100644 (file)
 #define MY_NAME "nbd-tester-client"
 #include "cliserv.h"
 
+#ifdef WITH_GNUTLS
+#include "crypto-gnutls.h"
+#endif
+
 static gchar errstr[1024];
 const static int errstr_len = 1023;
 
@@ -50,6 +54,10 @@ static uint64_t size;
 static int looseordering = 0;
 
 static gchar *transactionlog = "nbd-tester-client.tr";
+static gchar *certfile = NULL;
+static gchar *keyfile = NULL;
+static gchar *cacertfile = NULL;
+static gchar *tlshostname = NULL;
 
 typedef enum {
        CONNECTION_TYPE_NONE,
@@ -342,6 +350,10 @@ static inline int write_all(int f, void *buf, size_t len)
        return retval;
 }
 
+static int tlserrout (void *opaque, const char *format, va_list ap) {
+       return vfprintf(stderr, format, ap);
+}
+
 #define READ_ALL_ERRCHK(f, buf, len, whereto, errmsg...) if((read_all(f, buf, len))<=0) { snprintf(errstr, errstr_len, ##errmsg); goto whereto; }
 #define READ_ALL_ERR_RT(f, buf, len, whereto, rval, errmsg...) if((read_all(f, buf, len))<=0) { snprintf(errstr, errstr_len, ##errmsg); retval = rval; goto whereto; }
 
@@ -401,6 +413,10 @@ int setup_connection_common(int sock, char *name, CONNECTION_TYPE ctype,
        /* negotiation flags */
        if (handshakeflags & NBD_FLAG_FIXED_NEWSTYLE)
                negotiationflags |= NBD_FLAG_C_FIXED_NEWSTYLE;
+       else if (keyfile) {
+               snprintf(errstr, errstr_len, "Cannot negotiate TLS without NBD_FLAG_FIXED_NEWSTYLE");
+               goto err;
+       }
        negotiationflags = htonl(negotiationflags);
        WRITE_ALL_ERRCHK(sock, &negotiationflags, sizeof(negotiationflags), err,
                         "Could not write reserved field: %s", strerror(errno));
@@ -412,6 +428,111 @@ int setup_connection_common(int sock, char *name, CONNECTION_TYPE ctype,
                }
                goto end;
        }
+#ifdef WITH_GNUTLS
+       /* TLS */
+       if (keyfile) {
+               int plainfd[2]; // [0] is used by the proxy, [1] is used by NBD
+               tlssession_t *s = NULL;
+               int ret;
+
+               /* magic */
+               tmp64 = htonll(opts_magic);
+               WRITE_ALL_ERRCHK(sock, &tmp64, sizeof(tmp64), err,
+                                "Could not write magic: %s", strerror(errno));
+               /* starttls */
+               tmp32 = htonl(NBD_OPT_STARTTLS);
+               WRITE_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+                        "Could not write option: %s", strerror(errno));
+               /* length of data */
+               tmp32 = htonl(0);
+               WRITE_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+                        "Could not write option length: %s", strerror(errno));
+
+               READ_ALL_ERRCHK(sock, &tmp64, sizeof(tmp64), err,
+                               "Could not read cliserv_magic: %s", strerror(errno));
+               tmp64 = ntohll(tmp64);
+               if (tmp64 != NBD_OPT_REPLY_MAGIC) {
+                       strncpy(errstr, "reply magic does not match", errstr_len);
+                       goto err;
+               }
+               READ_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+                               "Could not read option type: %s", strerror(errno));
+               tmp32 = ntohl(tmp32);
+               if (tmp32 != NBD_OPT_STARTTLS) {
+                       strncpy(errstr, "Reply to wrong option", errstr_len);
+                       goto err;
+               }
+               READ_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+                               "Could not read option reply type: %s", strerror(errno));
+               tmp32 = ntohl(tmp32);
+               if (tmp32 != NBD_REP_ACK) {
+                       strncpy(errstr, "Option reply type != NBD_REP_ACK", errstr_len);
+                       goto err;
+               }
+               READ_ALL_ERRCHK(sock, &tmp32, sizeof(tmp32), err,
+                               "Could not read option data length: %s", strerror(errno));
+               tmp32 = ntohl(tmp32);
+               if (tmp32 != 0) {
+                       strncpy(errstr, "Option reply data length != 0", errstr_len);
+                       goto err;
+               }
+
+               s = tlssession_new(FALSE,
+                                  keyfile,
+                                  certfile,
+                                  cacertfile,
+                                  tlshostname,
+                                  !cacertfile || !tlshostname, // insecure flag
+#ifdef DODBG
+                                  1, // debug
+#else
+                                  0, // debug
+#endif
+                                  NULL, // quitfn
+                                  tlserrout, // erroutfn
+                                  NULL // opaque
+                       );
+               if (!s) {
+                       strncpy(errstr, "Cannot establish TLS session", errstr_len);
+                       goto err;
+               }
+
+               if (socketpair(AF_UNIX, SOCK_STREAM, 0, plainfd) < 0) {
+                       strncpy(errstr, "Cannot get socket pair", errstr_len);
+                       goto err;
+               }
+
+               if (set_nonblocking(plainfd[0], 0) <0 ||
+                   set_nonblocking(plainfd[1], 0) <0 ||
+                   set_nonblocking(sock, 0) <0) {
+                       close(plainfd[0]);
+                       close(plainfd[1]);
+                       strncpy(errstr, "Cannot set socket options", errstr_len);
+                       goto err;
+               }
+
+               ret = fork();
+               if (ret < 0)
+                       err("Could not fork");
+               else if (ret == 0) {
+                       // we are the child
+                       signal (SIGPIPE, SIG_IGN);
+                       close(plainfd[1]);
+                       tlssession_mainloop(sock, plainfd[0], s);
+                       close(sock);
+                       close(plainfd[0]);
+                       exit(0);
+               }
+               close(plainfd[0]);
+               close(sock);
+               sock = plainfd[1]; /* use the decrypted FD from now on */
+       }
+#else
+       if (keyfile) {
+               strncpy(errstr, "TLS requested but support not compiled in", errstr_len);
+               goto err;
+       }
+#endif
        /* magic */
        tmp64 = htonll(opts_magic);
        WRITE_ALL_ERRCHK(sock, &tmp64, sizeof(tmp64), err,
@@ -1597,6 +1718,10 @@ int main(int argc, char **argv)
        int testflags = 0;
        testfunc test = throughput_test;
 
+#ifdef WITH_GNUTLS
+       tlssession_init();
+#endif
+
        /* Ignore SIGPIPE as we want to pick up the error from write() */
        signal(SIGPIPE, SIG_IGN);
 
@@ -1613,7 +1738,7 @@ int main(int argc, char **argv)
                exit(EXIT_FAILURE);
        }
        logging(MY_NAME);
-       while ((c = getopt(argc, argv, "FN:t:owfilu:h")) >= 0) {
+       while ((c = getopt(argc, argv, "FN:t:owfilu:hC:K:A:H:")) >= 0) {
                switch (c) {
                case 1:
                        handle_nonopt(optarg, &hostname, &p);
@@ -1652,6 +1777,28 @@ int main(int argc, char **argv)
                        test = handshake_test;
                        testflags |= TEST_HANDSHAKE;
                        break;
+#ifdef WITH_GNUTLS
+               case 'C':
+                       certfile=g_strdup(optarg);
+                       break;
+               case 'K':
+                       keyfile=g_strdup(optarg);
+                       break;
+               case 'A':
+                       cacertfile=g_strdup(optarg);
+                       break;
+               case 'H':
+                       tlshostname=g_strdup(optarg);
+                       break;
+#else
+               case 'C':
+               case 'K':
+               case 'H':
+               case 'A':
+                       g_warning("TLS support not compiled in");
+                       /* Do not change this - looked for by test suite */
+                       exit(77);
+#endif
                }
        }
 
@@ -1659,6 +1806,12 @@ int main(int argc, char **argv)
                handle_nonopt(argv[optind++], &hostname, &p);
        }
 
+       if (keyfile && !certfile)
+               certfile = g_strdup(keyfile);
+
+       if (!tlshostname && hostname)
+               tlshostname = g_strdup(hostname);
+
        if (test(hostname, unixsock, (int)p, name, sock, FALSE, TRUE, testflags)
            < 0) {
                g_warning("Could not run test: %s", errstr);
index 2ca78dd..c64cabb 100755 (executable)
@@ -306,6 +306,51 @@ EOF
                ./nbd-tester-client -h -N export1 localhost
                retval=$?
        ;;
+       */tls)
+               # TLS test
+               certdir=$(pwd)/certs
+               cat >${conffile} <<EOF
+[generic]
+       certfile = $certdir/server-cert.pem
+       keyfile = $certdir/server-key.pem
+       cacertfile = $certdir/ca-cert.pem
+[export1]
+       exportname = $tmpnam
+       flush = true
+       fua = true
+       rotational = true
+       filesize = 52428800
+       temporary = true
+EOF
+               ../../nbd-server -C ${conffile} -p ${pidfile} &
+               PID=$!
+               sleep 1
+               ./nbd-tester-client -N export1 -i -t "${mydir}/integrity-test.tr" -C "${certdir}/client-cert.pem" -K "${certdir}/client-key.pem" -A "${certdir}/ca-cert.pem" localhost
+               retval=$?
+       ;;
+       */tlshuge)
+               # TLS test with big operations
+               # takes a while
+               certdir=$(pwd)/certs
+               cat >${conffile} <<EOF
+[generic]
+       certfile = $certdir/server-cert.pem
+       keyfile = $certdir/server-key.pem
+       cacertfile = $certdir/ca-cert.pem
+[export1]
+       exportname = $tmpnam
+       flush = true
+       fua = true
+       rotational = true
+       filesize = 52428800
+       temporary = true
+EOF
+               ../../nbd-server -C ${conffile} -p ${pidfile} &
+               PID=$!
+               sleep 1
+               ./nbd-tester-client -N export1 -i -t "${mydir}/integrityhuge-test.tr" -C "${certdir}/client-cert.pem" -K "${certdir}/client-key.pem" -A "${certdir}/ca-cert.pem" -H 127.0.0.1 localhost
+               retval=$?
+       ;;
        *)
                echo "E: unknown test $1"
                exit 1