diff --git a/go.mod b/go.mod index ed5b51c7a6..3e4dc0190b 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 1525826f4f..b8c79c535e 100644 --- a/go.sum +++ b/go.sum @@ -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= @@ -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= diff --git a/x509util/android.go b/x509util/android.go index b07c766b43..6130822b07 100644 --- a/x509util/android.go +++ b/x509util/android.go @@ -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 @@ -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: @@ -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 { @@ -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)) } } }