diff options
-rw-r--r-- | Android.bp | 5 | ||||
-rw-r--r-- | apex/apex.go | 12 | ||||
-rw-r--r-- | apex/apex_test.go | 6 | ||||
-rw-r--r-- | apex/key.go | 58 | ||||
-rw-r--r-- | apex/testing.go | 5 |
5 files changed, 85 insertions, 1 deletions
diff --git a/Android.bp b/Android.bp index d78379a60..47a195c1d 100644 --- a/Android.bp +++ b/Android.bp @@ -253,3 +253,8 @@ build_prop { relative_install_path: "etc/ramdisk", // ramdisk/system/etc/ramdisk/build.prop visibility: ["//visibility:private"], } + +all_apex_certs { + name: "all_apex_certs", + visibility: ["//cts/tests/tests/security"], +} diff --git a/apex/apex.go b/apex/apex.go index 375d5af17..773439152 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -888,8 +888,20 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...) ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...) ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...) + + // Add a reverse dependency to all_apex_certs singleton module. + // all_apex_certs will use this dependency to collect the certificate of this apex. + ctx.AddReverseDependency(ctx.Module(), allApexCertsDepTag, "all_apex_certs") +} + +type allApexCertsDependencyTag struct { + blueprint.DependencyTag } +func (_ allApexCertsDependencyTag) ExcludeFromVisibilityEnforcement() {} + +var allApexCertsDepTag = allApexCertsDependencyTag{} + // DepsMutator for the overridden properties. func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) { if a.overridableProperties.Allowed_files != nil { diff --git a/apex/apex_test.go b/apex/apex_test.go index fa4cf3bb1..e1a958268 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -3585,7 +3585,11 @@ func TestCertificate(t *testing.T) { name: "myapex.key", public_key: "testkey.avbpubkey", private_key: "testkey.pem", - }`) + }`, + android.MockFS{ + "vendor/foo/devkeys/testkey.x509.pem": nil, + }.AddToFixture(), + ) rule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("signapk") expected := "vendor/foo/devkeys/testkey.x509.pem vendor/foo/devkeys/testkey.pk8" if actual := rule.Args["certificates"]; actual != expected { diff --git a/apex/key.go b/apex/key.go index e4214f0e0..9fa9d1e02 100644 --- a/apex/key.go +++ b/apex/key.go @@ -18,6 +18,7 @@ import ( "fmt" "android/soong/android" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -29,6 +30,7 @@ func init() { func registerApexKeyBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("apex_key", ApexKeyFactory) + ctx.RegisterParallelSingletonModuleType("all_apex_certs", allApexCertsFactory) } type apexKey struct { @@ -155,3 +157,59 @@ func writeApexKeys(ctx android.ModuleContext, module android.Module) android.Wri android.WriteFileRuleVerbatim(ctx, path, entry.String()) return path } + +var ( + pemToDer = pctx.AndroidStaticRule("pem_to_der", + blueprint.RuleParams{ + Command: `openssl x509 -inform PEM -outform DER -in $in -out $out`, + Description: "Convert certificate from PEM to DER format", + }, + ) +) + +// all_apex_certs is a singleton module that collects the certs of all apexes in the tree. +// It provides two types of output files +// 1. .pem: This is usually the checked-in x509 certificate in PEM format +// 2. .der: This is DER format of the certificate, and is generated from the PEM certificate using `openssl x509` +func allApexCertsFactory() android.SingletonModule { + m := &allApexCerts{} + android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) + return m +} + +type allApexCerts struct { + android.SingletonModuleBase +} + +func (_ *allApexCerts) GenerateAndroidBuildActions(ctx android.ModuleContext) { + var certificatesPem android.Paths + ctx.VisitDirectDeps(func(m android.Module) { + if apex, ok := m.(*apexBundle); ok { + pem, _ := apex.getCertificateAndPrivateKey(ctx) + if !android.ExistentPathForSource(ctx, pem.String()).Valid() { + if ctx.Config().AllowMissingDependencies() { + return + } else { + ctx.ModuleErrorf("Path %s is not valid\n", pem.String()) + } + } + certificatesPem = append(certificatesPem, pem) + } + }) + certificatesPem = android.SortedUniquePaths(certificatesPem) // For hermiticity + var certificatesDer android.Paths + for index, certificatePem := range certificatesPem { + certificateDer := android.PathForModuleOut(ctx, fmt.Sprintf("x509.%v.der", index)) + ctx.Build(pctx, android.BuildParams{ + Rule: pemToDer, + Input: certificatePem, + Output: certificateDer, + }) + certificatesDer = append(certificatesDer, certificateDer) + } + ctx.SetOutputFiles(certificatesPem, ".pem") + ctx.SetOutputFiles(certificatesDer, ".der") +} + +func (_ *allApexCerts) GenerateSingletonBuildActions(ctx android.SingletonContext) { +} diff --git a/apex/testing.go b/apex/testing.go index 63c5b699e..a22f640c9 100644 --- a/apex/testing.go +++ b/apex/testing.go @@ -22,6 +22,9 @@ var PrepareForTestWithApexBuildComponents = android.GroupFixturePreparers( android.FixtureRegisterWithContext(registerApexBuildComponents), android.FixtureRegisterWithContext(registerApexKeyBuildComponents), android.FixtureRegisterWithContext(registerApexDepsInfoComponents), + android.FixtureAddTextFile("all_apex_certs/Android.bp", ` + all_apex_certs { name: "all_apex_certs" } + `), // Additional files needed in tests that disallow non-existent source files. // This includes files that are needed by all, or at least most, instances of an apex module type. android.MockFS{ @@ -30,6 +33,8 @@ var PrepareForTestWithApexBuildComponents = android.GroupFixturePreparers( "build/soong/scripts/gen_ndk_backedby_apex.sh": nil, // Needed by prebuilt_apex. "build/soong/scripts/unpack-prebuilt-apex.sh": nil, + // Needed by all_apex_certs + "build/make/target/product/security/testkey.x509.pem": nil, }.AddToFixture(), android.PrepareForTestWithBuildFlag("RELEASE_DEFAULT_UPDATABLE_MODULE_VERSION", testDefaultUpdatableModuleVersion), ) |