In this post, we’ll explore how the SDK works for interacting with tpm-ca-certificates.

Note: image generated by ChatGPT

The SDK provides a simple interface to interact with the project while abstracting much of the complexity. In fact, tpmtb is built on top of this SDK.

Let’s take a closer look at the key features offered.

Features

1. Bundle Download and Validation

In part 3, we briefly presented the different steps involved in verifying the integrity and provenance of a bundle. Since the process is quite complex, it’s strongly recommended to use the SDK to simplify these operations.

Examples

The SDK always validates the integrity and provenance of the bundle before making it available for use.

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)

func main() {
	ctx := context.Background()

	// Get the latest verified bundle
	tb, err := apiv1beta.GetTrustedBundle(ctx)
	if err != nil {
		log.Fatalf("Failed to get bundle: %v", err)
	}
	defer tb.Stop() // stop auto update process

	// Bundle is verified and ready to use!
	metadata := tb.GetRootMetadata()
	fmt.Printf("Bundle date: %s\n", metadata.Date)
	fmt.Printf("Bundle commit: %s\n", metadata.Commit)
}
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)

func main() {
	ctx := context.Background()

    // Get a specific bundle by date
	tb, err := apiv1beta.GetTrustedBundle(ctx, apiv1beta.GetConfig{
        Date: "2026-02-04",
    })
	if err != nil {
		log.Fatalf("Failed to get bundle: %v", err)
	}
	defer tb.Stop() // stop auto update process

	// Bundle is verified and ready to use!
	metadata := tb.GetRootMetadata()
	fmt.Printf("Bundle date: %s\n", metadata.Date)
	fmt.Printf("Bundle commit: %s\n", metadata.Commit)
}
package main

import (
	"context"
	"fmt"
    "log"

	"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)

func main() {
	ctx := context.Background()

	// Load bundle in offline mode
	tb, err := apiv1beta.LoadTrustedBundle(ctx, apiv1beta.LoadConfig{
		OfflineMode: true,
		CachePath:   "/path/to/cache/directory",
	})
	if err != nil {
		log.Fatalf("Failed to load bundle: %v", err)
	}

	// Bundle is verified and ready to use!
	metadata := tb.GetRootMetadata()
	fmt.Printf("Bundle date: %s\n", metadata.Date)
	fmt.Printf("Bundle commit: %s\n", metadata.Commit)
}

2. Auto-Renew

To ensure the bundle stays up to date, the SDK offers an auto-renewal feature (enabled by default).

The auto-renewal job regularly checks if a new bundle is available and automatically downloads it (while verifying its integrity).

Examples

The SDK always validates the integrity and provenance of the bundle before making it available for use.

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)

func main() {
	ctx := context.Background()

	tb, err := apiv1beta.GetTrustedBundle(ctx, apiv1beta.GetConfig{
        AutoUpdate: apiv1beta.AutoUpdateConfig{
            Interval: "24h",
        },
    })
	if err != nil {
		log.Fatalf("Failed to get bundle: %v", err)
	}
	defer tb.Stop() // stop auto update process

	// Bundle will be automatically updated according to the specified interval
	metadata := tb.GetRootMetadata()
	fmt.Printf("Bundle date: %s\n", metadata.Date)
	fmt.Printf("Bundle commit: %s\n", metadata.Commit)
}
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)

func main() {
	ctx := context.Background()

	tb, err := apiv1beta.GetTrustedBundle(ctx, apiv1beta.GetConfig{
        AutoUpdate: apiv1beta.AutoUpdateConfig{
            Disabled: true,
        },
    })
	if err != nil {
		log.Fatalf("Failed to get bundle: %v", err)
	}
	defer tb.Stop() // stop auto update process

	// Bundle is verified and ready to use!

	metadata := tb.GetRootMetadata()
	fmt.Printf("Bundle date: %s\n", metadata.Date)
	fmt.Printf("Bundle commit: %s\n", metadata.Commit)
}

3. Certificate Verification

The SDK can validate the trust of an Endorsement Key (EK) certificate.

Examples

The SDK always validates the integrity and provenance of the bundle before making it available for use.

package main

import (
	"context"
    "log"

	"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)

func main() {
	ctx := context.Background()

	tb, err := apiv1beta.GetTrustedBundle(ctx)
	if err != nil {
		log.Fatalf("Failed to get bundle: %v", err)
	}
	defer tb.Stop() // stop auto update process

	ekCert := getEKCert() // Your implementation

	// Verify the EK certificate against the trusted bundle
	if err := tb.Verify(ekCert); err != nil {
		log.Fatalf("EK certificate verification failed: %v", err)
	}

	log.Println("EK certificate verified successfully!")
}

A TPM may also store intermediate certificates. The SDK supports this kind of scenario as well.

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)

func main() {
	ctx := context.Background()

	tb, err := apiv1beta.GetTrustedBundle(ctx)
	if err != nil {
		log.Fatalf("Failed to get bundle: %v", err)
	}
	defer tb.Stop() // stop auto update process

	ekCert, intermediates := getEKCertAndIntermediates() // Your implementation

	// Verify the EK certificate against the trusted bundle
	if err := tb.Verify(ekCert, intermediates); err != nil {
		log.Fatalf("EK certificate verification failed: %v", err)
	}

	log.Println("EK certificate verified successfully!")
}

4. Vendor Filtering

You may want to restrict trust to only a limited number of vendors. For example, a company or individual may want to buy from specific vendors.

The SDK handles this by allowing filtering by vendors.

Example
package main

import (
	"context"
    "log"

	"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)

func main() {
	ctx := context.Background()

	tb, err := apiv1beta.GetTrustedBundle(ctx, apiv1beta.GetConfig{
        VendorIDs: []apiv1beta.VendorID{
            apiv1beta.AMD,
            apiv1beta.NTC,
        },
    })
	if err != nil {
		log.Fatalf("Failed to get bundle: %v", err)
	}
	defer tb.Stop() // stop auto update process

	ekCert := getEKCert() // Your implementation

	// Verify limit the trust ONLY to the specified vendors
	if err := tb.Verify(ekCert); err != nil {
		log.Fatalf("EK certificate verification failed: %v", err)
	}

	log.Println("EK certificate verified successfully!")
}

Conclusion

In this post, we’ve highlighted the various features offered by the SDK. You now have a good understanding of what’s possible and concrete examples of how to use it. In the next post, we’ll introduce a tool built on top of the SDK: tpm-trust.