"cert" + clientcert=verify-ca in pg_hba.conf?

Started by Kyotaro Horiguchiover 5 years ago35 messageshackers
Jump to latest
#1Kyotaro Horiguchi
horikyota.ntt@gmail.com

Hello.

The "Certificate Authentication" section in the doc for PG12 and later
describes the relation ship with clientcert as follows.

In a pg_hba.conf record specifying certificate authentication, the
authentication option clientcert is assumed to be verify-ca or
verify-full, and it cannot be turned off since a client certificate
is necessary for this method. What the cert method adds to the basic
clientcert certificate validity test is a check that the cn
attribute matches the database user name.

In reality, cert method is assumed as "vefiry-full" and does not add
anything to verify-full and cannot be degraded or turned off. It seems
to be a mistake on rewriting it when clientcert was changed to accept
verify-ca/full at PG12.

Related to that, pg_hba.conf accepts the combination of "cert" method
and the option clientcert="verify-ca" but it is ignored. We should
reject that combination the same way with "cert"+"no-verify".

regards.

--
Kyotaro Horiguchi
NTT Open Source Software Center

Attachments:

0001-Fix-behavior-for-cert-verify-ca-in-pg_hba.conf.patchtext/x-patch; charset=us-asciiDownload+12-6
#2Bruce Momjian
bruce@momjian.us
In reply to: Kyotaro Horiguchi (#1)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

On Thu, Jul 16, 2020 at 09:30:12AM +0900, Kyotaro Horiguchi wrote:

Hello.

The "Certificate Authentication" section in the doc for PG12 and later
describes the relation ship with clientcert as follows.

In a pg_hba.conf record specifying certificate authentication, the
authentication option clientcert is assumed to be verify-ca or
verify-full, and it cannot be turned off since a client certificate
is necessary for this method. What the cert method adds to the basic
clientcert certificate validity test is a check that the cn
attribute matches the database user name.

In reality, cert method is assumed as "verify-full" and does not add
anything to verify-full and cannot be degraded or turned off. It seems
to be a mistake on rewriting it when clientcert was changed to accept
verify-ca/full at PG12.

Agreed. I was able to test this patch and it does what you explained.
I have slightly adjusted the doc part of the patch, attached.

Related to that, pg_hba.conf accepts the combination of "cert" method
and the option clientcert="verify-ca" but it is ignored. We should
reject that combination the same way with "cert"+"no-verify".

Are you saying we should _require_ clientcert=verify-full when 'cert'
authentication is used? I don't see the point of that --- I just
updated the docs to say doing so was duplicate behavior.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

Attachments:

cert.difftext/x-diff; charset=us-asciiDownload+13-6
#3Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#2)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

At Mon, 24 Aug 2020 20:01:26 -0400, Bruce Momjian <bruce@momjian.us> wrote in

On Thu, Jul 16, 2020 at 09:30:12AM +0900, Kyotaro Horiguchi wrote:

Hello.

The "Certificate Authentication" section in the doc for PG12 and later
describes the relation ship with clientcert as follows.

In a pg_hba.conf record specifying certificate authentication, the
authentication option clientcert is assumed to be verify-ca or
verify-full, and it cannot be turned off since a client certificate
is necessary for this method. What the cert method adds to the basic
clientcert certificate validity test is a check that the cn
attribute matches the database user name.

In reality, cert method is assumed as "verify-full" and does not add
anything to verify-full and cannot be degraded or turned off. It seems
to be a mistake on rewriting it when clientcert was changed to accept
verify-ca/full at PG12.

Agreed. I was able to test this patch and it does what you explained.
I have slightly adjusted the doc part of the patch, attached.

Thanks.

     In a <filename>pg_hba.conf</filename> record specifying certificate
-    authentication, the authentication option <literal>clientcert</literal> is
-    assumed to be <literal>verify-ca</literal> or <literal>verify-full</literal>,
-    and it cannot be turned off since a client certificate is necessary for this
-    method. What the <literal>cert</literal> method adds to the basic
-    <literal>clientcert</literal> certificate validity test is a check that the
-    <literal>cn</literal> attribute matches the database user name.
+    authentication, the only valid value for <literal>clientcert</literal>
+    is <literal>verify-full</literal>, and this has no affect since it
+    just duplicates <literal>client</literal> authentication's behavior.

I read it as "it can be specified (without an error), but actually
does nothing". If it is the correct reading, I prefer to mention that
incompatible values cause an error.

Related to that, pg_hba.conf accepts the combination of "cert" method
and the option clientcert="verify-ca" but it is ignored. We should
reject that combination the same way with "cert"+"no-verify".

Are you saying we should _require_ clientcert=verify-full when 'cert'
authentication is used? I don't see the point of that --- I just
updated the docs to say doing so was duplicate behavior.

I don't suggest changing the current behavior. I'm saying it is the
way it is working and we should correctly error-out that since it
doesn't work as specified.

auth.c:608
if ((status == STATUS_OK && port->hba->clientcert == clientCertFull)
|| port->hba->auth_method == uaCert)
{
/*
* Make sure we only check the certificate if we use the cert method
* or verify-full option.
*/
#ifdef USE_SSL
status = CheckCertAuth(port);
#else
Assert(false);
#endif
}

regard.

--
Kyotaro Horiguchi
NTT Open Source Software Center

#4Bruce Momjian
bruce@momjian.us
In reply to: Kyotaro Horiguchi (#3)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

On Tue, Aug 25, 2020 at 10:41:26AM +0900, Kyotaro Horiguchi wrote:

At Mon, 24 Aug 2020 20:01:26 -0400, Bruce Momjian <bruce@momjian.us> wrote in

I have slightly adjusted the doc part of the patch, attached.

Thanks.

In a <filename>pg_hba.conf</filename> record specifying certificate
-    authentication, the authentication option <literal>clientcert</literal> is
-    assumed to be <literal>verify-ca</literal> or <literal>verify-full</literal>,
-    and it cannot be turned off since a client certificate is necessary for this
-    method. What the <literal>cert</literal> method adds to the basic
-    <literal>clientcert</literal> certificate validity test is a check that the
-    <literal>cn</literal> attribute matches the database user name.
+    authentication, the only valid value for <literal>clientcert</literal>
+    is <literal>verify-full</literal>, and this has no affect since it
+    just duplicates <literal>client</literal> authentication's behavior.

I read it as "it can be specified (without an error), but actually
does nothing". If it is the correct reading, I prefer to mention that
incompatible values cause an error.

Well, when I say "the only valid value", that means any other value is
invalid, and hence will generate an error.

Related to that, pg_hba.conf accepts the combination of "cert" method
and the option clientcert="verify-ca" but it is ignored. We should
reject that combination the same way with "cert"+"no-verify".

Are you saying we should _require_ clientcert=verify-full when 'cert'
authentication is used? I don't see the point of that --- I just
updated the docs to say doing so was duplicate behavior.

I don't suggest changing the current behavior. I'm saying it is the
way it is working and we should correctly error-out that since it
doesn't work as specified.

Uh, I don't understand what 'combination the same way with
"cert"+"no-verify"'. Right now, cert with no clientcert/verify line
works just fine. Is "no-verify" something special? Are you saying it
is any random string that would generate an error?

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

#5Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#4)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

At Mon, 24 Aug 2020 21:49:40 -0400, Bruce Momjian <bruce@momjian.us> wrote in

Are you saying we should _require_ clientcert=verify-full when 'cert'
authentication is used? I don't see the point of that --- I just
updated the docs to say doing so was duplicate behavior.

I don't suggest changing the current behavior. I'm saying it is the
way it is working and we should correctly error-out that since it
doesn't work as specified.

Sorry, I mistead you. I don't suggest verify-full is needed for cert
authentication. I said we should just reject the combination
cert+veriry-ca.

Uh, I don't understand what 'combination the same way with
"cert"+"no-verify"'. Right now, cert with no clientcert/verify line
works just fine. Is "no-verify" something special? Are you saying it
is any random string that would generate an error?

It was delimited as "We should reject (that)" "that combination
(=cert+ferify-ca)" "the same way(=error-out)" "with cert+no-verify".

regards.

--
Kyotaro Horiguchi
NTT Open Source Software Center

#6Bruce Momjian
bruce@momjian.us
In reply to: Kyotaro Horiguchi (#5)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

On Tue, Aug 25, 2020 at 11:00:49AM +0900, Kyotaro Horiguchi wrote:

At Mon, 24 Aug 2020 21:49:40 -0400, Bruce Momjian <bruce@momjian.us> wrote in

Are you saying we should _require_ clientcert=verify-full when 'cert'
authentication is used? I don't see the point of that --- I just
updated the docs to say doing so was duplicate behavior.

I don't suggest changing the current behavior. I'm saying it is the
way it is working and we should correctly error-out that since it
doesn't work as specified.

Sorry, I mistead you. I don't suggest verify-full is needed for cert
authentication. I said we should just reject the combination
cert+veriry-ca.

OK.

Uh, I don't understand what 'combination the same way with
"cert"+"no-verify"'. Right now, cert with no clientcert/verify line
works just fine. Is "no-verify" something special? Are you saying it
is any random string that would generate an error?

It was delimited as "We should reject (that)" "that combination
(=cert+ferify-ca)" "the same way(=error-out)" "with cert+no-verify".

OK, and that is what your patch does, right? And we should error out on
"with cert+no-verify" just like "with cert+XXXXXX", right? I don't see
"no-verify" mentioned anywhere in our docs.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

#7Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#6)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

Thank you for the patience.

At Mon, 24 Aug 2020 22:06:45 -0400, Bruce Momjian <bruce@momjian.us> wrote in

On Tue, Aug 25, 2020 at 11:00:49AM +0900, Kyotaro Horiguchi wrote:

At Mon, 24 Aug 2020 21:49:40 -0400, Bruce Momjian <bruce@momjian.us> wrote in

Are you saying we should _require_ clientcert=verify-full when 'cert'
authentication is used? I don't see the point of that --- I just
updated the docs to say doing so was duplicate behavior.

I don't suggest changing the current behavior. I'm saying it is the
way it is working and we should correctly error-out that since it
doesn't work as specified.

Sorry, I mistead you. I don't suggest verify-full is needed for cert
authentication. I said we should just reject the combination
cert+veriry-ca.

OK.

Uh, I don't understand what 'combination the same way with
"cert"+"no-verify"'. Right now, cert with no clientcert/verify line
works just fine. Is "no-verify" something special? Are you saying it
is any random string that would generate an error?

It was delimited as "We should reject (that)" "that combination
(=cert+ferify-ca)" "the same way(=error-out)" "with cert+no-verify".

OK, and that is what your patch does, right?

Yes,

And we should error out on "with cert+no-verify" just like "with
cert+XXXXXX", right?

Currently only cert+no-verify is rejected. The patch makes "cert+verify-ca" be rejected.

I don't see "no-verify" mentioned anywhere in our docs.

no-verify itself is mentioned here.

https://www.postgresql.org/docs/13/ssl-tcp.html#SSL-CLIENT-CERTIFICATES

The clientcert authentication option is available for all
authentication methods, but only in pg_hba.conf lines specified as
hostssl. When clientcert is not specified or is set to *no-verify*,
the server will still verify any presented client certificates
against its CA file, if one is configured — but it will not insist
that a client certificate be presented.

regards.

--
Kyotaro Horiguchi
NTT Open Source Software Center

#8Bruce Momjian
bruce@momjian.us
In reply to: Kyotaro Horiguchi (#7)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

On Tue, Aug 25, 2020 at 11:41:55AM +0900, Kyotaro Horiguchi wrote:

Thank you for the patience.

At Mon, 24 Aug 2020 22:06:45 -0400, Bruce Momjian <bruce@momjian.us> wrote in

On Tue, Aug 25, 2020 at 11:00:49AM +0900, Kyotaro Horiguchi wrote:

At Mon, 24 Aug 2020 21:49:40 -0400, Bruce Momjian <bruce@momjian.us> wrote in

Are you saying we should _require_ clientcert=verify-full when 'cert'
authentication is used? I don't see the point of that --- I just
updated the docs to say doing so was duplicate behavior.

I don't suggest changing the current behavior. I'm saying it is the
way it is working and we should correctly error-out that since it
doesn't work as specified.

Sorry, I mistead you. I don't suggest verify-full is needed for cert
authentication. I said we should just reject the combination
cert+veriry-ca.

OK.

Uh, I don't understand what 'combination the same way with
"cert"+"no-verify"'. Right now, cert with no clientcert/verify line
works just fine. Is "no-verify" something special? Are you saying it
is any random string that would generate an error?

It was delimited as "We should reject (that)" "that combination
(=cert+ferify-ca)" "the same way(=error-out)" "with cert+no-verify".

OK, and that is what your patch does, right?

Yes,

And we should error out on "with cert+no-verify" just like "with
cert+XXXXXX", right?

Currently only cert+no-verify is rejected. The patch makes "cert+verify-ca" be rejected.

I don't see "no-verify" mentioned anywhere in our docs.

no-verify itself is mentioned here.

https://www.postgresql.org/docs/13/ssl-tcp.html#SSL-CLIENT-CERTIFICATES

Oh, I see it now, thanks. Do you have any idea what this part of the
docs means?

When <literal>clientcert</literal> is not specified or is set to
<literal>no-verify</literal>, the server will still verify any presented
client certificates against its CA file, if one is configured &mdash;
but it will not insist that a client certificate be presented.

Why is this useful?

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

#9Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#8)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

At Mon, 24 Aug 2020 23:04:51 -0400, Bruce Momjian <bruce@momjian.us> wrote in

I don't see "no-verify" mentioned anywhere in our docs.

no-verify itself is mentioned here.

https://www.postgresql.org/docs/13/ssl-tcp.html#SSL-CLIENT-CERTIFICATES

Oh, I see it now, thanks. Do you have any idea what this part of the
docs means?

When <literal>clientcert</literal> is not specified or is set to
<literal>no-verify</literal>, the server will still verify any presented
client certificates against its CA file, if one is configured &mdash;
but it will not insist that a client certificate be presented.

Ah.. Indeed.

Even if clientcert is not set or set to no-verify, it checks client
certificate against the CA if any. If verify-ca, client certificate
must be provided. As the result, no-verify actually fails if client
had a certificate that is not backed by the CA.

Why is this useful?

I agree, but there seems to be an implementation reason for the
behavior. To identify an hba-line, some connection parameters like
user name and others sent over a connection is required. Thus the
clientcert option in the to-be-identified hba-line is unknown prior to
the time SSL connection is made. So the documentation might need
amendment. Roughly something like the following?

===
When <literal>clientcert</literal> is not specified or is set
to<literal>no-verify</literal>, clients can connect to server without
having a client certificate.

Note: Regardless of the setting of <literal>clientcert</literal>,
connection can end with failure if a client certificate that cannot be
verified by the server is stored in the ~/.postgresql directory.
===

By the way, the following table line might need to be changed?

libpq-ssl.html:

<entry><filename>~/.postgresql/postgresql.crt</filename></entry>
<entry>client certificate</entry>

- <entry>requested by server</entry>

The file is actually not requested by server, client just pushes to
server if any, unconditionally.

+ <entry>sent to server</entry>

regards.

--
Kyotaro Horiguchi
NTT Open Source Software Center

#10Bruce Momjian
bruce@momjian.us
In reply to: Kyotaro Horiguchi (#9)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

On Tue, Aug 25, 2020 at 03:53:20PM +0900, Kyotaro Horiguchi wrote:

At Mon, 24 Aug 2020 23:04:51 -0400, Bruce Momjian <bruce@momjian.us> wrote in

I don't see "no-verify" mentioned anywhere in our docs.

no-verify itself is mentioned here.

https://www.postgresql.org/docs/13/ssl-tcp.html#SSL-CLIENT-CERTIFICATES

Oh, I see it now, thanks. Do you have any idea what this part of the
docs means?

When <literal>clientcert</literal> is not specified or is set to
<literal>no-verify</literal>, the server will still verify any presented
client certificates against its CA file, if one is configured &mdash;
but it will not insist that a client certificate be presented.

Ah.. Indeed.

Even if clientcert is not set or set to no-verify, it checks client
certificate against the CA if any. If verify-ca, client certificate
must be provided. As the result, no-verify actually fails if client
had a certificate that is not backed by the CA.

I think there are a few problems here. In the docs, it says "will still
verify", but it doesn't say if it verifies the CA, or the CA _and_ the
CN/username.

Second, since it is optional, what value does it have?

Why is this useful?

I agree, but there seems to be an implementation reason for the
behavior. To identify an hba-line, some connection parameters like
user name and others sent over a connection is required. Thus the
clientcert option in the to-be-identified hba-line is unknown prior to
the time SSL connection is made. So the documentation might need
amendment. Roughly something like the following?

Well, I realize internally we need a way to indicate clientcert is not
used, but why do we bother exposing that to the user as a named option?

And you are right that the option name 'no-verify' is wrong since it
will verify the CA if it exists, so it more like 'optionally-verify',
which seems useless from a user interface perspective.

I guess the behavior of no-verify matches our client-side
sslmode=prefer, but at least that has the value of using SSL if
available, which prevents user-visible network traffic, but doesn't
force it, but I am not sure what the value of optional certificate
verification is, since verification is all it does. I guess it should
be called "prefer-verify".

===
When <literal>clientcert</literal> is not specified or is set
to<literal>no-verify</literal>, clients can connect to server without
having a client certificate.

Note: Regardless of the setting of <literal>clientcert</literal>,
connection can end with failure if a client certificate that cannot be
verified by the server is stored in the ~/.postgresql directory.
===

By the way, the following table line might need to be changed?

libpq-ssl.html:

<entry><filename>~/.postgresql/postgresql.crt</filename></entry>
<entry>client certificate</entry>

- <entry>requested by server</entry>

The file is actually not requested by server, client just pushes to
server if any, unconditionally.

+ <entry>sent to server</entry>

I have just applied this change to all branches, since it is an
independent fix. Thanks.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

#11Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#10)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

At Tue, 25 Aug 2020 10:04:44 -0400, Bruce Momjian <bruce@momjian.us> wrote in

On Tue, Aug 25, 2020 at 03:53:20PM +0900, Kyotaro Horiguchi wrote:

At Mon, 24 Aug 2020 23:04:51 -0400, Bruce Momjian <bruce@momjian.us> wrote in

I don't see "no-verify" mentioned anywhere in our docs.

no-verify itself is mentioned here.

https://www.postgresql.org/docs/13/ssl-tcp.html#SSL-CLIENT-CERTIFICATES

Oh, I see it now, thanks. Do you have any idea what this part of the
docs means?

When <literal>clientcert</literal> is not specified or is set to
<literal>no-verify</literal>, the server will still verify any presented
client certificates against its CA file, if one is configured &mdash;
but it will not insist that a client certificate be presented.

Ah.. Indeed.

Even if clientcert is not set or set to no-verify, it checks client
certificate against the CA if any. If verify-ca, client certificate
must be provided. As the result, no-verify actually fails if client
had a certificate that is not backed by the CA.

I think there are a few problems here. In the docs, it says "will still
verify", but it doesn't say if it verifies the CA, or the CA _and_ the
CN/username.

It verifies only CA.

Second, since it is optional, what value does it have?

Why is this useful?

I agree, but there seems to be an implementation reason for the
behavior. To identify an hba-line, some connection parameters like
user name and others sent over a connection is required. Thus the
clientcert option in the to-be-identified hba-line is unknown prior to
the time SSL connection is made. So the documentation might need
amendment. Roughly something like the following?

Well, I realize internally we need a way to indicate clientcert is not
used, but why do we bother exposing that to the user as a named option?

Because we think we need any named value for every alternatives
including the default value?

And you are right that the option name 'no-verify' is wrong since it
will verify the CA if it exists, so it more like 'optionally-verify',
which seems useless from a user interface perspective.

I guess the behavior of no-verify matches our client-side
sslmode=prefer, but at least that has the value of using SSL if
available, which prevents user-visible network traffic, but doesn't
force it, but I am not sure what the value of optional certificate
verification is, since verification is all it does. I guess it should
be called "prefer-verify".

The point of no-verify is to allow the absence of client
certificate. It is similar to "prefer" in a sense that it allows the
absence of availability of an SSL connection. (In a similar way to
"prefer", we could "fall back" to "no client cert" SSL connection
after verification failure but I think it's not worth doing.)

"prefer-verify" seems right in that sense. But I'm not sure we may
break backward compatibility for the reason.

===
When <literal>clientcert</literal> is not specified or is set
to<literal>no-verify</literal>, clients can connect to server without
having a client certificate.

Note: Regardless of the setting of <literal>clientcert</literal>,
connection can end with failure if a client certificate that cannot be
verified by the server is stored in the ~/.postgresql directory.
===

By the way, the following table line might need to be changed?

libpq-ssl.html:

<entry><filename>~/.postgresql/postgresql.crt</filename></entry>
<entry>client certificate</entry>

- <entry>requested by server</entry>

The file is actually not requested by server, client just pushes to
server if any, unconditionally.

+ <entry>sent to server</entry>

I have just applied this change to all branches, since it is an
independent fix. Thanks.

Thanks.

--
Kyotaro Horiguchi
NTT Open Source Software Center

#12Bruce Momjian
bruce@momjian.us
In reply to: Kyotaro Horiguchi (#11)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

On Wed, Aug 26, 2020 at 11:41:39AM +0900, Kyotaro Horiguchi wrote:

At Tue, 25 Aug 2020 10:04:44 -0400, Bruce Momjian <bruce@momjian.us> wrote in

I think there are a few problems here. In the docs, it says "will still
verify", but it doesn't say if it verifies the CA, or the CA _and_ the
CN/username.

It verifies only CA.

OK, that will need to be clarified.

Second, since it is optional, what value does it have?

Why is this useful?

I agree, but there seems to be an implementation reason for the
behavior. To identify an hba-line, some connection parameters like
user name and others sent over a connection is required. Thus the
clientcert option in the to-be-identified hba-line is unknown prior to
the time SSL connection is made. So the documentation might need
amendment. Roughly something like the following?

Well, I realize internally we need a way to indicate clientcert is not
used, but why do we bother exposing that to the user as a named option?

Because we think we need any named value for every alternatives
including the default value?

Well, not putting clientcert at all gives the default behavior, so why
have clientcert=no-verify?

And you are right that the option name 'no-verify' is wrong since it
will verify the CA if it exists, so it more like 'optionally-verify',
which seems useless from a user interface perspective.

I guess the behavior of no-verify matches our client-side
sslmode=prefer, but at least that has the value of using SSL if
available, which prevents user-visible network traffic, but doesn't
force it, but I am not sure what the value of optional certificate
verification is, since verification is all it does. I guess it should
be called "prefer-verify".

The point of no-verify is to allow the absence of client
certificate. It is similar to "prefer" in a sense that it allows the
absence of availability of an SSL connection. (In a similar way to
"prefer", we could "fall back" to "no client cert" SSL connection
after verification failure but I think it's not worth doing.)

Well, sslmode=prefer gives encryption without identification.
clientcert=no-verify has no value because it is just an optional CA
check that has no value because optional authentication is useless. It
is like saying you can type in the password if you want, and we will
check it, or you can just not type in the password.

"prefer-verify" seems right in that sense. But I'm not sure we may
break backward compatibility for the reason.

True, but right now it is inaccurate so I think it just need to be fixed
or removed and documented in the PG 14 release notes.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

#13Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#12)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

At Tue, 25 Aug 2020 22:52:44 -0400, Bruce Momjian <bruce@momjian.us> wrote in

On Wed, Aug 26, 2020 at 11:41:39AM +0900, Kyotaro Horiguchi wrote:

At Tue, 25 Aug 2020 10:04:44 -0400, Bruce Momjian <bruce@momjian.us> wrote in

I think there are a few problems here. In the docs, it says "will still
verify", but it doesn't say if it verifies the CA, or the CA _and_ the
CN/username.

It verifies only CA.

OK, that will need to be clarified.

Second, since it is optional, what value does it have?

Why is this useful?

I agree, but there seems to be an implementation reason for the
behavior. To identify an hba-line, some connection parameters like
user name and others sent over a connection is required. Thus the
clientcert option in the to-be-identified hba-line is unknown prior to
the time SSL connection is made. So the documentation might need
amendment. Roughly something like the following?

Well, I realize internally we need a way to indicate clientcert is not
used, but why do we bother exposing that to the user as a named option?

Because we think we need any named value for every alternatives
including the default value?

Well, not putting clientcert at all gives the default behavior, so why
have clientcert=no-verify?

clientcert=verify-ca or verify-full don't allow absence of client
certificate. We need an option to allow the absence.

And you are right that the option name 'no-verify' is wrong since it
will verify the CA if it exists, so it more like 'optionally-verify',
which seems useless from a user interface perspective.

I guess the behavior of no-verify matches our client-side
sslmode=prefer, but at least that has the value of using SSL if
available, which prevents user-visible network traffic, but doesn't
force it, but I am not sure what the value of optional certificate
verification is, since verification is all it does. I guess it should
be called "prefer-verify".

The point of no-verify is to allow the absence of client
certificate. It is similar to "prefer" in a sense that it allows the
absence of availability of an SSL connection. (In a similar way to
"prefer", we could "fall back" to "no client cert" SSL connection
after verification failure but I think it's not worth doing.)

Well, sslmode=prefer gives encryption without identification.
clientcert=no-verify has no value because it is just an optional CA
check that has no value because optional authentication is useless. It

The point of the option is not to do optional CA check if possible,
but to allow absence of client cert. We need to have that mode
regardless of named or not named, and I believe we usually provide a
name for default mode.

is like saying you can type in the password if you want, and we will
check it, or you can just not type in the password.

Yes, since the point is the fact that I'm allowed to skip typing a
password. And the reason for the strange-looking behavior is that I
can't help entering a password if I had, but the server has no way
other than checking the password that I provided.

In the correct words, the server cannot ignore the certificate if
client sent it. But the client cannot identify whether the certificate
is needed by the server before sending it.

"prefer-verify" seems right in that sense. But I'm not sure we may
break backward compatibility for the reason.

True, but right now it is inaccurate so I think it just need to be fixed
or removed and documented in the PG 14 release notes.

I'm fine with that.

regards.

--
Kyotaro Horiguchi
NTT Open Source Software Center

#14Bruce Momjian
bruce@momjian.us
In reply to: Kyotaro Horiguchi (#13)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

On Wed, Aug 26, 2020 at 06:13:23PM +0900, Kyotaro Horiguchi wrote:

At Tue, 25 Aug 2020 22:52:44 -0400, Bruce Momjian <bruce@momjian.us> wrote in

Because we think we need any named value for every alternatives
including the default value?

Well, not putting clientcert at all gives the default behavior, so why
have clientcert=no-verify?

clientcert=verify-ca or verify-full don't allow absence of client
certificate. We need an option to allow the absence.

Isn't the option not specifying clientcert? Here are some valid
pg_hba.conf lines:

hostssl all all 127.0.0.1/32 trust clientcert=verify-full
hostssl all all 127.0.0.1/32 trust clientcert=verify-ca
hostssl all all 127.0.0.1/32 trust clientcert=no-verify
hostssl all all 127.0.0.1/32 trust

It is my understanding that the last two lines are the same. Why isn't
it sufficient to just tell users not to specify clientcert if they want
the default behavior? You can do:

host all all 192.168.0.0/16 ident map=omicron

but there is no way to specify the default map value of 'no map', so why
have one for clientcert?

Well, sslmode=prefer gives encryption without identification.
clientcert=no-verify has no value because it is just an optional CA
check that has no value because optional authentication is useless. It

The point of the option is not to do optional CA check if possible,
but to allow absence of client cert. We need to have that mode
regardless of named or not named, and I believe we usually provide a
name for default mode.

Uh, see above --- not really. The absense of the option is the default
action.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

#15Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#14)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

At Wed, 26 Aug 2020 18:36:50 -0400, Bruce Momjian <bruce@momjian.us> wrote in
bruce> On Wed, Aug 26, 2020 at 06:13:23PM +0900, Kyotaro Horiguchi wrote:

At Tue, 25 Aug 2020 22:52:44 -0400, Bruce Momjian <bruce@momjian.us> wrote in

Because we think we need any named value for every alternatives
including the default value?

Well, not putting clientcert at all gives the default behavior, so why
have clientcert=no-verify?

clientcert=verify-ca or verify-full don't allow absence of client
certificate. We need an option to allow the absence.

Isn't the option not specifying clientcert? Here are some valid
pg_hba.conf lines:

Sorry for the ambiguity. Perhaps I understand that we talked at
different objects. I was mentioning about the option value that is
stored *internally*, concretely the values for the struct member
port->hba->clientcert. You are talking about the descriptive option in
pg_hba.conf.

Does the following discussion make sense?

We need to use the default value zero (=clientCertOff) for
port->hba->clientcert to tell server to omit checking against CA if
cert is not given. I suppose that the value clientCertOff is labeled
as "no-verify" since someone who developed this thought that that
choice needs to be explicitly describable in pg_hba.conf. And my
discussion was following that decision.

I understand that the label "no-verify" is not essential to specify
the behavior, so I don't object to removing "no-verify" label itself
if no one oppose to remove it.

My point here is just "are we OK to remove it?"

It is my understanding that the last two lines are the same. Why isn't
it sufficient to just tell users not to specify clientcert if they want
the default behavior? You can do:

host all all 192.168.0.0/16 ident map=omicron

but there is no way to specify the default map value of 'no map', so why
have one for clientcert?

The difference from clientcert is that it gives an arbitrary name that
points to a defined mapping, not a choice from an defined
enumeration.

Well, sslmode=prefer gives encryption without identification.
clientcert=no-verify has no value because it is just an optional CA
check that has no value because optional authentication is useless. It

The point of the option is not to do optional CA check if possible,
but to allow absence of client cert. We need to have that mode
regardless of named or not named, and I believe we usually provide a
name for default mode.

Uh, see above --- not really. The absense of the option is the default
action.

regards.

--
Kyotaro Horiguchi
NTT Open Source Software Center

#16Bruce Momjian
bruce@momjian.us
In reply to: Kyotaro Horiguchi (#15)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

On Thu, Aug 27, 2020 at 04:09:25PM +0900, Kyotaro Horiguchi wrote:

At Wed, 26 Aug 2020 18:36:50 -0400, Bruce Momjian <bruce@momjian.us> wrote in
bruce> On Wed, Aug 26, 2020 at 06:13:23PM +0900, Kyotaro Horiguchi wrote:

At Tue, 25 Aug 2020 22:52:44 -0400, Bruce Momjian <bruce@momjian.us> wrote in

Because we think we need any named value for every alternatives
including the default value?

Well, not putting clientcert at all gives the default behavior, so why
have clientcert=no-verify?

clientcert=verify-ca or verify-full don't allow absence of client
certificate. We need an option to allow the absence.

Isn't the option not specifying clientcert? Here are some valid
pg_hba.conf lines:

Sorry for the ambiguity. Perhaps I understand that we talked at
different objects. I was mentioning about the option value that is
stored *internally*, concretely the values for the struct member
port->hba->clientcert. You are talking about the descriptive option in
pg_hba.conf.

Does the following discussion make sense?

We need to use the default value zero (=clientCertOff) for
port->hba->clientcert to tell server to omit checking against CA if
cert is not given. I suppose that the value clientCertOff is labeled
as "no-verify" since someone who developed this thought that that
choice needs to be explicitly describable in pg_hba.conf. And my
discussion was following that decision.

I understand that the label "no-verify" is not essential to specify
the behavior, so I don't object to removing "no-verify" label itself
if no one oppose to remove it.

My point here is just "are we OK to remove it?"

Yes, in PG 14. Security is confusing enough, so having a mis-named
option that doesn't do anything more than just not specifying clientcert
is not useful and should be removed.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

#17Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#16)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

On Thu, Aug 27, 2020 at 03:41:40PM -0400, Bruce Momjian wrote:

On Thu, Aug 27, 2020 at 04:09:25PM +0900, Kyotaro Horiguchi wrote:

At Wed, 26 Aug 2020 18:36:50 -0400, Bruce Momjian <bruce@momjian.us> wrote in
bruce> On Wed, Aug 26, 2020 at 06:13:23PM +0900, Kyotaro Horiguchi wrote:

At Tue, 25 Aug 2020 22:52:44 -0400, Bruce Momjian <bruce@momjian.us> wrote in

Because we think we need any named value for every alternatives
including the default value?

Well, not putting clientcert at all gives the default behavior, so why
have clientcert=no-verify?

clientcert=verify-ca or verify-full don't allow absence of client
certificate. We need an option to allow the absence.

Isn't the option not specifying clientcert? Here are some valid
pg_hba.conf lines:

Sorry for the ambiguity. Perhaps I understand that we talked at
different objects. I was mentioning about the option value that is
stored *internally*, concretely the values for the struct member
port->hba->clientcert. You are talking about the descriptive option in
pg_hba.conf.

Yes, I realize we need an internal vaue for this, but it doesn't need to
be visible to the user.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

#18Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#16)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

Hello, Bruce.

At Thu, 27 Aug 2020 15:41:40 -0400, Bruce Momjian <bruce@momjian.us> wrote in

My point here is just "are we OK to remove it?"

Yes, in PG 14. Security is confusing enough, so having a mis-named
option that doesn't do anything more than just not specifying clientcert
is not useful and should be removed.

Ok, this is that. If we spcify clientcert=no-verify other than for
"cert" authentication, server complains as the following at startup.

LOG: no-verify or 0 is the default setting that is discouraged to use explicitly for clientcert option
HINT: Consider removing the option instead. This option value is going to be deprecated in later version.
CONTEXT: line 90 of configuration file "/home/horiguti/data/data_noverify/pg_hba.conf"

And, cert clientcert=verifry-ca (and no-verify) is correctly rejected.

LOG: clientcert accepts only "verify-full" when using "cert" authentication

I once I thought that the deprecation message should e WARNING but
later I changed my mind to change it to LOG unifying to surrounding
setting error messages.

I'm going to register this to the coming CF.

regrds.

--
Kyotaro Horiguchi
NTT Open Source Software Center

Attachments:

0001-Prepare-for-deprecating-no-verify-for-clientcert.patchtext/x-patch; charset=us-asciiDownload+26-15
#19Bruce Momjian
bruce@momjian.us
In reply to: Kyotaro Horiguchi (#18)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

On Mon, Aug 31, 2020 at 05:56:58PM +0900, Kyotaro Horiguchi wrote:

Hello, Bruce.

At Thu, 27 Aug 2020 15:41:40 -0400, Bruce Momjian <bruce@momjian.us> wrote in

My point here is just "are we OK to remove it?"

Yes, in PG 14. Security is confusing enough, so having a mis-named
option that doesn't do anything more than just not specifying clientcert
is not useful and should be removed.

Ok, this is that. If we spcify clientcert=no-verify other than for
"cert" authentication, server complains as the following at startup.

Why does clientcert=no-verify have any value, even for a
cert-authentication line?

LOG: no-verify or 0 is the default setting that is discouraged to use explicitly for clientcert option
HINT: Consider removing the option instead. This option value is going to be deprecated in later version.
CONTEXT: line 90 of configuration file "/home/horiguti/data/data_noverify/pg_hba.conf"

I think it should just be removed in PG 14. This is a configuration
setting, not an SQL-level item that needs a deprecation period.

And, cert clientcert=verifry-ca (and no-verify) is correctly rejected.

LOG: clientcert accepts only "verify-full" when using "cert" authentication

I once I thought that the deprecation message should e WARNING but
later I changed my mind to change it to LOG unifying to surrounding
setting error messages.

I'm going to register this to the coming CF.

I plan to apply this once we are done discussing it.

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

#20Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#19)
Re: "cert" + clientcert=verify-ca in pg_hba.conf?

At Mon, 31 Aug 2020 11:34:29 -0400, Bruce Momjian <bruce@momjian.us> wrote in

On Mon, Aug 31, 2020 at 05:56:58PM +0900, Kyotaro Horiguchi wrote:

Ok, this is that. If we spcify clientcert=no-verify other than for
"cert" authentication, server complains as the following at startup.

Why does clientcert=no-verify have any value, even for a
cert-authentication line?

LOG: no-verify or 0 is the default setting that is discouraged to use explicitly for clientcert option
HINT: Consider removing the option instead. This option value is going to be deprecated in later version.
CONTEXT: line 90 of configuration file "/home/horiguti/data/data_noverify/pg_hba.conf"

I think it should just be removed in PG 14. This is a configuration
setting, not an SQL-level item that needs a deprecation period.

Ok, it is changed to just error out. I tempted to show a suggestion to
removing the option in that case like the following, but *didn't* in
this version of the patch.

LOG: invalid value for clientcert: "no-verify"

?? HINT: Instead, consider removing the clinetcert option.

CONTEXT: line 90 of configuration file "/h

I'm going to register this to the coming CF.

I plan to apply this once we are done discussing it.

Roger.

regards.

--
Kyotaro Horiguchi
NTT Open Source Software Center

Attachments:

v2-0001-Deprecate-no-verify-for-clientcert.patchtext/x-patch; charset=us-asciiDownload+23-27
#21Bruce Momjian
bruce@momjian.us
In reply to: Kyotaro Horiguchi (#20)
#22Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#21)
#23Bruce Momjian
bruce@momjian.us
In reply to: Kyotaro Horiguchi (#22)
#24Michael Paquier
michael@paquier.xyz
In reply to: Bruce Momjian (#23)
#25Bruce Momjian
bruce@momjian.us
In reply to: Michael Paquier (#24)
#26Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#25)
#27Michael Paquier
michael@paquier.xyz
In reply to: Bruce Momjian (#25)
#28Tom Lane
tgl@sss.pgh.pa.us
In reply to: Kyotaro Horiguchi (#26)
#29Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#28)
#30Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#29)
#31Bruce Momjian
bruce@momjian.us
In reply to: Kyotaro Horiguchi (#26)
#32Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#31)
#33Bruce Momjian
bruce@momjian.us
In reply to: Kyotaro Horiguchi (#32)
#34Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#33)
#35Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Bruce Momjian (#34)