// TODO(nick): re-enable with non-expired certificate func testUpdateIntermediate(t *testing.T) { b := newCustomizedBundlerFromFile(t, testNSSRootBundle, testIntCaBundle, "") ubiquity.Platforms = nil ubiquity.LoadPlatforms(testMetadata) // forcebundle.pem contains a newer intermediate, which should be used when bundling. ub, err := b.BundleFromFile(forcebundlePEM, "", Ubiquitous) if err != nil { t.Fatal("ubiquitous bundling failed.", err) } // Ubiquitous bundle should use the intermediate from NSS since it will score higher. if len(ub.Chain) != 2 { t.Fatal("force bundling failed. Bundle length:", len(ub.Chain)) } if ub.Status.IsRebundled == false { t.Fatal("force bundling failed, incorrect bundle.Status", ub.Status) } fb, err := b.BundleFromFile(forcebundlePEM, "", Force) if err != nil { t.Fatal("force bundling failed.", err) } // Force bundle should use the intermediate from input, indicating intermediate pool is updated. if len(fb.Chain) != 2 { t.Fatal("force bundling failed. Bundle length:", len(fb.Chain)) } if fb.Status.IsRebundled == true { t.Fatal("force bundling failed, incorrect bundle.Status", fb.Status) } }
// FIXME: test case expires in July 2015 // Regression test on ubiquity. // It is to make sure ubiquitous bundles are generated so they can be trusted by Android 2.2 // and its variants. // // Leaf cert from DraftKings.com is issued by a GoDaddy intermediate cert, // which in turn is issued by a GoDaddy Root Certificate (CN: Go Daddy Root Certificate Authority // G2). The NSS library includes this root cert. So optimal bundle should only have two certs. // However, that root cert is not present in trust stores of Android <= 2.2. Ubiquitous bundling // should be able to recognize this scenario and produces a bundle that includes the GoDaddy Root // cert as an intermediate, which is verified by older trust roots. func TestAndroidUbiquitousBundle(t *testing.T) { leafs := []string{draftkingsPEM} for _, leaf := range leafs { b := newCustomizedBundlerFromFile(t, testNSSRootBundle, testIntCaBundle, "") ubiquity.Platforms = nil ubiquity.LoadPlatforms(testMetadata) // Optimal bundle algorithm will use the Godaddy Root/GeoTrust CA. optimalBundle, err := b.BundleFromFile(leaf, "", Optimal) if err != nil { t.Fatal("Optimal bundle failed:", err) } if len(optimalBundle.Chain) != 2 { t.Fatal("Optimal bundle failed") } checkUbiquityWarningAndCode(t, optimalBundle, true) // Ubiquitous bundle will include a 2nd intermediate CA. ubiquitousBundle, err := b.BundleFromFile(leaf, "", Ubiquitous) if err != nil { t.Fatal("Ubiquitous bundle failed") } if len(ubiquitousBundle.Chain) != 3 { t.Fatal("Ubiquitous bundle failed") } if len(ubiquitousBundle.Status.Untrusted) != 0 { t.Fatal("Regression: Ubiquitous bundle has untrusted platforms: ", ubiquitousBundle.Status.Untrusted) } checkUbiquityWarningAndCode(t, ubiquitousBundle, false) } }
// Regression test on bundle with flavor 'Force'. // Compare to ubiquitous bundle which will optimize bundle length given the platform ubiquity is the same, force bundle // with return the same bundle as long as the input bundle is verified. func TestForceBundle(t *testing.T) { b := newCustomizedBundlerFromFile(t, testNSSRootBundle, testIntCaBundle, "") ubiquity.Platforms = nil ubiquity.LoadPlatforms(testMetadata) bundle, err := b.BundleFromFile(firstdataPEM, "", Ubiquitous) if err != nil { t.Fatal("ubiquitous bundling failed.", err) } if len(bundle.Chain) != 2 { t.Fatal("ubiquitous bundling failed. Bundle length:", len(bundle.Chain)) } if bundle.Status.IsRebundled == false { t.Fatal("force bundling failed, incorrect bundle.Status", bundle.Status) } bundle, err = b.BundleFromFile(firstdataPEM, "", Force) if err != nil { t.Fatal("force bundling failed.", err) } if len(bundle.Chain) != 3 { t.Fatal("force bundling failed. Bundle length:", len(bundle.Chain)) } if bundle.Status.IsRebundled == true { t.Fatal("force bundling failed, incorrect bundle.Status", bundle.Status) } }
func TestBundleFromRemoteFlavor(t *testing.T) { b := newBundler(t) ubiquity.Platforms = nil ubiquity.LoadPlatforms(testMetadata) bundle, err := b.BundleFromRemote(ECCCertSite, "", Ubiquitous) if err != nil { t.Errorf("expected no error. but an error occurred: %s", err.Error()) } if len(bundle.Chain) != 3 { t.Error("expected 3-cert bundle. Got ", len(bundle.Chain)) } if len(bundle.Status.Untrusted) != 0 { t.Error("expected no untrusted platforms. Got ", bundle.Status.Untrusted) } bundle, err = b.BundleFromRemote(ECCCertSite, "", Optimal) if err != nil { t.Errorf("expected no error. but an error occurred: %s", err.Error()) } if len(bundle.Chain) != 2 { t.Error("expected 2-cert bundle. Got ", len(bundle.Chain)) } }
// bundlerMain is the main CLI of bundler functionality. func bundlerMain(args []string, c cli.Config) (err error) { ubiquity.LoadPlatforms(c.Metadata) flavor := bundler.BundleFlavor(c.Flavor) // Initialize a bundler with CA bundle and intermediate bundle. b, err := bundler.NewBundler(c.CABundleFile, c.IntBundleFile) if err != nil { return } var bundle *bundler.Bundle if c.CertFile != "" { if c.CertFile == "-" { var certPEM, keyPEM []byte certPEM, err = cli.ReadStdin(c.CertFile) if err != nil { return } if c.KeyFile != "" { keyPEM, err = cli.ReadStdin(c.KeyFile) if err != nil { return } } bundle, err = b.BundleFromPEM(certPEM, keyPEM, flavor) if err != nil { return } } else { // Bundle the client cert bundle, err = b.BundleFromFile(c.CertFile, c.KeyFile, flavor) if err != nil { return } } } else if c.Domain != "" { bundle, err = b.BundleFromRemote(c.Domain, c.IP, flavor) if err != nil { return } } else { return errors.New("Must specify bundle target through -cert or -domain") } marshaled, err := bundle.MarshalJSON() if err != nil { return } fmt.Printf("%s", marshaled) return }
// Regression test: ubiquity bundle test with SHA2-homogeneous preference should not override root ubiquity. func TestSHA2Homogeneity(t *testing.T) { b := newCustomizedBundlerFromFile(t, testNSSRootBundle, testIntCaBundle, "") ubiquity.Platforms = nil ubiquity.LoadPlatforms(testMetadata) // The input PEM bundle is 3-cert chain with a cross-signed GeoTrust certificate, // aimed to provide cert ubiquity to Android 2.2 bundle, err := b.BundleFromFile(bunningsPEM, "", Force) if err != nil { t.Fatal("Force bundle failed:", err) } if len(bundle.Chain) != 3 { t.Fatal("Force bundle failed:") } if len(bundle.Status.Untrusted) != 0 { t.Fatal("Force bundle failed:") } // With ubiquity flavor, we should not sacrifice Android 2.2 and rebundle with a shorter chain. bundle, err = b.BundleFromFile(bunningsPEM, "", Ubiquitous) if err != nil { t.Fatal("Ubiquitous bundle failed:", err) } if len(bundle.Chain) != 3 { t.Fatal("Ubiquitous bundle failed:") } if len(bundle.Status.Untrusted) != 0 { t.Fatal("Ubiquitous bundle failed:") } // With optimal flavor, we should have a shorter chain with only SHA-2 intermediates. But Android 2.2 // is untrusted. bundle, err = b.BundleFromFile(bunningsPEM, "", Optimal) if err != nil { t.Fatal("Optimal bundle failed:", err) } if len(bundle.Chain) != 2 { t.Fatal("Optimal bundle failed:") } if len(bundle.Status.Untrusted) == 0 { t.Fatal("Optimal bundle failed:") } }
func TestUbiquitySHA2Preference(t *testing.T) { // Add a SHA-2 L1 cert to the intermediate pool. b := newCustomizedBundlerFromFile(t, sha1CA, sha1Intermediate, sha2Intermediate) ubiquity.Platforms = nil ubiquity.LoadPlatforms(testChromeMetadata) bundle, err := b.BundleFromFile(sha2LeafExp2017Jan2nd, "", Ubiquitous) if err != nil { t.Fatal("bundling failed: ", err) } // With same ubiquity score, the chain with SHA2 L1 will be chosen. And so there is no Chrome warning. if len(bundle.Status.Messages) != 2 || bundle.Status.Messages[0] != sha2Warning || bundle.Status.Messages[1] != ecdsaWarning { t.Fatal("Incorrect bundle status messages. Bundle status messages:", bundle.Status.Messages) } }
// serverMain is the command line entry point to the API server. It sets up a // new HTTP server to handle sign, bundle, and validate requests. func serverMain(args []string, c cli.Config) error { // serve doesn't support arguments. if len(args) > 0 { return errors.New("argument is provided but not defined; please refer to the usage by flag -h") } bundler.IntermediateStash = c.IntDir err := ubiquity.LoadPlatforms(c.Metadata) if err != nil { log.Error(err) } err = registerHandlers(c) if err != nil { return err } addr := fmt.Sprintf("%s:%d", c.Address, c.Port) log.Info("Now listening on ", addr) return http.ListenAndServe(addr, nil) }
// FIXME: test case expires in July 2015 func TestForceBundleFallback(t *testing.T) { leafs := []string{draftkingsPEM} for _, leaf := range leafs { b := newCustomizedBundlerFromFile(t, testNSSRootBundle, testIntCaBundle, "") ubiquity.Platforms = nil ubiquity.LoadPlatforms(testMetadata) forceBundle, err := b.BundleFromFile(leaf, "", Force) if err != nil { t.Fatal("Force bundle failed:", err) } ubiquitousBundle, err := b.BundleFromFile(leaf, "", Ubiquitous) if err != nil { t.Fatal("Ubiquitous bundle failed") } if diff(ubiquitousBundle.Chain, forceBundle.Chain) { t.Fatal("Force bundle fallback failed.") } } }
func TestChromeWarning(t *testing.T) { b := newCustomizedBundlerFromFile(t, sha1CA, sha1Intermediate, "") // The metadata contains Chrome M39, M40 and M41. The effective date for their SHA1 deprecation // is pushed to 2014-09-01 to enable unit testing. ubiquity.Platforms = nil ubiquity.LoadPlatforms(testChromeMetadata) // Bundle a leaf cert with expiration on 2015-06-02. // Expect no SHA-1 deprecation warnings but a SHA2 warning. bundle, err := b.BundleFromFile(sha2LeafExp2015Jun2nd, "", Ubiquitous) if err != nil { t.Fatal("bundling failed: ", err) } if bundle.Status.Code|errors.BundleNotUbiquitousBit != errors.BundleNotUbiquitousBit { t.Fatal("Incorrect bundle status code. Bundle status:", bundle.Status) } if len(bundle.Status.Messages) != 2 || bundle.Status.Messages[0] != sha2Warning || bundle.Status.Messages[1] != ecdsaWarning { t.Fatal("Incorrect bundle status messages. Bundle status messages:", bundle.Status.Messages) } // Bundle a leaf cert with expiration on 2016-01-02. // Expect one SHA-1 deprecation warning from Chrome M41 and a SHA2 warning. bundle, err = b.BundleFromFile(sha2LeafExp2016Jan2nd, "", Ubiquitous) if err != nil { t.Fatal("bundling failed: ", err) } if bundle.Status.Code|errors.BundleNotUbiquitousBit != errors.BundleNotUbiquitousBit { t.Fatal("Incorrect bundle status code. Bundle status:", bundle.Status) } if len(bundle.Status.Messages) != 3 || bundle.Status.Messages[0] != sha2Warning || bundle.Status.Messages[1] != ecdsaWarning || bundle.Status.Messages[2] != deprecateSHA1WarningStub+" Chrome Browser M41." { t.Fatal("Incorrect bundle status messages. Bundle status messages:", bundle.Status.Messages) } // Bundle a leaf cert with expiration on 2016-06-02. // Expect SHA-1 deprecation warnings from Chrome M40, M41 and a SHA2 warning. bundle, err = b.BundleFromFile(sha2LeafExp2016Jun2nd, "", Ubiquitous) if err != nil { t.Fatal("bundling failed: ", err) } if bundle.Status.Code|errors.BundleNotUbiquitousBit != errors.BundleNotUbiquitousBit { t.Fatal("Incorrect bundle status code. Bundle status:", bundle.Status) } if len(bundle.Status.Messages) != 3 || bundle.Status.Messages[0] != sha2Warning || bundle.Status.Messages[1] != ecdsaWarning || bundle.Status.Messages[2] != deprecateSHA1WarningStub+" Chrome Browser M40, Chrome Browser M41." { t.Fatal("Incorrect bundle status messages. Bundle status messages:", bundle.Status.Messages) } // Bundle a leaf cert with expiration on 2017-01-02. // Expect SHA-1 deprecation warnings from Chrome M39, M40, M41 and a SHA2 warning. bundle, err = b.BundleFromFile(sha2LeafExp2017Jan2nd, "", Ubiquitous) if err != nil { t.Fatal("bundling failed: ", err) } if bundle.Status.Code|errors.BundleNotUbiquitousBit != errors.BundleNotUbiquitousBit { t.Fatal("Incorrect bundle status code. Bundle status:", bundle.Status) } if len(bundle.Status.Messages) != 3 || bundle.Status.Messages[0] != sha2Warning || bundle.Status.Messages[1] != ecdsaWarning || bundle.Status.Messages[2] != deprecateSHA1WarningStub+" Chrome Browser M39, Chrome Browser M40, Chrome Browser M41." { t.Fatal("Incorrect bundle status messages. Bundle status messages:", bundle.Status.Messages) } }