Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Require client cert auth for gRPC, allow for JSON-RPC #1867

Merged
merged 1 commit into from Oct 15, 2020

Conversation

jrick
Copy link
Member

@jrick jrick commented Oct 13, 2020

Client authentication for JSON-RPC previously required configuring a
user and password, with both client and server holding knowledge of
the secret. By allowing client authentication to be performed with
TLS client certificates, only the client side must hold a private key,
as long as the dcrwallet server is configured to trust the public key.

The gRPC server had no client authentication at all previously, and
the only reason this was marginally safe was that all requests that
could use a wallet key also required supplying and checking the wallet
private passhprase in the request. However, with per-account
passphrases, this is no longer a suitable mechanism, and instead the
entire transport layer must be authenticated. The simplest way to
perform this is by requiring and verifying client certificates.

TLS client certificate authentication must be enabled with the
--authtype=clientcerts flag or config setting. The gRPC server will
no longer start without this setting, and enabling this also allows
the JSON-RPC server to be started without any user or password.

There are two ways in which a client certificate may be trusted:

  1. A certificate authority is created which adds trust for a client
    cert, or certs signed by the authority. This file defaults to
    clients.pem in the dcrwallet application data directory and can
    be modified to use other paths with the --clientcafile option.
    Certificates can be created using gencerts, OpenSSL, and similar
    tooling.

  2. A parent process can read an issued ephemeral certificate and key
    through a pipe. These certs and keys never reach the filesystem,
    and this is the expected mechanism by which Decrediton will
    authenticate itself to the gRPC server. This behavior is enabled
    with the --issueclientcert flag.

Copy link
Member

@marcopeereboom marcopeereboom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks right and reads well. I am not seeing any tests though. Please add some tests that verify that the cert code does indeed work as expected.

I also would like to see a negative test for client auth on a spend.

This is going to have significant fallout with politeiavoter, piwww, dcrtime and others.

Client authentication for JSON-RPC previously required configuring a
user and password, with both client and server holding knowledge of
the secret.  By allowing client authentication to be performed with
TLS client certificates, only the client side must hold a private key,
as long as the dcrwallet server is configured to trust the public key.

The gRPC server had no client authentication at all previously, and
the only reason this was marginally safe was that all requests that
could use a wallet key also required supplying and checking the wallet
private passhprase in the request.  However, with per-account
passphrases, this is no longer a suitable mechanism, and instead the
entire transport layer must be authenticated.  The simplest way to
perform this is by requiring and verifying client certificates.

TLS client certificate authentication must be enabled with the
--authtype=clientcerts flag or config setting.  The gRPC server will
no longer start without this setting, and enabling this also allows
the JSON-RPC server to be started without any user or password.

There are two ways in which a client certificate may be trusted:

1. A certificate authority is created which adds trust for a client
   cert, or certs signed by the authority.  This file defaults to
   clients.pem in the dcrwallet application data directory and can
   be modified to use other paths with the --clientcafile option.
   Certificates can be created using gencerts, OpenSSL, and similar
   tooling.

2. A parent process can read an issued ephemeral certificate and key
   through a pipe.  These certs and keys never reach the filesystem,
   and this is the expected mechanism by which Decrediton will
   authenticate itself to the gRPC server.  This behavior is enabled
   with the --issueclientcert flag.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants