mirror of
https://github.com/google/go-attestation.git
synced 2025-05-25 11:34:20 +00:00
attest: re-work EK API (#79)
This PR adds: * Renames 'PlatformEK' to 'EK' * More consistant support of EKs without certificates * Removes HTTP GET to Intel EK certificate service * Always populates EK.Public
This commit is contained in:
parent
cd07b32602
commit
bfcbe8f1e2
@ -3,6 +3,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/ecdsa"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
@ -107,9 +108,11 @@ func runCommand(tpm *attest.TPM) error {
|
|||||||
return fmt.Errorf("failed to read EKs: %v", err)
|
return fmt.Errorf("failed to read EKs: %v", err)
|
||||||
}
|
}
|
||||||
for _, ek := range eks {
|
for _, ek := range eks {
|
||||||
if ek.Cert != nil {
|
data, err := encodeEK(ek)
|
||||||
fmt.Printf("EK certificate: %x\n", ek.Cert.Raw)
|
if err != nil {
|
||||||
|
return fmt.Errorf("encoding ek: %v", err)
|
||||||
}
|
}
|
||||||
|
fmt.Printf("%s\n", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
case "list-pcrs":
|
case "list-pcrs":
|
||||||
@ -145,6 +148,33 @@ func runCommand(tpm *attest.TPM) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func encodeEK(ek attest.EK) ([]byte, error) {
|
||||||
|
if ek.Certificate != nil {
|
||||||
|
return pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: "CERTIFICATE",
|
||||||
|
Bytes: ek.Certificate.Raw,
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
switch pub := ek.Public.(type) {
|
||||||
|
case *ecdsa.PublicKey:
|
||||||
|
data, err := x509.MarshalPKIXPublicKey(pub)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("marshaling ec public key: %v", err)
|
||||||
|
}
|
||||||
|
return pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: "EC PUBLIC KEY",
|
||||||
|
Bytes: data,
|
||||||
|
}), nil
|
||||||
|
case *rsa.PublicKey:
|
||||||
|
return pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: "RSA PUBLIC KEY",
|
||||||
|
Bytes: x509.MarshalPKCS1PublicKey(pub),
|
||||||
|
}), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported public key type %T", pub)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func runDump(tpm *attest.TPM) (*internal.Dump, error) {
|
func runDump(tpm *attest.TPM) (*internal.Dump, error) {
|
||||||
var (
|
var (
|
||||||
out internal.Dump
|
out internal.Dump
|
||||||
@ -201,11 +231,8 @@ func rsaEKPEM(tpm *attest.TPM) ([]byte, error) {
|
|||||||
buf bytes.Buffer
|
buf bytes.Buffer
|
||||||
)
|
)
|
||||||
for _, ek := range eks {
|
for _, ek := range eks {
|
||||||
if ek.Cert != nil && ek.Cert.PublicKeyAlgorithm == x509.RSA {
|
if pub, ok := ek.Public.(*rsa.PublicKey); ok {
|
||||||
pk = ek.Cert.PublicKey.(*rsa.PublicKey)
|
pk = pub
|
||||||
break
|
|
||||||
} else if ek.Public != nil {
|
|
||||||
pk = ek.Public.(*rsa.PublicKey)
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,11 +156,19 @@ type PCR struct {
|
|||||||
DigestAlg crypto.Hash
|
DigestAlg crypto.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// PlatformEK represents a burned-in Endorsement Key, and its
|
// EK is a burned-in endorcement key bound to a TPM. This optionally contains
|
||||||
// corrresponding EKCert (where present).
|
// a certificate that can chain to the TPM manufacturer.
|
||||||
type PlatformEK struct {
|
type EK struct {
|
||||||
Cert *x509.Certificate
|
// Public key of the EK.
|
||||||
Public crypto.PublicKey
|
Public crypto.PublicKey
|
||||||
|
|
||||||
|
// Certificate is the EK certificate for TPMs that provide it.
|
||||||
|
Certificate *x509.Certificate
|
||||||
|
|
||||||
|
// For Intel TPMs, Intel hosts certificates at a public URL derived from the
|
||||||
|
// Public key. Clients or servers can perform an HTTP GET to this URL, and
|
||||||
|
// use ParseEKCertificate on the response body.
|
||||||
|
CertificateURL string
|
||||||
}
|
}
|
||||||
|
|
||||||
// AttestationParameters describes information about a key which is necessary
|
// AttestationParameters describes information about a key which is necessary
|
||||||
|
@ -19,11 +19,8 @@ package attest
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/rsa"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/certificate-transparency-go/x509"
|
|
||||||
|
|
||||||
"github.com/google/go-tpm-tools/simulator"
|
"github.com/google/go-tpm-tools/simulator"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -49,7 +46,7 @@ func TestSimTPM20EK(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("EKs() failed: %v", err)
|
t.Errorf("EKs() failed: %v", err)
|
||||||
}
|
}
|
||||||
if len(eks) == 0 || (eks[0].Cert == nil && eks[0].Public == nil) {
|
if len(eks) == 0 || (eks[0].Public == nil) {
|
||||||
t.Errorf("EKs() = %v, want at least 1 EK with populated fields", eks)
|
t.Errorf("EKs() = %v, want at least 1 EK with populated fields", eks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,22 +96,6 @@ func TestSimTPM20AIKCreateAndLoad(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// chooseEKPub selects the EK public which will be activated against.
|
|
||||||
func chooseEKPub(t *testing.T, eks []PlatformEK) crypto.PublicKey {
|
|
||||||
t.Helper()
|
|
||||||
|
|
||||||
for _, ek := range eks {
|
|
||||||
if ek.Cert != nil && ek.Cert.PublicKeyAlgorithm == x509.RSA {
|
|
||||||
return ek.Cert.PublicKey.(*rsa.PublicKey)
|
|
||||||
} else if ek.Public != nil {
|
|
||||||
return ek.Public
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Skip("No suitable RSA EK found")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSimTPM20ActivateCredential(t *testing.T) {
|
func TestSimTPM20ActivateCredential(t *testing.T) {
|
||||||
sim, tpm := setupSimulatedTPM(t)
|
sim, tpm := setupSimulatedTPM(t)
|
||||||
defer sim.Close()
|
defer sim.Close()
|
||||||
@ -129,7 +110,7 @@ func TestSimTPM20ActivateCredential(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("EKs() failed: %v", err)
|
t.Fatalf("EKs() failed: %v", err)
|
||||||
}
|
}
|
||||||
ek := chooseEKPub(t, EKs)
|
ek := chooseEK(t, EKs)
|
||||||
|
|
||||||
ap := ActivationParameters{
|
ap := ActivationParameters{
|
||||||
TPMVersion: TPMVersion20,
|
TPMVersion: TPMVersion20,
|
||||||
|
@ -17,11 +17,8 @@ package attest
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/rsa"
|
|
||||||
"flag"
|
"flag"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/certificate-transparency-go/x509"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -121,18 +118,14 @@ func TestAIKCreateAndLoad(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// chooseEK selects the EK public which will be activated against.
|
// chooseEK selects the EK public which will be activated against.
|
||||||
func chooseEK(t *testing.T, eks []PlatformEK) crypto.PublicKey {
|
func chooseEK(t *testing.T, eks []EK) crypto.PublicKey {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
for _, ek := range eks {
|
for _, ek := range eks {
|
||||||
if ek.Cert != nil && ek.Cert.PublicKeyAlgorithm == x509.RSA {
|
|
||||||
return ek.Cert.PublicKey.(*rsa.PublicKey)
|
|
||||||
} else if ek.Public != nil {
|
|
||||||
return ek.Public
|
return ek.Public
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
t.Skip("No suitable RSA EK found")
|
t.Fatalf("No suitable EK found")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,16 +77,14 @@ func TestTPM12EKs(t *testing.T) {
|
|||||||
tpm := openTPM12(t)
|
tpm := openTPM12(t)
|
||||||
defer tpm.Close()
|
defer tpm.Close()
|
||||||
|
|
||||||
EKs, err := tpm.EKs()
|
eks, err := tpm.EKs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to get EKs: %v", err)
|
t.Fatalf("Failed to get EKs: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(EKs) == 0 {
|
if len(eks) == 0 {
|
||||||
t.Fatalf("EKs returned nothing")
|
t.Fatalf("EKs returned nothing")
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Logf("EKCert Raw: %x\n", EKs[0].Cert.Raw)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMintAIK(t *testing.T) {
|
func TestMintAIK(t *testing.T) {
|
||||||
@ -151,7 +149,7 @@ func TestTPMActivateCredential(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to read EKs: %v", err)
|
t.Fatalf("failed to read EKs: %v", err)
|
||||||
}
|
}
|
||||||
ek := chooseEKPub(t, EKs)
|
ek := chooseEK(t, EKs)
|
||||||
|
|
||||||
ap := ActivationParameters{
|
ap := ActivationParameters{
|
||||||
TPMVersion: TPMVersion12,
|
TPMVersion: TPMVersion12,
|
||||||
|
@ -404,7 +404,7 @@ func (h *winPCP) EKCerts() ([]*x509.Certificate, error) {
|
|||||||
|
|
||||||
var out []*x509.Certificate
|
var out []*x509.Certificate
|
||||||
for _, der := range c {
|
for _, der := range c {
|
||||||
cert, err := parseCert(der)
|
cert, err := ParseEKCertificate(der)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,9 @@ package attest
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/base64"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -147,7 +150,8 @@ func readTPM2VendorAttributes(tpm io.ReadWriter) (tpm20Info, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseCert(ekCert []byte) (*x509.Certificate, error) {
|
// ParseEKCertificate parses a raw DER encoded EK certificate blob.
|
||||||
|
func ParseEKCertificate(ekCert []byte) (*x509.Certificate, error) {
|
||||||
var wasWrapped bool
|
var wasWrapped bool
|
||||||
|
|
||||||
// TCG PC Specific Implementation section 7.3.2 specifies
|
// TCG PC Specific Implementation section 7.3.2 specifies
|
||||||
@ -184,12 +188,25 @@ func parseCert(ekCert []byte) (*x509.Certificate, error) {
|
|||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
manufacturerIntel = "Intel"
|
||||||
|
intelEKCertServiceURL = "https://ekop.intel.com/ekcertservice/"
|
||||||
|
)
|
||||||
|
|
||||||
|
func intelEKURL(ekPub *rsa.PublicKey) string {
|
||||||
|
pubHash := sha256.New()
|
||||||
|
pubHash.Write(ekPub.N.Bytes())
|
||||||
|
pubHash.Write([]byte{0x1, 0x00, 0x01})
|
||||||
|
|
||||||
|
return intelEKCertServiceURL + base64.URLEncoding.EncodeToString(pubHash.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
func readEKCertFromNVRAM20(tpm io.ReadWriter) (*x509.Certificate, error) {
|
func readEKCertFromNVRAM20(tpm io.ReadWriter) (*x509.Certificate, error) {
|
||||||
ekCert, err := tpm2.NVReadEx(tpm, nvramCertIndex, tpm2.HandleOwner, "", 0)
|
ekCert, err := tpm2.NVReadEx(tpm, nvramCertIndex, tpm2.HandleOwner, "", 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("reading EK cert: %v", err)
|
return nil, fmt.Errorf("reading EK cert: %v", err)
|
||||||
}
|
}
|
||||||
return parseCert(ekCert)
|
return ParseEKCertificate(ekCert)
|
||||||
}
|
}
|
||||||
|
|
||||||
func quote20(tpm io.ReadWriter, aikHandle tpmutil.Handle, hashAlg tpm2.Algorithm, nonce []byte) (*Quote, error) {
|
func quote20(tpm io.ReadWriter, aikHandle tpmutil.Handle, hashAlg tpm2.Algorithm, nonce []byte) (*Quote, error) {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package attest
|
package attest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
@ -221,25 +222,28 @@ func readEKCertFromNVRAM12(ctx *tspi.Context) (*x509.Certificate, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("reading EK cert: %v", err)
|
return nil, fmt.Errorf("reading EK cert: %v", err)
|
||||||
}
|
}
|
||||||
return parseCert(ekCert)
|
return ParseEKCertificate(ekCert)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EKs returns the endorsement keys burned-in to the platform.
|
// EKs returns the endorsement keys burned-in to the platform.
|
||||||
func (t *TPM) EKs() ([]PlatformEK, error) {
|
func (t *TPM) EKs() ([]EK, error) {
|
||||||
var cert *x509.Certificate
|
|
||||||
var err error
|
|
||||||
switch t.version {
|
switch t.version {
|
||||||
case TPMVersion12:
|
case TPMVersion12:
|
||||||
cert, err = readEKCertFromNVRAM12(t.ctx)
|
cert, err := readEKCertFromNVRAM12(t.ctx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("readEKCertFromNVRAM failed: %v", err)
|
return nil, fmt.Errorf("readEKCertFromNVRAM failed: %v", err)
|
||||||
}
|
}
|
||||||
|
return []EK{
|
||||||
|
{Public: crypto.PublicKey(cert.PublicKey), Certificate: cert},
|
||||||
|
}, nil
|
||||||
case TPMVersion20:
|
case TPMVersion20:
|
||||||
cert, err = readEKCertFromNVRAM20(t.rwc)
|
if cert, err := readEKCertFromNVRAM20(t.rwc); err == nil {
|
||||||
|
return []EK{
|
||||||
|
{Public: crypto.PublicKey(cert.PublicKey), Certificate: cert},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
// Attempt to create an EK.
|
||||||
ekHnd, _, err := tpm2.CreatePrimary(t.rwc, tpm2.HandleEndorsement, tpm2.PCRSelection{}, "", "", defaultEKTemplate)
|
ekHnd, _, err := tpm2.CreatePrimary(t.rwc, tpm2.HandleEndorsement, tpm2.PCRSelection{}, "", "", defaultEKTemplate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("EK CreatePrimary failed: %v", err)
|
return nil, fmt.Errorf("EK CreatePrimary failed: %v", err)
|
||||||
@ -253,19 +257,17 @@ func (t *TPM) EKs() ([]PlatformEK, error) {
|
|||||||
if pub.RSAParameters == nil {
|
if pub.RSAParameters == nil {
|
||||||
return nil, errors.New("ECC EK not yet supported")
|
return nil, errors.New("ECC EK not yet supported")
|
||||||
}
|
}
|
||||||
|
return []EK{
|
||||||
return []PlatformEK{
|
{
|
||||||
{nil, &rsa.PublicKey{E: int(pub.RSAParameters.Exponent()), N: pub.RSAParameters.Modulus()}},
|
Public: &rsa.PublicKey{
|
||||||
|
E: int(pub.RSAParameters.Exponent()),
|
||||||
|
N: pub.RSAParameters.Modulus(),
|
||||||
|
},
|
||||||
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unsupported TPM version: %x", t.version)
|
return nil, fmt.Errorf("unsupported TPM version: %x", t.version)
|
||||||
}
|
}
|
||||||
|
|
||||||
return []PlatformEK{
|
|
||||||
{cert, cert.PublicKey},
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MintAIK creates an attestation key.
|
// MintAIK creates an attestation key.
|
||||||
|
54
attest/tpm_test.go
Normal file
54
attest/tpm_test.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package attest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Generated using the following command:
|
||||||
|
//
|
||||||
|
// openssl genrsa 2048|openssl rsa -outform PEM -pubout
|
||||||
|
//
|
||||||
|
var testRSAKey = mustParseRSAKey(`-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8zyTXCjVALZzjS8wgNH
|
||||||
|
nAVdt4ZGM3N450xOnLplx/RbCVwXyu83SWh0B3Ka+92aocqcHzo+j6e6Urppre/I
|
||||||
|
+7VVKTdUAr8t5gxgSLGvo+ev+zv70GF4DmJthb8JNheHCmk3RnoSFs5TnDuSdvGb
|
||||||
|
KcSzas0186LQyxvwfFjTxLweGrZKh/CTewD0/f5ozXmbTtJpl+qYrMi9GJamGlg6
|
||||||
|
N6EsWKh1xos8J/cEmS2vbyCGGADyBwRV8Zkto5EU1HJaEli10HVZf0D06vuKzzxM
|
||||||
|
+6W7LzGqzAPeaWvHi07ezShqdr5q5y1KKhFJcy8HOpwN8iFfIw70y3FtMlrMprrU
|
||||||
|
twIDAQAB
|
||||||
|
-----END PUBLIC KEY-----`)
|
||||||
|
|
||||||
|
func mustParseRSAKey(data string) *rsa.PublicKey {
|
||||||
|
pub, err := parseRSAKey(data)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return pub
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseRSAKey(data string) (*rsa.PublicKey, error) {
|
||||||
|
b, _ := pem.Decode([]byte(data))
|
||||||
|
if b == nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse PEM key")
|
||||||
|
}
|
||||||
|
pub, err := x509.ParsePKIXPublicKey(b.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("parsing public key: %v", err)
|
||||||
|
}
|
||||||
|
if rsaPub, ok := pub.(*rsa.PublicKey); ok {
|
||||||
|
return rsaPub, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("expected *rsa.PublicKey, got %T", pub)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIntelEKURL(t *testing.T) {
|
||||||
|
want := "https://ekop.intel.com/ekcertservice/7YtWV2nT3LpvSCfJt7ENIznN1R1jYkj_3S6mez3yyzg="
|
||||||
|
got := intelEKURL(testRSAKey)
|
||||||
|
if got != want {
|
||||||
|
t.Fatalf("intelEKURL(), got=%q, want=%q", got, want)
|
||||||
|
}
|
||||||
|
}
|
@ -22,15 +22,11 @@ import (
|
|||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"net/http"
|
|
||||||
|
|
||||||
tpm1 "github.com/google/go-tpm/tpm"
|
tpm1 "github.com/google/go-tpm/tpm"
|
||||||
tpmtbs "github.com/google/go-tpm/tpmutil/tbs"
|
tpmtbs "github.com/google/go-tpm/tpmutil/tbs"
|
||||||
@ -151,35 +147,36 @@ func (t *TPM) Info() (*TPMInfo, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EKs returns the Endorsement Keys burned-in to the platform.
|
// EKs returns the Endorsement Keys burned-in to the platform.
|
||||||
func (t *TPM) EKs() ([]PlatformEK, error) {
|
func (t *TPM) EKs() ([]EK, error) {
|
||||||
ekCerts, err := t.pcp.EKCerts()
|
ekCerts, err := t.pcp.EKCerts()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not read EKCerts: %v", err)
|
return nil, fmt.Errorf("could not read EKCerts: %v", err)
|
||||||
}
|
}
|
||||||
|
if len(ekCerts) > 0 {
|
||||||
var out []PlatformEK
|
var eks []EK
|
||||||
for _, cert := range ekCerts {
|
for _, cert := range ekCerts {
|
||||||
out = append(out, PlatformEK{cert, cert.PublicKey})
|
eks = append(eks, EK{Certificate: cert, Public: cert.PublicKey})
|
||||||
|
}
|
||||||
|
return eks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(out) == 0 {
|
pub, err := t.ekPub()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not read ek public key from tpm: %v", err)
|
||||||
|
}
|
||||||
|
ek := EK{Public: pub}
|
||||||
|
|
||||||
i, err := t.Info()
|
i, err := t.Info()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if i.Manufacturer.String() == "Intel" {
|
if i.Manufacturer.String() == manufacturerIntel {
|
||||||
eks, err := t.readEKCertFromServer("https://ekop.intel.com/ekcertservice/")
|
ek.CertificateURL = intelEKURL(pub)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
out = append(out, eks...)
|
|
||||||
}
|
}
|
||||||
|
return []EK{ek}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return out, nil
|
func (t *TPM) ekPub() (*rsa.PublicKey, error) {
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TPM) readEKCertFromServer(url string) ([]PlatformEK, error) {
|
|
||||||
p, err := t.pcp.EKPub()
|
p, err := t.pcp.EKPub()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not read ekpub: %v", err)
|
return nil, fmt.Errorf("could not read ekpub: %v", err)
|
||||||
@ -188,25 +185,7 @@ func (t *TPM) readEKCertFromServer(url string) ([]PlatformEK, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not decode ekpub: %v", err)
|
return nil, fmt.Errorf("could not decode ekpub: %v", err)
|
||||||
}
|
}
|
||||||
pubHash := sha256.New()
|
return ekPub, nil
|
||||||
pubHash.Write(ekPub.N.Bytes())
|
|
||||||
pubHash.Write([]byte{0x1, 0x00, 0x01})
|
|
||||||
|
|
||||||
resp, err := http.Get(url + base64.URLEncoding.EncodeToString(pubHash.Sum(nil)))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("request failed: %v")
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
d, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed reading EKCert from network: %v")
|
|
||||||
}
|
|
||||||
|
|
||||||
cert, err := parseCert(d)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("parsing certificate: %v", err)
|
|
||||||
}
|
|
||||||
return []PlatformEK{{Cert: cert}}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type bcryptRSABlobHeader struct {
|
type bcryptRSABlobHeader struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user