From 54b74b3d82b0b4ca7ac58621bfca145bc87e4c53 Mon Sep 17 00:00:00 2001 From: chris-j-h Date: Sun, 7 Jul 2019 16:44:50 +0100 Subject: [PATCH] Implement open for hashicorp wallets to create a client --- accounts/vault/testdata/README.md | 1 + accounts/vault/testdata/caRoot.pem | 35 ++++ .../testdata/localhost-with-san-chain.pem | 117 +++++++++++ .../vault/testdata/localhost-with-san.key | 27 +++ .../vault/testdata/quorum-client-chain.pem | 99 +++++++++ accounts/vault/testdata/quorum-client.key | 27 +++ accounts/vault/vault_wallet.go | 54 +++-- accounts/vault/vault_wallet_test.go | 195 ++++++++++++++++-- 8 files changed, 524 insertions(+), 31 deletions(-) create mode 100644 accounts/vault/testdata/README.md create mode 100644 accounts/vault/testdata/caRoot.pem create mode 100644 accounts/vault/testdata/localhost-with-san-chain.pem create mode 100644 accounts/vault/testdata/localhost-with-san.key create mode 100644 accounts/vault/testdata/quorum-client-chain.pem create mode 100644 accounts/vault/testdata/quorum-client.key diff --git a/accounts/vault/testdata/README.md b/accounts/vault/testdata/README.md new file mode 100644 index 000000000..2ed55636a --- /dev/null +++ b/accounts/vault/testdata/README.md @@ -0,0 +1 @@ +`server.crt` and `server.key` contain the values of `internal.LocalhostCert` and `internal.LocalhostKey` respectively, for use with enabling TLS on the httptest server diff --git a/accounts/vault/testdata/caRoot.pem b/accounts/vault/testdata/caRoot.pem new file mode 100644 index 000000000..a0fd1c136 --- /dev/null +++ b/accounts/vault/testdata/caRoot.pem @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIGDDCCA/SgAwIBAgIJAMqZvaZrhPEWMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYD +VQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEUMBIGA1UEBwwLQm91cm5lbW91dGgx +EzARBgNVBAoMClF1b3J1bSBMdGQxKTAnBgNVBAsMIFF1b3J1bSBMdGQgQ2VydGlm +aWNhdGUgQXV0aG9yaXR5MRswGQYDVQQDDBJRdW9ydW0gTHRkIFJvb3QgQ0EwHhcN +MTkwMTA5MjEwOTA4WhcNMzkwMTA0MjEwOTA4WjCBkjELMAkGA1UEBhMCR0IxEDAO +BgNVBAgMB0VuZ2xhbmQxFDASBgNVBAcMC0JvdXJuZW1vdXRoMRMwEQYDVQQKDApR +dW9ydW0gTHRkMSkwJwYDVQQLDCBRdW9ydW0gTHRkIENlcnRpZmljYXRlIEF1dGhv +cml0eTEbMBkGA1UEAwwSUXVvcnVtIEx0ZCBSb290IENBMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAuZ7qUku/uzXJSz7DkLKg+UrQXd7Bma59fqZFjnu8 +XPaqIusXOePkh3SjNWSB4TLCm/uvHlW28ljNJfro1UxSPNtNWSiyb+oTbp76C/oX +Tkf9t8Z6osMM8zWsG6wpPCvGsJ91LkN+binJQK6RALdZBNkJ9d7jNJlhJ/CWmNSd +sn47CTargMdppxL96/JhVFzFY/Yorrc9np+tRGceRcfTh4ng8m53n37HHBrb8rXd +Gk7x8UG7Lo+GAHeF1RSzzuNElwHOdbh884uZ4qejG80x/hWQxghfFtXHNj6v6Llh +lAM9rn9fi57cv8G/A+sL5u81CoQCaichDqdGX6L70XHidyO0FgJO5tJ5w6wYanb6 +Kj5HVSblH79NDI7spy9XzoVtKETo15sguCX16ZWgaEooXQEB1PkjdtYYDgIA7JCK +okvBrYEby3ygQB2rxWqfkJIzgfRC+iHLQrYEl9d5uz3tmV/rhDnA7La3BGBuKpyw +oVdBHxxF2FeSbLHewfg6KXkVUGZEhx1MsKmI8+3ktFs+EOQdocoFHznX5niEIOIU +AynYJMTAZEAy1f0JuZHIwoMwnLLEjbqlPC9PgVDoUZHugAa36VSRBvWhJvWx81db +3DbY2wyQ8jGS920sRlVTswBARNDUyPpIpez7+M0KlhJ79p2rl+JyPnbMWgJn+Uet +Up0CAwEAAaNjMGEwHQYDVR0OBBYEFF6uedlS+J83omsSQx55AK99dMv5MB8GA1Ud +IwQYMBaAFF6uedlS+J83omsSQx55AK99dMv5MA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBuK9O23LSLwCkixn9OcfnD +QWhIQubLkc9AB1BytowYYhkpOKzGBTUK70zyS+dBTd8OxWsWyOLCgwIpZJwc8IcT +vk8F6/+q7qrJ+XCz/xp+R+XJK4XP+re/Lh/iGYXH0NovFzo3aXqUtvZFfdLWe65L +9RT6qlkol4MM7pXMtr014nv26H7R74eI2YfizIKgkBuhYCrNTjjs3A/qnCepsFn1 +xy6MZfDLtkH9wb4bd/UaCiuhFvM/t1cwz+94Y3wTj79aKD4Y01+Tfy0yWN8F0iDW +PS3mxlhl7bBZ4OOtCwZLm73f/3KymhGgAjeSH6C4BoizBjVMzYfXDwP7CgrwgfHN +26me2OpQV9pl0bCtXo+C0oIC4nWDayls7b0QouFiUP7F2pO96fvyUmztFn9XuF3E +jmJ6VtrpWe2ZbNoWVyIciZNf7QK2wkKkolh+TbVZ/AoSfdmTX0uS6/JtiQwB8dtC ++lOCApON84fDZYCMCeKhj08zanVfmeKWwqE1wR6qP2w4WXuNdHorDwlR8I4eXT+p +qQ552wAJA3CSbkOn1inVjgyLoGQFFYKRwABUbSDQwG+AJB7CSE3wW+P78im18tWr +AidHHhcUanfYSz4mhhUambQGYB/j46lZf9ps9zHXZhagxVbZf5ar6oDeWeckcIbf +Ol7LoOth/fFCDr5mGoL04g== +-----END CERTIFICATE----- diff --git a/accounts/vault/testdata/localhost-with-san-chain.pem b/accounts/vault/testdata/localhost-with-san-chain.pem new file mode 100644 index 000000000..e21ca81c6 --- /dev/null +++ b/accounts/vault/testdata/localhost-with-san-chain.pem @@ -0,0 +1,117 @@ +-----BEGIN CERTIFICATE----- +MIIIgDCCBmigAwIBAgICEAgwDQYJKoZIhvcNAQENBQAwbzELMAkGA1UEBhMCR0Ix +EDAOBgNVBAgMB0VuZ2xhbmQxEzARBgNVBAoMClF1b3J1bSBMdGQxFDASBgNVBAsM +C1F1b3J1bSBCbXRoMSMwIQYDVQQDDBpRdW9ydW0gTHRkIEludGVybWVkaWF0ZSBD +QTAeFw0xOTAxMTYxNDI2MTVaFw0yMTAyMDQxNDI2MTVaMG8xCzAJBgNVBAYTAkdC +MRAwDgYDVQQIDAdFbmdsYW5kMRQwEgYDVQQHDAtCb3VybmVtb3V0aDETMBEGA1UE +CgwKUXVvcnVtIEx0ZDEPMA0GA1UECwwGUXVvcnVtMRIwEAYDVQQDDAlsb2NhbGhv +c3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0lM8VwNTD5up0/ZlT +/tX3aInBZ9GjZLZis+X/mx6c5scpfKqPCNn6sxADtpfoGsuvW+wvyeBKQqb6Op/q +5gp708QNFHZNxA/L/wtPZPaJNT/R/b4LJAZim+zOe/NWYkdT86iQPjxeWxO8ux+W +JMKZ85m5I9byJ7pJRegPcjh0WO3wymTs9fDN0yIs+KjXTn4W2xjiKXfGteUbwmZq +3U2Ufiz4H+yt1w7cF4YQ6V159DVzsGi4q6TECZu8xFHEyKUdI7DDY0UvZFCvuE0X +NAP2R/hxRFSLiw/XJL12xsDd2LkQXR8WJrOp3cu7P5zh9gPYuJBtFyGJGovwwHWP +82ZdAgMBAAGjggQkMIIEIDAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDAz +BglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgU2VydmVyIENlcnRpZmlj +YXRlMB0GA1UdDgQWBBQsUYyJgozCDSWSajWF2FRgAv0l3DCBwAYDVR0jBIG4MIG1 +gBSpi32woCQRbD5vTo70FZQPqE8PdqGBmKSBlTCBkjELMAkGA1UEBhMCR0IxEDAO +BgNVBAgMB0VuZ2xhbmQxFDASBgNVBAcMC0JvdXJuZW1vdXRoMRMwEQYDVQQKDApR +dW9ydW0gTHRkMSkwJwYDVQQLDCBRdW9ydW0gTHRkIENlcnRpZmljYXRlIEF1dGhv +cml0eTEbMBkGA1UEAwwSUXVvcnVtIEx0ZCBSb290IENBggIQADAOBgNVHQ8BAf8E +BAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwggLCBgNVHREEggK5MIICtYIJbG9j +YWxob3N0ghVsb2NhbGhvc3QubG9jYWxkb21haW6CEnF1b3J1bTEucXVvcnVtLm5l +dIIScXVvcnVtMi5xdW9ydW0ubmV0ghJxdW9ydW0zLnF1b3J1bS5uZXSCEnF1b3J1 +bTQucXVvcnVtLm5ldIIScXVvcnVtNS5xdW9ydW0ubmV0ghJxdW9ydW02LnF1b3J1 +bS5uZXSCEnF1b3J1bTcucXVvcnVtLm5ldIIScXVvcnVtOC5xdW9ydW0ubmV0ghJx +dW9ydW05LnF1b3J1bS5uZXSCE3F1b3J1bTEwLnF1b3J1bS5uZXSCE3Rlc3NlcmEx +LnF1b3J1bS5uZXSCE3Rlc3NlcmEyLnF1b3J1bS5uZXSCE3Rlc3NlcmEzLnF1b3J1 +bS5uZXSCE3Rlc3NlcmE0LnF1b3J1bS5uZXSCE3Rlc3NlcmE1LnF1b3J1bS5uZXSC +E3Rlc3NlcmE2LnF1b3J1bS5uZXSCE3Rlc3NlcmE3LnF1b3J1bS5uZXSCE3Rlc3Nl +cmE4LnF1b3J1bS5uZXSCE3Rlc3NlcmE5LnF1b3J1bS5uZXSCFHRlc3NlcmExMC5x +dW9ydW0ubmV0ggVub2RlMYIFbm9kZTKCBW5vZGUzggVub2RlNIIFbm9kZTWCBW5v +ZGU2ggVub2RlN4IKdHhtYW5hZ2VyMYIKdHhtYW5hZ2VyMoIKdHhtYW5hZ2VyM4IK +dHhtYW5hZ2VyNIIKdHhtYW5hZ2VyNYIKdHhtYW5hZ2VyNoIKdHhtYW5hZ2VyN4cE +fwAAAYcEfwABAYcEfwABAocEfwABA4cEfwABBIcEfwABBYcEfwABBocEfwABB4cE +fwABCIcEfwABCYcEfwABCocEfwABC4cEfwABDIcEfwABDYcEfwABDocEfwABD4cE +fwABEIcEfwABEYcEfwABEjANBgkqhkiG9w0BAQ0FAAOCAgEAaCXgWafkHZ62c2jo +kTzejGmT6a0tDnJYR5q96HcdpCfIOVvbz3tAhDq7Hr37OL2+fQe8Xdu5/RTbyhmk +2eexdzzGueHcKgSxEYppVn/sE5U49dKgzMfYndTG/9f4wcJw0QajFziMGe1v4qDy +204YE63jHd3rih6a3Ox8mI7ucB7GwFjmG+pdpXnDROm02MWZBthzmE2JuMN1oatj +8BXnbuKZcDtd67isxkCEVO656TjGL3XimBSxTe0KEJIQccAsuXAwlUUp/2Tzboe1 +MajQgEoQ14muYrddtm0zJj0eadZC2MTbHZyPNDeQr77gFlZ+WuLigDZQhK5XkNMm +CUVPCIc/aXN1PI+zLx9BKeE4z879Tyun7NVPcEdhX/xoQfdbWqixH2lRaauNLxew +ZoggxUj6Hupdkaz9or0NDM1sm28OuEnH8SCwJlS+CZgqjX4qhM5Pp7jHmnkjdRo+ +9ddsP6mCgZSGOp5dNEN7USVNVqRlnaNq7w38HAyjpCiVBRnxBHw5BE3Jx6XVakQK +QZwyKTOWyhGDiwqJCbJwvnwC2dbyZNRgDBYxCLEEA37EvI1N9xG7LWHP2b2TFxTx +bMCXj1PrR0y8/7wNa0+YIIfPXRVGN3dOD1mXZaBLwTgBqixBUFViITtBNUsu2eXd +PkeUbdTBMfdPM96Fshzf2v8F4kI= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +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 +lQKtVq+b9LK8nOxZjVLWXbvirZQ0rK59 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGDDCCA/SgAwIBAgIJAMqZvaZrhPEWMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYD +VQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEUMBIGA1UEBwwLQm91cm5lbW91dGgx +EzARBgNVBAoMClF1b3J1bSBMdGQxKTAnBgNVBAsMIFF1b3J1bSBMdGQgQ2VydGlm +aWNhdGUgQXV0aG9yaXR5MRswGQYDVQQDDBJRdW9ydW0gTHRkIFJvb3QgQ0EwHhcN +MTkwMTA5MjEwOTA4WhcNMzkwMTA0MjEwOTA4WjCBkjELMAkGA1UEBhMCR0IxEDAO +BgNVBAgMB0VuZ2xhbmQxFDASBgNVBAcMC0JvdXJuZW1vdXRoMRMwEQYDVQQKDApR +dW9ydW0gTHRkMSkwJwYDVQQLDCBRdW9ydW0gTHRkIENlcnRpZmljYXRlIEF1dGhv +cml0eTEbMBkGA1UEAwwSUXVvcnVtIEx0ZCBSb290IENBMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAuZ7qUku/uzXJSz7DkLKg+UrQXd7Bma59fqZFjnu8 +XPaqIusXOePkh3SjNWSB4TLCm/uvHlW28ljNJfro1UxSPNtNWSiyb+oTbp76C/oX +Tkf9t8Z6osMM8zWsG6wpPCvGsJ91LkN+binJQK6RALdZBNkJ9d7jNJlhJ/CWmNSd +sn47CTargMdppxL96/JhVFzFY/Yorrc9np+tRGceRcfTh4ng8m53n37HHBrb8rXd +Gk7x8UG7Lo+GAHeF1RSzzuNElwHOdbh884uZ4qejG80x/hWQxghfFtXHNj6v6Llh +lAM9rn9fi57cv8G/A+sL5u81CoQCaichDqdGX6L70XHidyO0FgJO5tJ5w6wYanb6 +Kj5HVSblH79NDI7spy9XzoVtKETo15sguCX16ZWgaEooXQEB1PkjdtYYDgIA7JCK +okvBrYEby3ygQB2rxWqfkJIzgfRC+iHLQrYEl9d5uz3tmV/rhDnA7La3BGBuKpyw +oVdBHxxF2FeSbLHewfg6KXkVUGZEhx1MsKmI8+3ktFs+EOQdocoFHznX5niEIOIU +AynYJMTAZEAy1f0JuZHIwoMwnLLEjbqlPC9PgVDoUZHugAa36VSRBvWhJvWx81db +3DbY2wyQ8jGS920sRlVTswBARNDUyPpIpez7+M0KlhJ79p2rl+JyPnbMWgJn+Uet +Up0CAwEAAaNjMGEwHQYDVR0OBBYEFF6uedlS+J83omsSQx55AK99dMv5MB8GA1Ud +IwQYMBaAFF6uedlS+J83omsSQx55AK99dMv5MA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBuK9O23LSLwCkixn9OcfnD +QWhIQubLkc9AB1BytowYYhkpOKzGBTUK70zyS+dBTd8OxWsWyOLCgwIpZJwc8IcT +vk8F6/+q7qrJ+XCz/xp+R+XJK4XP+re/Lh/iGYXH0NovFzo3aXqUtvZFfdLWe65L +9RT6qlkol4MM7pXMtr014nv26H7R74eI2YfizIKgkBuhYCrNTjjs3A/qnCepsFn1 +xy6MZfDLtkH9wb4bd/UaCiuhFvM/t1cwz+94Y3wTj79aKD4Y01+Tfy0yWN8F0iDW +PS3mxlhl7bBZ4OOtCwZLm73f/3KymhGgAjeSH6C4BoizBjVMzYfXDwP7CgrwgfHN +26me2OpQV9pl0bCtXo+C0oIC4nWDayls7b0QouFiUP7F2pO96fvyUmztFn9XuF3E +jmJ6VtrpWe2ZbNoWVyIciZNf7QK2wkKkolh+TbVZ/AoSfdmTX0uS6/JtiQwB8dtC ++lOCApON84fDZYCMCeKhj08zanVfmeKWwqE1wR6qP2w4WXuNdHorDwlR8I4eXT+p +qQ552wAJA3CSbkOn1inVjgyLoGQFFYKRwABUbSDQwG+AJB7CSE3wW+P78im18tWr +AidHHhcUanfYSz4mhhUambQGYB/j46lZf9ps9zHXZhagxVbZf5ar6oDeWeckcIbf +Ol7LoOth/fFCDr5mGoL04g== +-----END CERTIFICATE----- diff --git a/accounts/vault/testdata/localhost-with-san.key b/accounts/vault/testdata/localhost-with-san.key new file mode 100644 index 000000000..31c818b72 --- /dev/null +++ b/accounts/vault/testdata/localhost-with-san.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAtJTPFcDUw+bqdP2ZU/7V92iJwWfRo2S2YrPl/5senObHKXyq +jwjZ+rMQA7aX6BrLr1vsL8ngSkKm+jqf6uYKe9PEDRR2TcQPy/8LT2T2iTU/0f2+ +CyQGYpvsznvzVmJHU/OokD48XlsTvLsfliTCmfOZuSPW8ie6SUXoD3I4dFjt8Mpk +7PXwzdMiLPio105+FtsY4il3xrXlG8Jmat1NlH4s+B/srdcO3BeGEOldefQ1c7Bo +uKukxAmbvMRRxMilHSOww2NFL2RQr7hNFzQD9kf4cURUi4sP1yS9dsbA3di5EF0f +Fiazqd3Luz+c4fYD2LiQbRchiRqL8MB1j/NmXQIDAQABAoIBAFB2pjeZLrUD5aCv +h2yn9otBZ3BoZD8cFzCv3GIiqmdbZY8U36LQXOCafR5KdDGWDwBaQ0mf+HLedCy3 +hp5SVoWKfKcfYP+Rx0Asqst7v2av9XoKSG4KZVX3CHORQ4JQVFwSDCAJuziH+Kl1 +78MlKhkTNIIMeDB6h0UzAw4u5PziC2R8MbQmPhBS2HF/xftU0BEtvb+LTGNBu/mF +HTDUbnR9yk2SNtIy3tAJwMARMnBohZaZevfBVYKCiyINdxdr03H9uLwd22Qa+ygS +EZiBctgQ/MsXPNvM7jTXDPUHUAx50FJSEsRmVOBIFCTpWt9vYI6Ui4qNT7fY+Eih +Dbt7fIECgYEA4+ZGqj6udE7n2jZsLa4WUA9F1FQUD5ZmxItzP80AwcZRm+oa5HOe +ok8nxConVhD6dxTwO3cRxF2Q44+CtLCbBiy8q0auO11H9tO3YzDBXYzcf3pfbDQB +iLgavKGzI2kciFkuapuvxk6jPOmwwM84O4JvnrnDoee/ffasxsOOme0CgYEAytjq +zelZOlawtslUQdX3MKjfCenKMNl8AEHAaHikZN+49ttzJ1zMW+dZeYtJ2l8CJFma +qOxsQxPfd1oVQzJYM3aOGKJ32jOJ4uxr2cPGnxrSFf1dFFu6vjZLXkPmkC9yGy8N +avDNkHX+SwbzV+tylVnwjxpBVPrSHs/l75iJsDECgYEAl9vb/plh+hKSIC/fidjU ++WgT6dZUv8ZCmHkrxLm/5V9XBgPLA6ufaxw/rVFBgPIzU6JaKeW/qw+F+nyoZerA +gi7RUXf5pYkU6P5O1wOn9cRlMXTDnQBSfV3gQw2kptXls11ptpQjXosL7wzxQKlU +GSNjaWrzVzFrwm3a11976EkCgYAj7oLBUNl+bQbGiilDtDwiQXeo0OIA/zVo8jy8 +BMrSF5MzHzJpwZVtnjCKSDMf3H6Lo9eynpaa1zVZdfqYOZ3IF/MZyAXFACYnrUt5 +eqV/X4fhX00SoyEUOpflLc/0sILc79vHmro/IbeW4LdQVqOocxMatkLmY7u+u4L2 +iyWwsQKBgASxpYGLQ2rxmhUZ1YrS4jT3qQQO3cF0+mh2U8mx3jPYihzY4fhVOZr3 +sU5nWai3lqxzke0luRe5afTHaREvBdHYnxhfGd6bt1a8bB4xhTyR0SngPgoKv2Em +lXyMEaHcrN4Is+PGq03y2gqs/gavIYsIKYsYSj/FY10r6uwJ22eO +-----END RSA PRIVATE KEY----- diff --git a/accounts/vault/testdata/quorum-client-chain.pem b/accounts/vault/testdata/quorum-client-chain.pem new file mode 100644 index 000000000..261bd5e2c --- /dev/null +++ b/accounts/vault/testdata/quorum-client-chain.pem @@ -0,0 +1,99 @@ +-----BEGIN CERTIFICATE----- +MIIFJDCCAwygAwIBAgICEAYwDQYJKoZIhvcNAQENBQAwbzELMAkGA1UEBhMCR0Ix +EDAOBgNVBAgMB0VuZ2xhbmQxEzARBgNVBAoMClF1b3J1bSBMdGQxFDASBgNVBAsM +C1F1b3J1bSBCbXRoMSMwIQYDVQQDDBpRdW9ydW0gTHRkIEludGVybWVkaWF0ZSBD +QTAeFw0xOTAxMTYxMDU0MjRaFw0yMTAyMDQxMDU0MjRaMHMxCzAJBgNVBAYTAkdC +MRAwDgYDVQQIDAdFbmdsYW5kMRQwEgYDVQQHDAtCb3VybmVtb3V0aDETMBEGA1UE +CgwKUXVvcnVtIEx0ZDEPMA0GA1UECwwGUXVvcnVtMRYwFAYDVQQDDA1xdW9ydW0t +Y2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAogskfL7U9DKv +9rB8Xl7zsjl4aFVmACMjMmplNEinpuJ5BzbYhYadnnEN8CMPFjQUovCoL7kErStI +GuVPaeeLF5hnlyTg/umU3X28UiJTstcgpkMl++yD5GONQrWYDyjh8+RVpeY4+dh1 +EGjdtc88ofUIGK08JNr672ybXhB89mck8j6vc6bzTyJ+TT6gPdukRqfEyZmhzuXM +qh6GyXoOAEHR2RcwYNk4XY/2I87nnZ5W23Mt0oFpE7t2FbP1DwVERiilBb5///+p +/PNoaXZUmsgv6qQYYH4+W26QXTSWvHHNxC/wd+/E/y8QrzHU6WJqPnIAU7mrH9j8 +QGbcwVYfFQIDAQABo4HFMIHCMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgWg +MDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBDbGllbnQgQ2VydGlm +aWNhdGUwHQYDVR0OBBYEFAebrJy7j4e39Svfy6RrT093M4AzMB8GA1UdIwQYMBaA +FKmLfbCgJBFsPm9OjvQVlA+oTw92MA4GA1UdDwEB/wQEAwIF4DAdBgNVHSUEFjAU +BggrBgEFBQcDAgYIKwYBBQUHAwQwDQYJKoZIhvcNAQENBQADggIBAMn5KqT+kG8r +Kitw/sEhMWxwxWqGztJKFcQy9YzeLCAbJVC95RO5YTiszSy1Tt7Ov8W3HqTJaNXt +Jcfek0Fqf6Y/GvDYYkXXAoP4MVW7Y3s0ONSue+cJUnPQwrKMQRDCVyy3gji1n9kZ +ulk0W9L2vFSOafkPXatDEAaN6xkD1IPmcFXsrrZ9WZSAhMngHJxRJdI/5eDvqXnw +hTMBiobI6mbxOC94Pv/kDxtCz6S51hQgjnwA0GWRNRMTt0YpbaojK62aGKyxdOUu +kfKHxLYq2rTmw6TeEHFiBR1zRDygeIDg/IVlXyfsrB48adTQuGsXe4EUv/bUw5wM +mRt78q3LZ5gk87iV3jBXhPsGuff7XK+c0GG9RbsF3o/Rlb/BYfi87AmgryaMLtmi +P8Cuxzws1mom6QN9Me81vEU2fCXOeTt1Y8dqohM8SP8U16FQCu/w4id5ESlzQxOL +jzPxMDv+GY/Lub9nkTcBuXD6mmswBu3dGcqQKJK1pZKuNjwO2RMaPsgQpLEMm+GG +iQoN4RaqxKIjfsN6bbeEsYUOJEEgr447H9vvZ+5a91IfjQefrS2oHi6UvNVpt3Se +cw3wXUXcGPBqP3w71EF6z3AsiWPd0SSuslwIn06w7unOEFd57ju7k/kvwC3ksccY +gFAqQ/hFlF6wgAF0lqQ6EE8gpJTgwfcr +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +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 +lQKtVq+b9LK8nOxZjVLWXbvirZQ0rK59 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGDDCCA/SgAwIBAgIJAMqZvaZrhPEWMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYD +VQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEUMBIGA1UEBwwLQm91cm5lbW91dGgx +EzARBgNVBAoMClF1b3J1bSBMdGQxKTAnBgNVBAsMIFF1b3J1bSBMdGQgQ2VydGlm +aWNhdGUgQXV0aG9yaXR5MRswGQYDVQQDDBJRdW9ydW0gTHRkIFJvb3QgQ0EwHhcN +MTkwMTA5MjEwOTA4WhcNMzkwMTA0MjEwOTA4WjCBkjELMAkGA1UEBhMCR0IxEDAO +BgNVBAgMB0VuZ2xhbmQxFDASBgNVBAcMC0JvdXJuZW1vdXRoMRMwEQYDVQQKDApR +dW9ydW0gTHRkMSkwJwYDVQQLDCBRdW9ydW0gTHRkIENlcnRpZmljYXRlIEF1dGhv +cml0eTEbMBkGA1UEAwwSUXVvcnVtIEx0ZCBSb290IENBMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAuZ7qUku/uzXJSz7DkLKg+UrQXd7Bma59fqZFjnu8 +XPaqIusXOePkh3SjNWSB4TLCm/uvHlW28ljNJfro1UxSPNtNWSiyb+oTbp76C/oX +Tkf9t8Z6osMM8zWsG6wpPCvGsJ91LkN+binJQK6RALdZBNkJ9d7jNJlhJ/CWmNSd +sn47CTargMdppxL96/JhVFzFY/Yorrc9np+tRGceRcfTh4ng8m53n37HHBrb8rXd +Gk7x8UG7Lo+GAHeF1RSzzuNElwHOdbh884uZ4qejG80x/hWQxghfFtXHNj6v6Llh +lAM9rn9fi57cv8G/A+sL5u81CoQCaichDqdGX6L70XHidyO0FgJO5tJ5w6wYanb6 +Kj5HVSblH79NDI7spy9XzoVtKETo15sguCX16ZWgaEooXQEB1PkjdtYYDgIA7JCK +okvBrYEby3ygQB2rxWqfkJIzgfRC+iHLQrYEl9d5uz3tmV/rhDnA7La3BGBuKpyw +oVdBHxxF2FeSbLHewfg6KXkVUGZEhx1MsKmI8+3ktFs+EOQdocoFHznX5niEIOIU +AynYJMTAZEAy1f0JuZHIwoMwnLLEjbqlPC9PgVDoUZHugAa36VSRBvWhJvWx81db +3DbY2wyQ8jGS920sRlVTswBARNDUyPpIpez7+M0KlhJ79p2rl+JyPnbMWgJn+Uet +Up0CAwEAAaNjMGEwHQYDVR0OBBYEFF6uedlS+J83omsSQx55AK99dMv5MB8GA1Ud +IwQYMBaAFF6uedlS+J83omsSQx55AK99dMv5MA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBuK9O23LSLwCkixn9OcfnD +QWhIQubLkc9AB1BytowYYhkpOKzGBTUK70zyS+dBTd8OxWsWyOLCgwIpZJwc8IcT +vk8F6/+q7qrJ+XCz/xp+R+XJK4XP+re/Lh/iGYXH0NovFzo3aXqUtvZFfdLWe65L +9RT6qlkol4MM7pXMtr014nv26H7R74eI2YfizIKgkBuhYCrNTjjs3A/qnCepsFn1 +xy6MZfDLtkH9wb4bd/UaCiuhFvM/t1cwz+94Y3wTj79aKD4Y01+Tfy0yWN8F0iDW +PS3mxlhl7bBZ4OOtCwZLm73f/3KymhGgAjeSH6C4BoizBjVMzYfXDwP7CgrwgfHN +26me2OpQV9pl0bCtXo+C0oIC4nWDayls7b0QouFiUP7F2pO96fvyUmztFn9XuF3E +jmJ6VtrpWe2ZbNoWVyIciZNf7QK2wkKkolh+TbVZ/AoSfdmTX0uS6/JtiQwB8dtC ++lOCApON84fDZYCMCeKhj08zanVfmeKWwqE1wR6qP2w4WXuNdHorDwlR8I4eXT+p +qQ552wAJA3CSbkOn1inVjgyLoGQFFYKRwABUbSDQwG+AJB7CSE3wW+P78im18tWr +AidHHhcUanfYSz4mhhUambQGYB/j46lZf9ps9zHXZhagxVbZf5ar6oDeWeckcIbf +Ol7LoOth/fFCDr5mGoL04g== +-----END CERTIFICATE----- diff --git a/accounts/vault/testdata/quorum-client.key b/accounts/vault/testdata/quorum-client.key new file mode 100644 index 000000000..49845787a --- /dev/null +++ b/accounts/vault/testdata/quorum-client.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAogskfL7U9DKv9rB8Xl7zsjl4aFVmACMjMmplNEinpuJ5BzbY +hYadnnEN8CMPFjQUovCoL7kErStIGuVPaeeLF5hnlyTg/umU3X28UiJTstcgpkMl +++yD5GONQrWYDyjh8+RVpeY4+dh1EGjdtc88ofUIGK08JNr672ybXhB89mck8j6v +c6bzTyJ+TT6gPdukRqfEyZmhzuXMqh6GyXoOAEHR2RcwYNk4XY/2I87nnZ5W23Mt +0oFpE7t2FbP1DwVERiilBb5///+p/PNoaXZUmsgv6qQYYH4+W26QXTSWvHHNxC/w +d+/E/y8QrzHU6WJqPnIAU7mrH9j8QGbcwVYfFQIDAQABAoIBAB3/3BhwJ/Kxs5wD +HnNGNu2m8CC4trKNzsVVpzjfvpIJ2Yg5YiqOOn4Lxh3QD8n3iF6GGU0EftYkbiv0 +ihg8MqcCoyL7Q+BNlC7RSV0XV9GDPFsrkUurhNtyhsNz5RvhYLuLaUPWdHPk2/9W +ur0fCcWeHIqc/8Z+9/f9bmIiwU/Iiz+aF4PG/5QSGzhUg8SGNGvr11WuxJj4xcLE +GwyR5hfpZjIz7hGp8Zf2VRu0/vJQW9b17Xih1yWKFE5foTP/xKRWaw8CTIaXLbFr +A1nkpIPUC0YYQaBoFtodRjwLbHLMrOCaPxSpPj9lvWvR3xI6abbBhScVJHqEPs/G +CYSgjCECgYEA0Y6cpeFZcsmQEdBYPL4A9yKypqc4pTAn+TA6Et0o4o0oTrJesJqm +6zVHz1VFpnWeQyxQWnjVKQvJXH6Jins3/Gx3XHuhicazTH7fOqn+vNh7o4uJNrPD +dgwIvktP/DO8jutf40vI1639Dv5HrXiug0JDEwz0/JV7ndiyJPfcClkCgYEAxfTP +sbdM51vzCDwsHtHeU+MSL/kwxMEQA6KIZlIfh527N2maeASmk0B2odutzl5Ym2kM +aKjU3wzAafhPHgPiB25xTSa6Ht0e9ADsQ2tHxdSPMw3x+bw4/n1D7W3fcemtuETB +SdtFWrm+V9QU0cucNXNTv1SE2BJLHF0C/aeMKx0CgYB/H+Gdq7hEr0wr0lVE/Aq/ +4Ze5C6aMZ0tImt4QBYRA81rpasGQpzDtbRQUDenD0oRgwag5SiYd0V2lM8oibR+I +jRBX1VQorZalqC2pe+jiDP3sN8DUo3bGzQQc1LlACO6xUM6Jp7a+SHlEuDMpZBWR +4QepremMtO4Z0pQ3YvlkeQKBgQCbWUbQ+b+BZRhxov8g5KQsguuX+F/8WGJf5+JR +IiuaOv9cOiS+ATBUKOewl/xrEoFI3QSe8be0n4Y042f7byKnoFWMLVMsu2z6IetH +8V3u86O5dj0qNjsoBFgVcP9EnxT0oghqFIj17QRiWo5IIhihnbLgWMyz4I9PX/Lj +6uPGRQKBgG8mdEppChhH3rWGJLfCkNewH2bhROXQOtJmtm1Wmyxn21qKgi3dYoX3 +cTgCAdjUH5eZpPl4NkBBp+4K1qAvsOyxwaCCtGHBA3lxF5emY8hVwXYUU2NJjH21 +9qolZWhEPlZ0zXLIui486x8YLj11AWnlNKnQKzKnhqtPQElNwjsq +-----END RSA PRIVATE KEY----- diff --git a/accounts/vault/vault_wallet.go b/accounts/vault/vault_wallet.go index 70b72c67d..ae34a82ac 100644 --- a/accounts/vault/vault_wallet.go +++ b/accounts/vault/vault_wallet.go @@ -18,6 +18,7 @@ type vaultWallet struct { // vault related behaviour that will be specific to each vault type type vaultService interface { status() (string, error) + open() error } func newHashicorpWallet(config hashicorpWalletConfig) (vaultWallet, error) { @@ -30,29 +31,20 @@ func newHashicorpWallet(config hashicorpWalletConfig) (vaultWallet, error) { return vaultWallet{}, err } - return vaultWallet{url: url, vault: hashicorpService{}}, nil + return vaultWallet{url: url, vault: &hashicorpService{config: config.Client}}, nil } func (w vaultWallet) URL() accounts.URL { return w.url } -const ( - open = "open" - closed = "closed" -) - // the vault service should return open and nil error if status is good func (w vaultWallet) Status() (string, error) { - if w.vault == nil { - return closed, nil - } - return w.vault.status() } func (w vaultWallet) Open(passphrase string) error { - panic("implement me") + return w.vault.open() } func (w vaultWallet) Close() error { @@ -93,9 +85,12 @@ func (w vaultWallet) SignTxWithPassphrase(account accounts.Account, passphrase s type hashicorpService struct { client *api.Client + config hashicorpClientConfig } const ( + open = "open" + closed = "closed" hashicorpHealthcheckFailed = "Hashicorp Vault healthcheck failed" hashicorpUninitialized = "Hashicorp Vault uninitialized" hashicorpSealed = "Hashicorp Vault sealed" @@ -114,8 +109,12 @@ func (e hashicorpHealthcheckErr) Error() string { return fmt.Sprintf("%v: %v", hashicorpHealthcheckFailed, e.err) } -func (c hashicorpService) status() (string, error) { - health, err := c.client.Sys().Health() +func (h *hashicorpService) status() (string, error) { + if h.client == nil { + return closed, nil + } + + health, err := h.client.Sys().Health() if err != nil { return hashicorpHealthcheckFailed, hashicorpHealthcheckErr{err: err} @@ -131,3 +130,32 @@ func (c hashicorpService) status() (string, error) { return open, nil } + +func (h *hashicorpService) open() error { + if h.client != nil { + return accounts.ErrWalletAlreadyOpen + } + + conf := api.DefaultConfig() + conf.Address = h.config.Url + + tlsConfig := &api.TLSConfig{ + CACert: h.config.CaCert, + ClientCert: h.config.ClientCert, + ClientKey: h.config.ClientKey, + } + + if err := conf.ConfigureTLS(tlsConfig); err != nil { + return fmt.Errorf("error creating Hashicorp client: %v", err) + } + + c, err := api.NewClient(conf) + + if err != nil { + return fmt.Errorf("error creating Hashicorp client: %v", err) + } + + h.client = c + + return nil +} diff --git a/accounts/vault/vault_wallet_test.go b/accounts/vault/vault_wallet_test.go index ee901b5af..73a9c7268 100644 --- a/accounts/vault/vault_wallet_test.go +++ b/accounts/vault/vault_wallet_test.go @@ -1,11 +1,15 @@ package vault import ( + "crypto/tls" + "crypto/x509" "encoding/json" "github.com/ethereum/go-ethereum/accounts" "github.com/hashicorp/vault/api" + "io/ioutil" "net/http" "net/http/httptest" + "reflect" "testing" ) @@ -20,20 +24,6 @@ func TestVaultWallet_URL(t *testing.T) { } } -func TestVaultWallet_Status_ClosedWhenNoVaultService(t *testing.T) { - w := vaultWallet{} - - status, err := w.Status() - - if err != nil { - t.Fatal(err) - } - - if status != closed { - t.Fatalf("want: %v, got: %v", closed, status) - } -} - // makeMockHashicorpService creates a new httptest.Server which responds with mockResponse for all requests. A default Hashicorp api.Client with URL updated with the httptest.Server's URL is returned. The Close() function for the httptest.Server and should be executed before test completion (probably best to defer as soon as it is returned) func makeMockHashicorpClient(t *testing.T, mockResponse []byte) (*api.Client, func()) { vaultServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -52,7 +42,21 @@ func makeMockHashicorpClient(t *testing.T, mockResponse []byte) (*api.Client, fu return client, vaultServer.Close } -func TestVaultWallet_Status_HashicorpHealthcheckSuccessful(t *testing.T) { +func TestVaultWallet_Status_Hashicorp_ClosedWhenServiceHasNoClient(t *testing.T) { + w := vaultWallet{vault: &hashicorpService{}} + + status, err := w.Status() + + if err != nil { + t.Fatal(err) + } + + if status != closed { + t.Fatalf("want: %v, got: %v", closed, status) + } +} + +func TestVaultWallet_Status_Hashicorp_HealthcheckSuccessful(t *testing.T) { const ( uninitialised = "uninitialized" sealed = "sealed" @@ -99,7 +103,7 @@ func TestVaultWallet_Status_HashicorpHealthcheckSuccessful(t *testing.T) { defer cleanup() w := vaultWallet{ - vault: hashicorpService{client: c}, + vault: &hashicorpService{client: c}, } status, err := w.Status() @@ -115,14 +119,14 @@ func TestVaultWallet_Status_HashicorpHealthcheckSuccessful(t *testing.T) { } } -func TestVaultWallet_Status_HashicorpHealthcheckFailed(t *testing.T) { +func TestVaultWallet_Status_Hashicorp_HealthcheckFailed(t *testing.T) { b := []byte("this is not the bytes for an api.HealthResponse and will cause a client error") c, cleanup := makeMockHashicorpClient(t, b) defer cleanup() w := vaultWallet{ - vault: hashicorpService{client: c}, + vault: &hashicorpService{client: c}, } status, err := w.Status() @@ -135,3 +139,158 @@ func TestVaultWallet_Status_HashicorpHealthcheckFailed(t *testing.T) { t.Fatalf("want: %v, got: %v", hashicorpHealthcheckFailed, status) } } + +func TestVaultWallet_Open_Hashicorp_ReturnsErrIfAlreadyOpen(t *testing.T) { + w := vaultWallet{vault: &hashicorpService{client: &api.Client{}}} + + if err := w.Open(""); err != accounts.ErrWalletAlreadyOpen { + t.Fatalf("want: %v, got: %v", accounts.ErrWalletAlreadyOpen, err) + } +} + +func TestVaultWallet_Open_Hashicorp_CreatesClientFromConfig(t *testing.T) { + // create mock server which responds to all requests with the same response + mockResponse := api.Secret{RequestID: "myrequestid"} + b, err := json.Marshal(mockResponse) + + if err != nil { + t.Fatal(err) + } + + vaultServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(b) + })) + defer vaultServer.Close() + + config := hashicorpClientConfig{ + Url: vaultServer.URL, + } + + w := vaultWallet{vault: &hashicorpService{config: config}} + + if err := w.Open(""); err != nil { + t.Fatalf("error: %v", err) + } + + v, ok := w.vault.(*hashicorpService) + + if !ok { + t.Fatal("type assertion failed") + } + + got := v.client + + if got == nil { + t.Fatal("client not created") + } + + if got.Address() != vaultServer.URL { + t.Fatalf("address: want: %v, got: %v", vaultServer.URL, got.Address()) + } + + // make a request to the vault server using the client to verify client config was correctly applied + resp, err := got.Logical().Read("vaultpath/to/secret") + + if err != nil { + t.Fatalf("error making request using created client: %v", err) + } + + if !reflect.DeepEqual(mockResponse, *resp) { + t.Fatalf("response not as expected\nwant: %v\ngot : %v", mockResponse, resp) + } +} + +func TestVaultWallet_Open_Hashicorp_CreatesTLSClientFromConfig(t *testing.T) { + // create mock server which responds to all requests with an empty secret + mockResponse := api.Secret{} + b, err := json.Marshal(mockResponse) + + if err != nil { + t.Fatal(err) + } + + vaultServer := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write(b) + })) + + // read TLS certs + rootCert, err := ioutil.ReadFile("testdata/caRoot.pem") + + if err != nil { + t.Error(err) + } + + certPool := x509.NewCertPool() + certPool.AppendCertsFromPEM(rootCert) + + cert, err := ioutil.ReadFile("testdata/localhost-with-san-chain.pem") + + if err != nil { + t.Error(err) + } + + key, err := ioutil.ReadFile("testdata/localhost-with-san.key") + + if err != nil { + t.Error(err) + } + + keypair, err := tls.X509KeyPair(cert, key) + + if err != nil { + t.Error(err) + } + + serverTlsConfig := &tls.Config{ + Certificates: []tls.Certificate{keypair}, + ClientAuth: tls.RequireAnyClientCert, + ClientCAs: certPool, + } + + // add TLS config to server and start + vaultServer.TLS = serverTlsConfig + + vaultServer.StartTLS() + defer vaultServer.Close() + + // create wallet with config and open + config := hashicorpClientConfig{ + Url: vaultServer.URL, + //Approle: "myapprole", + CaCert: "testdata/caRoot.pem", + ClientCert: "testdata/quorum-client-chain.pem", + ClientKey: "testdata/quorum-client.key", + //EnvVarPrefix: "prefix", + //UseSecretCache: false, + } + + w := vaultWallet{vault: &hashicorpService{config: config}} + + if err := w.Open(""); err != nil { + t.Fatalf("error: %v", err) + } + + // verify created client uses config + v, ok := w.vault.(*hashicorpService) + + if !ok { + t.Fatal("type assertion failed") + } + + got := v.client + + if got == nil { + t.Fatal("client not created") + } + + if got.Address() != vaultServer.URL { + t.Fatalf("address: want: %v, got: %v", vaultServer.URL, got.Address()) + } + + // make a request to the vault server using the client - if TLS was applied correctly on the client then the request will be allowed + // TODO test passes even if vault client config contains no TLS certs + if _, err := got.Logical().Read("vaultpath/to/secret"); err != nil { + t.Fatalf("error making request using created client: %v", err) + } +} +