sigstore / fulcio

Sigstore OIDC PKI
Apache License 2.0
652 stars 137 forks source link

implement modular CA #109

Closed lukehinds closed 3 years ago

lukehinds commented 3 years ago

as per #107 , implement a modular layer for CA / HSM integration.

dlorenc commented 3 years ago

I think the "lowest common denominator" API here is to switch from these protobufs to using CSRs for the API format. The "transport" layer for where to send the CSR would vary, but that's easier to make pluggable.

mmalone commented 3 years ago

Consider factoring out the HSM/KMS backend code from step-ca for this: https://github.com/smallstep/certificates/tree/master/kms

mmalone commented 3 years ago

/cc @maraino who wrote the above code and may have thoughts on how reusable it is.

step-ca can also run as a registration authority with a backing CA. We use a different interface for this, which may also be reusable for Fulcio. That code is at https://github.com/smallstep/certificates/tree/master/cas.

dlorenc commented 3 years ago

It would be nice to handle at least the following:

dlorenc commented 3 years ago

Oh, k8s even has its own basic CA.

lukehinds commented 3 years ago

Oh, k8s even has its own basic CA.

I think they are using cfssl? (I might be wrong there as its a while ago since I looked)

lukehinds commented 3 years ago

it could be handy to add AWS Certificate Manager Private Certificate Authority

My main want is SoftHSM and other pkcs11 HSM's via miekg/pkcs11 and I expect thalesignite/crypto11 to expose the crypto.Signer interface.

maraino commented 3 years ago

I'm the main the package that @mmalone mentioned, https://github.com/smallstep/certificates/tree/master/kms.

This provides a common interface for different KMS/HSMs:

The main interface looks like this:

type KeyManager interface {
    GetPublicKey(req *GetPublicKeyRequest) (crypto.PublicKey, error)
    CreateKey(req *CreateKeyRequest) (*CreateKeyResponse, error)
    CreateSigner(req *CreateSignerRequest) (crypto.Signer, error)
    Close() error
}
lukehinds commented 3 years ago

@maraino , have you considered Google Certificate Authority Service as well?

Just thinking that could mean that we possibly have smallstep/certificates/kms as a main interface to abstract the ca / hsm coverage we need?

Is AWS KMS is different to AWS Certificate Manager?

maraino commented 3 years ago

@lukehinds Yes, and there's an implementation for it too, but it's in the cas package, so it uses a different interface, the basic interface is this

type CertificateAuthorityService interface {
    CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error)
    RenewCertificate(req *RenewCertificateRequest) (*RenewCertificateResponse, error)
    RevokeCertificate(req *RevokeCertificateRequest) (*RevokeCertificateResponse, error)
}

And there are some extra methods that allow retrieving the root certificate, or even create a full PKI on Google CAS

maraino commented 3 years ago

Is AWS KMS is different from AWS Certificate Manager?

Yes, AWS KMS is this https://aws.amazon.com/kms/ I haven't look into AWS CM, but I assume an implementation would be more like the CAS one above.

mmalone commented 3 years ago

have you considered Google Certificate Authority Service as well?

We have integrated with GCP CAS. But that's a "CA Backend" service, not a "Key Management Service". The primary difference is that a CA backend accepts a CSR and returns a certificate whereas a key management service / hardware security module (KMS/HSM) exposes a lower-level signing API where you send bytes and get a signature back.

Oh, k8s even has its own basic CA... cfssl...

I think what @dlorenc might be referring to is the Kubernetes CSR resource. In a vanilla k8s cluster all this does is maintain a list of CSRs in a queue that some person/operator/whatever acting as a signer can monitor and update with an issued certificate. I don't think this is really useful here, but could be wrong.

It would be nice to handle at least the following...

It occurred to me that another way we could integrate that may be easier short-term is to have Fulcio act as an RA in front of step-ca, the same way it currently integrates with GCP CAS. Thoughts?

bobcallaway commented 3 years ago

a related question - does step-ca deal with precertificates?

maraino commented 3 years ago

a related question - does step-ca deal with precertificates?

We have an old branch that supports CT and creates precertificates for it. Right now we can generate a precertificate if you add a custom template like this one:

{
    "subject": {{ toJson .Subject }},
    "sans": {{ toJson .SANs }},
{{- if typeIs "*rsa.PublicKey" .Insecure.CR.PublicKey }}
    "keyUsage": ["keyEncipherment", "digitalSignature"],
{{- else }}
    "keyUsage": ["digitalSignature"],
{{- end }}
    "extKeyUsage": ["serverAuth", "clientAuth"],
    "extensions": [
        {"id":"1.3.6.1.4.1.11129.2.4.3", "critical": true, "value":"BQA="}
    ]
}
lukehinds commented 3 years ago

closing as fulcio has a modular system in place now