From 7d70cea79fe7554fea990041cfbbed89c7cbd189 Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Fri, 20 Oct 2023 15:20:49 -0700 Subject: [PATCH] Allow the define a custom tpm device This commit allows to pass the device name option when initializing a tpm in the acme flow. --- utils/cautils/acmeutils.go | 19 +++++++++++---- utils/cautils/tpm.go | 48 +++++++++++++++++++++++--------------- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/utils/cautils/acmeutils.go b/utils/cautils/acmeutils.go index fe350b146..51b71eff8 100644 --- a/utils/cautils/acmeutils.go +++ b/utils/cautils/acmeutils.go @@ -830,15 +830,26 @@ func (af *acmeFlow) GetCertificate() ([]*x509.Certificate, error) { // TODO: refactor this to be cleaner by passing the TPM and/or key around // instead of creating a new instance. if af.tpmSigner != nil { + attestationURI := af.ctx.String("attestation-uri") tpmStorageDirectory := af.ctx.String("tpm-storage-directory") - t, err := tpm.New(tpm.WithStore(tpmstorage.NewDirstore(tpmStorageDirectory))) + + keyName, attURI, err := parseTPMAttestationURI(attestationURI) if err != nil { - return nil, fmt.Errorf("failed initializing TPM: %w", err) + return nil, fmt.Errorf("failed parsing --attestation-uri: %w", err) + } + + tpmOpts := []tpm.NewTPMOption{ + tpm.WithStore(tpmstorage.NewDirstore(tpmStorageDirectory)), } - keyName, err := parseTPMAttestationURI(af.ctx.String("attestation-uri")) + if device := attURI.Get("device"); device != "" { + tpmOpts = append(tpmOpts, tpm.WithDeviceName(device)) + } + + t, err := tpm.New(tpmOpts...) if err != nil { - return nil, fmt.Errorf("failed parsing --attestation-uri: %w", err) + return nil, fmt.Errorf("failed initializing TPM: %w", err) } + ctx := tpm.NewContext(context.Background(), t) key, err := t.GetKey(ctx, keyName) if err != nil { diff --git a/utils/cautils/tpm.go b/utils/cautils/tpm.go index 2477fb230..49535c762 100644 --- a/utils/cautils/tpm.go +++ b/utils/cautils/tpm.go @@ -37,21 +37,37 @@ import ( ) func doTPMAttestation(clictx *cli.Context, ac *ca.ACMEClient, ch *acme.Challenge, identifier string, af *acmeFlow) error { + attestationURI := clictx.String("attestation-uri") tpmStorageDirectory := clictx.String("tpm-storage-directory") - t, err := tpm.New(tpm.WithStore(tpmstorage.NewDirstore(tpmStorageDirectory))) + tpmAttestationCABaseURL := clictx.String("attestation-ca-url") + tpmAttestationCARootFile := clictx.String("attestation-ca-root") + tpmAttestationCAInsecure := clictx.Bool("attestation-ca-insecure") + insecure := clictx.Bool("insecure") + + keyName, attURI, err := parseTPMAttestationURI(attestationURI) if err != nil { - return fmt.Errorf("failed initializing TPM: %w", err) + return fmt.Errorf("failed parsing --attestation-uri: %w", err) } - tpmAttestationCABaseURL := clictx.String("attestation-ca-url") if tpmAttestationCABaseURL == "" { - return errs.RequiredFlag(clictx, "attestation-ca-url") + tpmAttestationCABaseURL = attURI.Get("attestation-ca-url") + if tpmAttestationCABaseURL == "" { + return errs.RequiredFlag(clictx, "attestation-ca-url") + } } - tpmAttestationCARootFile := clictx.String("attestation-ca-root") - tpmAttestationCAInsecure := clictx.Bool("attestation-ca-insecure") + tpmOpts := []tpm.NewTPMOption{ + tpm.WithStore(tpmstorage.NewDirstore(tpmStorageDirectory)), + } + if device := attURI.Get("device"); device != "" { + tpmOpts = append(tpmOpts, tpm.WithDeviceName(device)) + } + + t, err := tpm.New(tpmOpts...) + if err != nil { + return fmt.Errorf("failed initializing TPM: %w", err) + } - insecure := clictx.Bool("insecure") kty, crv, size, err := utils.GetKeyDetailsFromCLI(clictx, insecure, "kty", "curve", "size") if err != nil { return fmt.Errorf("failed getting key details: %w", err) @@ -78,12 +94,6 @@ func doTPMAttestation(clictx *cli.Context, ac *ca.ACMEClient, ch *acme.Challenge return fmt.Errorf("unsupported key type: %q", kty) } - attestationURI := clictx.String("attestation-uri") - keyName, err := parseTPMAttestationURI(attestationURI) - if err != nil { - return fmt.Errorf("failed parsing --attestation-uri: %w", err) - } - ctx := tpm.NewContext(context.Background(), t) info, err := t.Info(ctx) if err != nil { @@ -185,23 +195,23 @@ func doTPMAttestation(clictx *cli.Context, ac *ca.ACMEClient, ch *acme.Challenge } // parseTPMAttestationURI parses attestation URIs for `tpmkms`. -func parseTPMAttestationURI(attestationURI string) (string, error) { +func parseTPMAttestationURI(attestationURI string) (string, *uri.URI, error) { if attestationURI == "" { - return "", errors.New("attestation URI cannot be empty") + return "", nil, errors.New("attestation URI cannot be empty") } if !strings.HasPrefix(attestationURI, "tpmkms:") { - return "", fmt.Errorf("%q does not start with tpmkms", attestationURI) + return "", nil, fmt.Errorf("%q does not start with tpmkms", attestationURI) } u, err := uri.Parse(attestationURI) if err != nil { - return "", fmt.Errorf("failed parsing %q: %w", attestationURI, err) + return "", nil, fmt.Errorf("failed parsing %q: %w", attestationURI, err) } var name string if name = u.Get("name"); name == "" { - return "", fmt.Errorf("failed parsing %q: name is missing", attestationURI) + return "", nil, fmt.Errorf("failed parsing %q: name is missing", attestationURI) } // TODO(hs): more properties for objects created/attested in TPM - return name, nil + return name, u, nil } // getAK returns an AK suitable for attesting the identifier that is requested. The