Skip to content

Commit

Permalink
[WIP] x509util: parse inner RKP extension
Browse files Browse the repository at this point in the history
  • Loading branch information
daviddrysdale committed Mar 26, 2024
1 parent 5b245f2 commit f2fa8cb
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 6 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/form3tech-oss/jwt-go v3.2.5+incompatible // indirect
github.com/fullstorydev/grpcurl v1.8.6
github.com/fxamacker/cbor/v2 v2.6.0 // indirect
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/mock v1.6.0
github.com/golang/protobuf v1.5.2
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ github.com/fullstorydev/grpcurl v1.8.1/go.mod h1:3BWhvHZwNO7iLXaQlojdg5NA6SxUDeP
github.com/fullstorydev/grpcurl v1.8.2/go.mod h1:YvWNT3xRp2KIRuvCphFodG0fKkMXwaxA9CJgKCcyzUQ=
github.com/fullstorydev/grpcurl v1.8.6 h1:WylAwnPauJIofYSHqqMTC1eEfUIzqzevXyogBxnQquo=
github.com/fullstorydev/grpcurl v1.8.6/go.mod h1:WhP7fRQdhxz2TkL97u+TCb505sxfH78W1usyoB3tepw=
github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
Expand Down Expand Up @@ -761,6 +763,8 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.7 h1:aXiFAgRugfJ27UFDsGJ9DB2FvTC73hlVXFSqq5bo9eU=
github.com/urfave/cli v1.22.7/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
Expand Down
73 changes: 67 additions & 6 deletions x509util/android.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"github.com/google/certificate-transparency-go/asn1"
"github.com/google/certificate-transparency-go/x509"
"github.com/fxamacker/cbor/v2"
)

// OIDExtensionAndroidAttestation is the OID value for an X.509 extension that holds
Expand Down Expand Up @@ -68,6 +69,23 @@ type AndroidVmComponent struct {
AuthorityHash []byte
}

// RkpProvisioningInfo describes remotely provisioned key information
type RkpProvisioningInfo struct {
CertsSigned30Days int64 `cbor:"1,keyasint"`
VerifiedFirmware *bool `cbor:"2,keyasint,omitempty"`
SocVendorCertified *bool `cbor:"3,keyasint,omitempty"`
DeviceProperties *RkpDeviceProperties `cbor:"4,keyasint,omitempty"`
}

// RkpDeviceProperties describes the device receiving an RKP key.
type RkpDeviceProperties struct {
Brand *string `cbor:"1,keyasint,omitempty"`
Device *string `cbor:"2,keyasint,omitempty"`
Manufacturer *string `cbor:"3,keyasint,omitempty"`
Model *string `cbor:"4,keyasint,omitempty"`
Product *string `cbor:"5,keyasint,omitempty"`
}

func securityLevelToString(lvl asn1.Enumerated) string {
switch lvl {
case 0:
Expand Down Expand Up @@ -189,6 +207,22 @@ func VmInfoFromCert(cert *x509.Certificate) (*AndroidVmAttestationInfo, error) {
return nil, errors.New("no Android VM Attestation extension found")
}

// RkpInfoFromCert retrieves and parses an Android VM attestation information extension
// from a certificate, if present.
func RkpInfoFromCert(cert *x509.Certificate) (*RkpProvisioningInfo, error) {
for _, ext := range cert.Extensions {
if ext.Id.Equal(OIDExtensionAndroidRkpInfo) {
var rkpInfo RkpProvisioningInfo
err := cbor.Unmarshal(ext.Value, &rkpInfo)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal RKP CBOR info: %v", err)
}
return &rkpInfo, nil
}
}
return nil, errors.New("no Android RKP Attestation extension found")
}

func showAndroidVmAttestation(result *bytes.Buffer, cert *x509.Certificate) {
count, critical := OIDInExtensions(OIDExtensionAndroidVmAttestation, cert.Extensions)
if count == 0 {
Expand All @@ -214,12 +248,39 @@ func showAndroidVmAttestation(result *bytes.Buffer, cert *x509.Certificate) {
}

func showAndroidRkpInfo(result *bytes.Buffer, cert *x509.Certificate) {
for _, ext := range cert.Extensions {
if ext.Id.Equal(OIDExtensionAndroidRkpInfo) {
result.WriteString(fmt.Sprintf(" Android RKP Information:"))
showCritical(result, ext.Critical)
appendHexData(result, ext.Value, 16, " ")
result.WriteString("\n")
count, critical := OIDInExtensions(OIDExtensionAndroidRkpInfo, cert.Extensions)
if count == 0 {
return
}
result.WriteString(fmt.Sprintf(" Android RKP Information:"))
showCritical(result, critical)
rkpInfo, err := RkpInfoFromCert(cert)
if err != nil {
result.WriteString(fmt.Sprintf(" Failed to CBOR-decode RKP info: (%s)\n", err))
return
}
result.WriteString(fmt.Sprintf(" Certs Signed Last 30d: %d\n", rkpInfo.CertsSigned30Days))
if rkpInfo.VerifiedFirmware != nil {
result.WriteString(fmt.Sprintf(" Verified Firmware: %t\n", *rkpInfo.VerifiedFirmware))
}
if rkpInfo.SocVendorCertified != nil {
result.WriteString(fmt.Sprintf(" Verified Firmware: %t\n", *rkpInfo.SocVendorCertified))
}
if rkpInfo.DeviceProperties != nil {
if rkpInfo.DeviceProperties.Brand != nil {
result.WriteString(fmt.Sprintf(" Brand: %s\n", *rkpInfo.DeviceProperties.Brand))
}
if rkpInfo.DeviceProperties.Device != nil {
result.WriteString(fmt.Sprintf(" Device: %s\n", *rkpInfo.DeviceProperties.Device))
}
if rkpInfo.DeviceProperties.Manufacturer != nil {
result.WriteString(fmt.Sprintf(" Manufacturer: %s\n", *rkpInfo.DeviceProperties.Manufacturer))
}
if rkpInfo.DeviceProperties.Model != nil {
result.WriteString(fmt.Sprintf(" Model: %s\n", *rkpInfo.DeviceProperties.Model))
}
if rkpInfo.DeviceProperties.Product != nil {
result.WriteString(fmt.Sprintf(" Product: %s\n", *rkpInfo.DeviceProperties.Product))
}
}
}
Expand Down

0 comments on commit f2fa8cb

Please sign in to comment.