Code Monkey home page Code Monkey logo

est's Introduction

est

GoDoc Build Status Go Report Card

An implementation of the Enrollment over Secure Transport (EST) certificate enrollment protocol as defined by RFC7030.

The implementation provides:

  • An EST client library;
  • An EST client command line utility using the client library; and
  • An EST server which can be used for testing and development purposes.

The implementation is intended to be mostly feature-complete, including support for:

  • The optional /csrattrs and /serverkeygen operations, with support for server-generated private keys returned with or without additional encryption
  • The optional additional path segment
  • Optional HTTP-based client authentication on top of certificate-based TLS authentication

In addition, a non-standard operation is implemented enabling EST-like enrollment using the privacy preserving protocol for distributing credentials for keys on a Trusted Platform Module (TPM) 2.0 device, as described in Part 1, section 24 of the Trusted Platform Module 2.0 Library specification.

Installation

go install github.com/globalsign/est/cmd/estserver@latest
go install github.com/globalsign/est/cmd/estclient@latest

Quickstart

Starting the server

When started with no configuration file, the EST server listens on localhost:8443 and generates a random, transient Certificate Authority (CA) which can be used for testing:

user@host:$ estserver &
[1] 62405

Refer to the documentation for more details on using a configuration file.

Getting the CA certificates

Because we're using a random, transient CA, we must retrieve the CA certificates in insecure mode to establish an explicit trust anchor for subsequent EST operations. Since we only need the root CA certificate to establish a trust anchor, we use the -rootout flag:

user@host:$ estclient cacerts -server localhost:8443 -insecure -rootout -out anchor.pem

We will also obtain and store the full CA certificates chain, since we'll use it shortly to demonstrate reenrollment. Since we now have an explicit trust anchor, we can use it instead of the -insecure option. Since we're storing the full chain, we don't use the -rootout option here:

user@host:$ estclient cacerts -server localhost:8443 -explicit anchor.pem -out cacerts.pem

Enrolling with an existing private key

First we generate a new private key, here using openssl:

user@host:$ openssl genrsa 4096 > key.pem
Generating RSA private key, 4096 bit long modulus
.................+++
.............+++
e is 65537 (0x10001)

Then we generate a PKCS#10 certificate signing request, and enroll using the explicit trust anchor we previously obtained:

user@host:$ estclient csr -key key.pem -cn 'John Doe' -emails '[email protected]' -out csr.pem
user@host:$ estclient enroll -server localhost:8443 -explicit anchor.pem -csr csr.pem -out cert.pem

Using a configuration file, we can enroll with a private key resident on a hardware module, such as a hardware security module (HSM) or a Trusted Platform Module 2.0 (TPM) device. Refer to the documentation for more details.

Enrolling with a server-generated private key

If we're unable or unwilling to create our own private key, the EST server can generate one for us, and return it along with our certificate:

user@host:$ estclient serverkeygen -server localhost:8443 -explicit anchor.pem -cn 'Jane Doe' -out cert.pem -keyout key.pem

Note that we can omit the -csr option when enrolling and the EST client can dynamically generate a CSR for us using fields passed at the command line and the private key we specified, or an automatically-generated ephemeral private key if we are requesting server-side private key generation.

Reenrolling

Whichever way we generated our private key, we can now use it to reenroll.

To reenroll a previously obtained certificate, we must use it to authenticate ourselves during the TLS handshake with the EST server. Since our random, transient CA uses an intermediate CA certificate, we must provide a chain of certificates to the EST client, or the TLS handshake may fail.

Although providing the root CA certificate is optional for a TLS handshake, the simplest option is to provide the certificate we received along with the full chain of CA certificates which we previously obtained. To do this, we can just append those CA certificates to the certificate we received, and use that chain to reenroll:

user@host:$ cat cert.pem cacerts.pem >> certs.pem
user@host:$ estclient reenroll -server localhost:8443 -explicit anchor.pem -key key.pem -certs certs.pem -out newcert.pem

Note that when we omit the -csr option when reenrolling, the EST client automatically generates a CSR for us by copying the subject field and subject alternative name extension from the certificate we're renewing.

est's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

est's Issues

Documentation for TPM scenario

Ciao,
with regards to the following statement:

Using a configuration file, we can enroll with a private key resident on a hardware module, such as a hardware security module (HSM) or a Trusted Platform Module 2.0 (TPM) device. Refer to the documentation for more details.

How do I find the documentation? I would like to test EST server with a virtual TPM like described in https://docs.microsoft.com/en-us/azure/iot-edge/how-to-auto-provision-simulated-device-linux?view=iotedge-2018-06
Thanks!

estserver help should give the help message

Because it employs commands, estclient help is the correct way to invoke the help system, but estclient -help will still yield a help message showing the correct command to use.

For the server, estserver -help is the correct way, but estserver help will ignore the argument and start up the server. For consistency, behavior should be modified so that estserver help invokes the help system.

Need to use server in production

We are considering to use the server in production along with local CA implementation. We are aware that when we start the server we have the notification not to use it in Production mode. Is it possible to clarify what are the risks in doing so, in order to try to find a workaround?

Doc comment lists are indented

Some lists in the documentation comments are indented, causing them to be formatted as code blocks in godoc.org.

Outdent the comments to the same level as the surrounding documentation.

Error on tpmkeys while installing estclient

Hello,

The command go install github.com/globalsign/est/cmd/estclient throws the following error:

github.com/globalsign/tpmkeys /go/pkg/mod/github.com/globalsign/[email protected]/key.go:68:23: not enough arguments in call to tpm2.Sign have (io.ReadWriter, tpmutil.Handle, string, []byte, *tpm2.SigScheme) want (io.ReadWriter, tpmutil.Handle, string, []byte, *tpm2.Ticket, *tpm2.SigScheme)

Any idea on how to resolve this?

Installation guide is deprecated

Hello,

my system is running the latest go version go1.18.2 linux/amd64

With this version, the mentioned install guide is deprecated since following error is shown:
grafik

Following commands are working instead:
go install github.com/globalsign/est/cmd/estserver@latest
go install github.com/globalsign/est/cmd/estclient@latest

Generate CSR at runtime

Hello,

The package implements different APIs of EST protocol.
It expects the CSR to be ready for use, like in the enroll method.

Is it possible to generate the CSR at runtime?
And can we fetch the TLS unique value from the current client implementation?

Typical use-case: include TLS-unique value (in TLS 1.2)
Such as, after establishing the TLS connection between server and client,

  1. the TLS unique value can be retrieved from the client
  2. the TLS unique value can included in the CSR
  3. The CSR can be signed with my private key
  4. Pass the signed CSR to the EST enroll method

Thank you very much

Support Custom URL strings

Hello,

I'm trying to use the estclient for certificate enrollment together with an Aruba Clearpass server, which also provides an EST URL.

After installing the estclient successfully, I downloaded all required server certificates to my linux host and tried to enroll a certificate. Since the Clearpass URL doesn't listen on https://<EST-SERVER-IP-ADDRESS>/.well-known/est/simpleenroll but instead listens to https://<EST-SERVER-IP-ADDRESS>/.well-known/est/ca:<NUMBER> it's not possible to enroll a certificate.

The estclient only expects the server IP address and the listening port and appends the string /.well-known-est-simpleenroll automatically, so no custom paths are supported.

Feature request:

  • Allow full URL strings for parameter -server

400 invalid base64 encoding ERROR: issue, analysis and a possible solution (Microsoft Azure IoT Edge)

Hi,
If I use curl to request a certificate over the /simpleenroll endpoint, I get the "400 invalid base64 encoding" response from the EST server.

I guess the problem is caused by the BEGIN/END CERTIFICATE REQUEST header and footer in the CSR.
The EST server indeed tries to base64 decode the entire incoming CSR, header&footer included... and that causes the 'invalid base64 encoding' error.

If I remove the header/footer from the CSR, everything works.

Here are the steps to reproduce the issue:

# create a CSR
openssl req -new -nodes \
    -newkey rsa:4096 -keyout key.pem \
    -subj "/C=US/ST=Somewhere/L=Somewhere/O=company x/OU=iot/CN=device1" \
    -out csr.pem

...and you will get a csr.pem like this:

-----BEGIN CERTIFICATE REQUEST-----
MIIErjCCApYCAQAwaTELMAkGA1UEBhMCVVMxEjAQBgNVBAgMCVNvbWV3aGVyZTES
MBAGA1UEBwwJU29tZXdoZXJlMRIwEAYDVQQKDAljb21wYW55IHgxDDAKBgNVBAsM
...
t8jXqWb7efx/YiP7OFQL3DvM7+3gbgkjMoTD4mJu7GQzsMwZl5r8ecy0TXuputR7
WjM=
-----END CERTIFICATE REQUEST-----

Let's submit the CSR over the simpleenroll endpoint to request for the certificate:

# submit CSR (-k to trust the self-signed server certificate)
curl -X POST --data-binary "@csr.pem" \
      -H "Content-Type: application/pkcs10" \
      -H "Content-Transfer-Encoding: base64" \
      -k \
      https://est.contoso.com:8449/.well-known/est/simpleenroll

...and I get the 400 invalid base64 encoding error.

If I remove the header/footer from the CSR and re-submit it to the EST server, it works and I get a response with a proper certificate.

This is btw what happens if you use the EST server to issue certificates for the Azure IoT Edge 1.2 via the built-in EST integration.
The IoT Edge will issue a CSR including the header and footer, and it will get a "400 invalid base64 encoding ERROR" as a response.

As a workaround, I patched the EST server code to remove the header/footer (if any) from the incoming CSR before performing the base64 decoding. Patch is here: arlotito@502dbf8
image

With that patch applied, both curl and iotedge work without issues.

I also created a containerized est server here

I'd be happy if you could have a look at it and tell me what you think.
I'm also happy to open a PR if it helps.

Thanks!

Installation recommendation

I tried

go get github.com/globalsign/est
go install github.com/globalsign/est/cmd/estserver
go install github.com/globalsign/est/cmd/estclient

but it gave me these errors:

go install github.com/globalsign/est/cmd/estserver
    go/src/github.com/globalsign/est/internal/mockca/ca.go:39:2: cannot find package "github.com/globalsign/pemfile" in any of:
        /usr/lib/go-1.14/src/github.com/globalsign/pemfile (from $GOROOT)
        /root/go/src/github.com/globalsign/pemfile (from $GOPATH)
go install github.com/globalsign/est/cmd/estclient
cannot find module providing package github.com/globalsign/est/cmd/estclient: working directory is not part of a module

Instead, I just used this for installation:

go get -u github.com/globalsign/est/cmd/estserver
~/go/bin/estserver -version
go get -u github.com/globalsign/est/cmd/estclient
~/go/bin/estclient version

Does not work under Windows

Hello,

i succesfully compile estclient under Ubuntu (amd64) and Raspbian (armv6l) but seems that i can't compile estclient under Windows; this is the output i get:

C:\Windows\System32>go version
go version go1.22.0 windows/amd64

C:\Windows\System32>go install github.com/globalsign/est/cmd/estclient@latest
github.com/ThalesIgnite/crypto11
C:\Users\xxx.yyy\go\pkg\mod\github.com!thales!ignite\[email protected]\crypto11.go:120:16: undefined: pkcs11.ObjectHandle
C:\Users\xxx.yyy\go\pkg\mod\github.com!thales!ignite\[email protected]\crypto11.go:139:22: undefined: pkcs11.ObjectHandle
C:\Users\xxx.yyy\go\pkg\mod\github.com!thales!ignite\[email protected]\crypto11.go:167:14: undefined: pkcs11.Ctx
C:\Users\xxx.yyy\go\pkg\mod\github.com!thales!ignite\[email protected]\crypto11.go:170:16: undefined: pkcs11.TokenInfo
C:\Users\xxx.yyy\go\pkg\mod\github.com!thales!ignite\[email protected]\crypto11.go:176:27: undefined: pkcs11.SessionHandle
C:\Users\xxx.yyy\go\pkg\mod\github.com!thales!ignite\[email protected]\aead.go:56:64: undefined: pkcs11.Mechanism
C:\Users\xxx.yyy\go\pkg\mod\github.com!thales!ignite\[email protected]\aead.go:56:83: undefined: pkcs11.GCMParams
C:\Users\xxx.yyy\go\pkg\mod\github.com!thales!ignite\[email protected]\attributes.go:15:25: undefined: pkcs11.Attribute
C:\Users\xxx.yyy\go\pkg\mod\github.com!thales!ignite\[email protected]\sessions.go:34:17: undefined: pkcs11.Ctx
C:\Users\xxx.yyy\go\pkg\mod\github.com!thales!ignite\[email protected]\sessions.go:35:16: undefined: pkcs11.SessionHandle
C:\Users\xxx.yyy\go\pkg\mod\github.com!thales!ignite\[email protected]\crypto11.go:139:22: too many errors

i am not very skilled with go.

How can it be?

Thank you very much

base64 encodings should be line-broken

Per section 6.8 of RFC2045 which defines the Content-Transfer-Encoding header:

The encoded output stream must be represented in lines of no more than 76 characters each. All line breaks or other characters not found in Table 1 must be ignored by decoding software.

Currently, no line breaks appear in base64-encoded output.

All base64-encoded output used in a message with a Content-Transfer-Encoding value of base64 should be broken into lines of 76 or less characters.

Install fails

Ubuntu 18.04 on WSL clean install

$go get github.com/globalsign/est
# github.com/go-chi/chi
go/src/github.com/go-chi/chi/tree.go:60:20: invalid operation: 2 << n (shift count type int, must be unsigned integer)
# github.com/google/go-tpm/tpm2
go/src/github.com/google/go-tpm/tpm2/open_other.go:38:6: undefined: errors.Is

image

Certificates required on reenrollment

During reenrollment it is required that the certificate used to authenticate, must be same as obtained during enrollment. Unfortunately it cannot work in a case when est server is communicating with client which is not using this cert directly.

E.g. when EST server is communicating with a registrar from this RFC: https://datatracker.ietf.org/doc/html/rfc9148#name-https-coaps-registrar
In mentioned case Registrar cannot use certificate obtained during enrollment as it is EST client's certificate, and private key of this client is not available on Registrar.

It would be nice to disable such check by introducing some flag to config, so it could be turned off in that case.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.