Skip to content

Add optional flags to pass client cert for step certificate inspect #65

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

Open
sourishkrout opened this issue Jan 17, 2019 · 3 comments
Open

Comments

@sourishkrout
Copy link
Contributor

sourishkrout commented Jan 17, 2019

Subject of the issue

When debugging mTLS'd environments it's handy to be able to inspect a server's cert remotely granted one is possession of a valid cert to pass client auth on the server.

Expected behaviour

Optional flags for subcommand to provide cert, e.g. step certificate inspect --roots federated.pem --cert client.crt --key client.key https://127.0.0.1:443

Actual behaviour

Fails because the server rejects client requests without/invalid certs.

@davidnarayan
Copy link
Contributor

@sourishkrout - I was looking at this and it seems that the client certificate is not required to inspect the peer certificate. The server certificate is sent to the client as part of the ServerHello in the TLS handshake so it's available for inspection irrespective of the client behavior. If the server requires a client certificate, it will fail the TLS handshake, but that's after the certificate exchange.

I'm curious if you've seen different behavior?

Here's the test that I did while researching this issue:

Go server requiring mTLS:

package main

import (
	"crypto/tls"
	"fmt"
	"log"
	"net/http"
	"net/http/httptest"
)

func main() {
	ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Hello, client")
	}))
	defer ts.Close()

	ts.TLS = &tls.Config{
		ClientAuth: tls.RequireAnyClientCert,
	}

	ts.StartTLS()
	fmt.Println("Listening on: ", ts.URL)
	select {}
}

Start the server:

❯ go run testserver.go
Listening on:  https://127.0.0.1:54371

Run step to inspect the certificate:

❯ step certificate inspect https://127.0.0.1:54371 -insecure -short
X.509v3 Root CA Certificate (RSA 1024) [Serial: 6448...4187]
  Subject:     example.com
               127.0.0.1
               ::1
  Issuer:
  Valid from:  1970-01-01T00:00:00Z
          to:  2084-01-29T16:00:00Z

Note that the server logged an error message because the client didn't provide a certificate:

2020/12/08 09:42:09 http: TLS handshake error from 127.0.0.1:54380: tls: client didn't provide a certificate

However, the peer certificate inspection still completed.

Are there perhaps other use cases or different behaviors that you've observed with other TLS servers?

@isodude
Copy link
Contributor

isodude commented Apr 24, 2025

I wanted this the other day when I was troubleshooting why my client certificate was not working.
As such, is not the peer certificate that is interesting, but rather validating the client certificate with the peer certificate.

@hslatman
Copy link
Member

@isodude this might (soon) be of use: #1402

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants