Commits

Will Glozer committed 1381549

add test for connecting with SSL client cert

  • Participants
  • Parent commits 48a40f0
  • Tags 1.1

Comments (0)

Files changed (7)

File test_data/epgsql.crt

+-----BEGIN CERTIFICATE-----
+MIIC6jCCAlOgAwIBAgIJAKwIWpOFC5EWMA0GCSqGSIb3DQEBBQUAMGQxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp
+c2NvMRQwEgYDVQQKEwtsYW1iZGFXb3JrczESMBAGA1UEAxMJZXBnc3FsIENBMB4X
+DTA5MDMyNzA0MzAxM1oXDTE5MDIwMzA0MzAxM1owazELMAkGA1UEBhMCVVMxEzAR
+BgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xFDASBgNV
+BAoTC2xhbWJkYVdvcmtzMRkwFwYDVQQDFBBlcGdzcWxfdGVzdF9jZXJ0MIGfMA0G
+CSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxnVk30edKqkIWWzTeWJHlc5Zco5MASAqz
+J6fC4HmR4y+StFB88NZE/ESKbWXNOD464fku72m5i4DI1NftGgZLVjjrFmLEE05S
+hymkqWtVb+H9RBD2SHl4VjwDUsMDHZGiXL3n02uWF+NtpeQHkacfav10ZQO0nnub
+njCUV3EHoQIDAQABo4GcMIGZMIGWBgNVHSMEgY4wgYuAFO5OzTWlO3ao7YAytIBW
+A3A1GXDaoWikZjBkMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEW
+MBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEUMBIGA1UEChMLbGFtYmRhV29ya3MxEjAQ
+BgNVBAMTCWVwZ3NxbCBDQYIJAIFM8k/soL/qMA0GCSqGSIb3DQEBBQUAA4GBAHhy
+nE3/U1DiqHNf+AaCktVoHlsjfXvfrhouqR7T84kxCjAHzM6q183ga4S9NhLeyhCT
+oiDnIoUlUg7v1h9wTvXAoO2NwkCpSbIUncj6Q2h6J8obWq/BDSJwbdPcCHe4un8P
+hEpkiEK1QMMm5h9d+jgE8mrgGZXMnvzw40ovJHON
+-----END CERTIFICATE-----

File test_data/epgsql.key

+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQCxnVk30edKqkIWWzTeWJHlc5Zco5MASAqzJ6fC4HmR4y+StFB8
+8NZE/ESKbWXNOD464fku72m5i4DI1NftGgZLVjjrFmLEE05ShymkqWtVb+H9RBD2
+SHl4VjwDUsMDHZGiXL3n02uWF+NtpeQHkacfav10ZQO0nnubnjCUV3EHoQIDAQAB
+AoGARXSemvF+XPhPd6aa+gfwpaWZuwhMR+PkK0Lqm45ke+Q3ikrw3qrfX4K22tsE
+4EeKLkSHyQ7ebSxcZCy3c4SlyNES88wk7epGYbui4L0Iv/1WXfg1zIRqdNgBMr6M
+ZUZoUJx1gyRY2S3zGjTBn8b4Wh9EwsD0KTluvtH74DtLPQECQQDiLhIVasTsgKpn
+SoLVJ+UqpQ8oe17m4gHbwMOK2s+o479oKuAbmwgUX8U2waoncq06vG+x3gziVIOF
+Qkj6s6rZAkEAyQgfN01SoNOwp61Nis8TWeltqZdh0VHYqpu/ARfUpsTAWHGhc4eK
+Ee+J1DmxrUAP+s25Z640Ps9jNTugrWB2CQJBAJ+XyHTKQKdsZlC517VWEDLWAusa
+mi0pvgv0aUW5/Zr7EJ0M29M+wiW2Ke7oGgr5tNfkDKAhwU+WOLM3wUz8p4kCQQCr
+5zcSShtzDTINYCNjpElO5E3y7FEn9g4Jbd7550/fP3We66P8r5VAWw4IHUGy/Yns
+lIiLgSqJ3ztdZNy0BT1JAkEAhPz9yMZN7NBfdTjM1ebp4VirL8uQAdod/d3oRN87
+dqVxywRm4dZ4hMD2Fr6CuLsZylCQKEt1jNEfjZzRC4hR2g==
+-----END RSA PRIVATE KEY-----

File test_data/root.crt

+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            81:4c:f2:4f:ec:a0:bf:ea
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=US, ST=California, L=San Francisco, O=lambdaWorks, CN=epgsql CA
+        Validity
+            Not Before: Mar 27 03:52:34 2009 GMT
+            Not After : Feb  3 03:52:34 2019 GMT
+        Subject: C=US, ST=California, L=San Francisco, O=lambdaWorks, CN=epgsql CA
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1024 bit)
+                Modulus (1024 bit):
+                    00:bd:03:59:e5:ce:5d:24:45:ae:bf:cd:a4:4a:d4:
+                    33:7a:48:08:79:8a:20:4c:b6:28:51:f8:f0:9a:1d:
+                    1e:fb:b8:de:a3:b7:10:95:d7:a3:58:b7:94:b4:7e:
+                    36:0a:0c:68:1c:e8:21:a5:5d:9d:0a:3a:5d:26:dd:
+                    bb:5b:62:59:e0:1f:b8:48:a7:3d:28:dd:f3:b9:de:
+                    27:d7:25:4b:f6:8a:ac:ef:a3:0e:b3:fb:1b:b8:dd:
+                    db:01:72:01:1f:79:5b:f8:c3:54:7e:1a:94:68:1d:
+                    81:2c:05:11:05:2c:5b:81:05:21:19:c0:c7:94:4f:
+                    77:f5:76:4c:98:8d:ab:68:5b
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                EE:4E:CD:35:A5:3B:76:A8:ED:80:32:B4:80:56:03:70:35:19:70:DA
+            X509v3 Authority Key Identifier: 
+                keyid:EE:4E:CD:35:A5:3B:76:A8:ED:80:32:B4:80:56:03:70:35:19:70:DA
+                DirName:/C=US/ST=California/L=San Francisco/O=lambdaWorks/CN=epgsql CA
+                serial:81:4C:F2:4F:EC:A0:BF:EA
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+        27:4c:04:ee:27:46:23:9b:6f:7c:8f:5b:9e:c6:65:74:33:40:
+        06:be:ca:e0:55:91:1c:9e:1c:77:27:82:03:4e:67:91:5d:14:
+        e4:74:b7:88:9e:49:d6:02:5b:71:94:b3:62:2a:5e:58:00:7d:
+        8c:42:09:db:ca:27:20:71:33:16:09:d2:17:36:d4:4f:63:09:
+        0a:48:80:d7:36:13:24:57:e3:7a:7e:25:4e:b8:f0:71:c6:34:
+        69:4e:e1:4b:5a:ec:b3:be:14:78:1e:af:85:b2:56:91:62:03:
+        6b:b2:85:2e:8e:ef:4b:5a:bf:ac:54:43:24:cb:0e:c6:f8:58:
+        b5:a1
+-----BEGIN CERTIFICATE-----
+MIIDEDCCAnmgAwIBAgIJAIFM8k/soL/qMA0GCSqGSIb3DQEBBQUAMGQxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp
+c2NvMRQwEgYDVQQKEwtsYW1iZGFXb3JrczESMBAGA1UEAxMJZXBnc3FsIENBMB4X
+DTA5MDMyNzAzNTIzNFoXDTE5MDIwMzAzNTIzNFowZDELMAkGA1UEBhMCVVMxEzAR
+BgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xFDASBgNV
+BAoTC2xhbWJkYVdvcmtzMRIwEAYDVQQDEwllcGdzcWwgQ0EwgZ8wDQYJKoZIhvcN
+AQEBBQADgY0AMIGJAoGBAL0DWeXOXSRFrr/NpErUM3pICHmKIEy2KFH48JodHvu4
+3qO3EJXXo1i3lLR+NgoMaBzoIaVdnQo6XSbdu1tiWeAfuEinPSjd87neJ9clS/aK
+rO+jDrP7G7jd2wFyAR95W/jDVH4alGgdgSwFEQUsW4EFIRnAx5RPd/V2TJiNq2hb
+AgMBAAGjgckwgcYwHQYDVR0OBBYEFO5OzTWlO3ao7YAytIBWA3A1GXDaMIGWBgNV
+HSMEgY4wgYuAFO5OzTWlO3ao7YAytIBWA3A1GXDaoWikZjBkMQswCQYDVQQGEwJV
+UzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEU
+MBIGA1UEChMLbGFtYmRhV29ya3MxEjAQBgNVBAMTCWVwZ3NxbCBDQYIJAIFM8k/s
+oL/qMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAJ0wE7idGI5tvfI9b
+nsZldDNABr7K4FWRHJ4cdyeCA05nkV0U5HS3iJ5J1gJbcZSzYipeWAB9jEIJ28on
+IHEzFgnSFzbUT2MJCkiA1zYTJFfjen4lTrjwccY0aU7hS1rss74UeB6vhbJWkWID
+a7KFLo7vS1q/rFRDJMsOxvhYtaE=
+-----END CERTIFICATE-----

File test_data/root.key

+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQC9A1nlzl0kRa6/zaRK1DN6SAh5iiBMtihR+PCaHR77uN6jtxCV
+16NYt5S0fjYKDGgc6CGlXZ0KOl0m3btbYlngH7hIpz0o3fO53ifXJUv2iqzvow6z
++xu43dsBcgEfeVv4w1R+GpRoHYEsBREFLFuBBSEZwMeUT3f1dkyYjatoWwIDAQAB
+AoGBAKg3UUyayn47nfiJtgv6qw3LCe/RJEnhXCUIHmmqPSbeMxcVF6ej0HZme+ve
+34012XrQhRE9LUQrCThL4jDEaSLsZ64PY+XL0ZdNCS4RX6OHGp6EyHC1HNSHn8a2
+zQuAzBsBHM39h/EVid9m0acfcEuN7TYAKF+sH6qjEBiSAWdRAkEA5hnwRsecGht6
+ViW4uuwHadNrc19mMPpXxFtIb79ONH+FmUkSQ0pRNOkEVICC7yokZbnhxcxSb76k
+r3S7rDa8xQJBANJJgpzuxbF0/NTXl5aH1gcucpIp6XBJfRmn1DpFq3Y20qGPr+Ez
+SiiDaqxoYjYRQ6FJg26kWnonWPawsiXSIp8CQQDQuQazra10ISi/rEf9hszSuezm
+IstX8j5a51K1yxrtlB9kBFyEnY08KYK8BDbBK8EIZaze95BvvMc2QPVcKerhAkB+
+Qh7HBOHz827eiHd+rR5Hf47QzZNYlPck0UyulCgnuTDsSi5qw3XSL118GMxm9CSs
+EUx1wP6F+1wB+gNsi+e3AkAR39uESbaaVOZmh1Uvvz0RVckXlJOEPY8Rp6kxhFS2
+QBsWbMrb5jraFy54iCmj8o3stp+LjBBv4PFA0LKq4vIa
+-----END RSA PRIVATE KEY-----

File test_data/test_schema.sql

+-- script to create test schema for epgsql unit tests --
+--
+-- this script should be run as the same user the tests will be run as,
+-- so that the test for connecting as the 'current user' succeeds
+--
+-- the following lines must be added to pg_hba.conf for all tests to
+-- succeed:
+--
+-- host    epgsql_test_db1 epgsql_test             127.0.0.1/32    trust
+-- host    epgsql_test_db1 epgsql_test_md5         127.0.0.1/32    md5
+-- host    epgsql_test_db1 epgsql_test_cleartext   127.0.0.1/32    password
+-- hostssl epgsql_test_db1 epgsql_test_cert        127.0.0.1/32    cert
+--
+-- any 'trust all' must be commented out for the invalid password test
+-- to succeed.
+--
+-- ssl support must be configured, and the sslinfo contrib module
+-- loaded for the ssl tests to succeed.
+
+
+CREATE USER epgsql_test;
+CREATE USER epgsql_test_md5 WITH PASSWORD 'epgsql_test_md5';
+CREATE USER epgsql_test_cleartext WITH PASSWORD 'epgsql_test_cleartext';
+CREATE USER epgsql_test_cert;
+
+CREATE DATABASE epgsql_test_db1;
+CREATE DATABASE epgsql_test_db2;
+
+GRANT ALL ON DATABASE epgsql_test_db1 to epgsql_test;
+GRANT ALL ON DATABASE epgsql_test_db1 to epgsql_test_md5;
+GRANT ALL ON DATABASE epgsql_test_db1 to epgsql_test_cleartext;
+GRANT ALL ON DATABASE epgsql_test_db2 to epgsql_test;
+
+\c epgsql_test_db1;
+
+CREATE TABLE test_table1 (id integer primary key, value text);
+
+INSERT INTO test_table1 (id, value) VALUES (1, 'one');
+INSERT INTO test_table1 (id, value) VALUES (2, 'two');
+
+CREATE TABLE test_table2 (
+  c_bool bool,
+  c_char char,  
+  c_int2 int2,
+  c_int4 int4,
+  c_int8 int8,
+  c_float4 float4,
+  c_float8 float8,
+  c_bytea bytea,
+  c_text text,
+  c_varchar varchar(64),
+  c_date date,
+  c_time time,
+  c_timetz timetz,
+  c_timestamp timestamp,
+  c_timestamptz timestamptz,
+  c_interval interval);
+
+CREATE LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION insert_test1(_id integer, _value text)
+returns integer
+as $$
+begin
+  insert into test_table1 (id, value) values (_id, _value);
+  return _id;
+end
+$$ language plpgsql;
+
+CREATE OR REPLACE FUNCTION do_nothing()
+returns void
+as $$
+begin
+end
+$$ language plpgsql;
+
+GRANT ALL ON TABLE test_table1 TO epgsql_test;
+GRANT ALL ON TABLE test_table2 TO epgsql_test;
+GRANT ALL ON FUNCTION insert_test1(integer, text) TO epgsql_test;
+GRANT ALL ON FUNCTION do_nothing() TO epgsql_test;

File test_src/pgsql_tests.erl

 -export([run_tests/0]).
 
 -include_lib("eunit/include/eunit.hrl").
+-include_lib("ssl/include/OTP-PKIX.hrl").
 -include("pgsql.hrl").
 
 -define(host, "localhost").
       fun(C) ->
               {ok, _Cols, [{true}]} = pgsql:equery(C, "select ssl_is_used()")
       end,
+      "epgsql_test",
       [{ssl, true}]).
 
+connect_with_client_cert_test() ->
+    lists:foreach(fun application:start/1, [crypto, ssl]),
+
+    Dir = filename:join(filename:dirname(code:which(pgsql_tests)), "../test_data"),
+    File = fun(Name) -> filename:join(Dir, Name) end,
+    {ok, Cert} = ssl_pkix:decode_cert_file(File("epgsql.crt"), [pem, pkix]),
+    #'TBSCertificate'{serialNumber = Serial} = Cert#'Certificate'.tbsCertificate,
+    Serial2 = list_to_binary(integer_to_list(Serial)),
+
+    with_connection(
+      fun(C) ->
+              {ok, _, [{true}]} = pgsql:equery(C, "select ssl_is_used()"),
+              {ok, _, [{Serial2}]} = pgsql:equery(C, "select ssl_client_serial()")
+      end,
+      "epgsql_test_cert",
+      [{ssl, true}, {keyfile, File("epgsql.key")}, {certfile, File("epgsql.crt")}]).
+
 select_test() ->
     with_connection(
       fun(C) ->
     flush().
 
 with_connection(F) ->
-    with_connection(F, []).
+    with_connection(F, "epgsql_test", []).
 
-with_connection(F, Args) ->
+with_connection(F, Username, Args) ->
     Args2 = [{port, ?port}, {database, "epgsql_test_db1"} | Args],
-    {ok, C} = pgsql:connect(?host, "epgsql_test", Args2),
+    {ok, C} = pgsql:connect(?host, Username, Args2),
     try
         F(C)
     after

File test_src/test_schema.sql

--- script to create test schema for epgsql unit tests --
---
--- this script should be run as the same user the tests will be run as,
--- so that the test for connecting as the 'current user' succeeds
---
--- the following lines must be added to pg_hba.conf for all tests to
--- succeed:
---
--- host    epgsql_test_db1 epgsql_test             127.0.0.1/32    trust
--- host    epgsql_test_db1 epgsql_test_md5         127.0.0.1/32    md5
--- host    epgsql_test_db1 epgsql_test_cleartext   127.0.0.1/32    password
---
--- any 'trust all' must be commented out for the invalid password test
--- to succeed.
---
--- ssl support must be configured, and the sslinfo contrib module
--- loaded for the ssl tests to succeed.
-
-
-CREATE USER epgsql_test;
-CREATE USER epgsql_test_md5 WITH PASSWORD 'epgsql_test_md5';
-CREATE USER epgsql_test_cleartext WITH PASSWORD 'epgsql_test_cleartext';
-
-CREATE DATABASE epgsql_test_db1;
-CREATE DATABASE epgsql_test_db2;
-
-GRANT ALL ON DATABASE epgsql_test_db1 to epgsql_test;
-GRANT ALL ON DATABASE epgsql_test_db1 to epgsql_test_md5;
-GRANT ALL ON DATABASE epgsql_test_db1 to epgsql_test_cleartext;
-GRANT ALL ON DATABASE epgsql_test_db2 to epgsql_test;
-
-\c epgsql_test_db1;
-
-CREATE TABLE test_table1 (id integer primary key, value text);
-
-INSERT INTO test_table1 (id, value) VALUES (1, 'one');
-INSERT INTO test_table1 (id, value) VALUES (2, 'two');
-
-CREATE TABLE test_table2 (
-  c_bool bool,
-  c_char char,  
-  c_int2 int2,
-  c_int4 int4,
-  c_int8 int8,
-  c_float4 float4,
-  c_float8 float8,
-  c_bytea bytea,
-  c_text text,
-  c_varchar varchar(64),
-  c_date date,
-  c_time time,
-  c_timetz timetz,
-  c_timestamp timestamp,
-  c_timestamptz timestamptz,
-  c_interval interval);
-
-CREATE LANGUAGE plpgsql;
-
-CREATE OR REPLACE FUNCTION insert_test1(_id integer, _value text)
-returns integer
-as $$
-begin
-  insert into test_table1 (id, value) values (_id, _value);
-  return _id;
-end
-$$ language plpgsql;
-
-CREATE OR REPLACE FUNCTION do_nothing()
-returns void
-as $$
-begin
-end
-$$ language plpgsql;
-
-GRANT ALL ON TABLE test_table1 TO epgsql_test;
-GRANT ALL ON TABLE test_table2 TO epgsql_test;
-GRANT ALL ON FUNCTION insert_test1(integer, text) TO epgsql_test;
-GRANT ALL ON FUNCTION do_nothing() TO epgsql_test;