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))
	}

}
Exemple #2
0
// 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 {
	conf = c
	// 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 = conf.IntDir
	var err error

	if err = ubiquity.LoadPlatforms(conf.Metadata); err != nil {
		return err
	}

	log.Info("Initializing signer")
	if s, err = sign.SignerFromConfig(c); err != nil {
		log.Warningf("couldn't initialize signer: %v", err)
	}

	if ocspSigner, err = ocspsign.SignerFromConfig(c); err != nil {
		log.Warningf("couldn't initialize ocsp signer: %v", err)
	}

	registerHandlers()

	addr := net.JoinHostPort(conf.Address, strconv.Itoa(conf.Port))
	log.Info("Now listening on ", addr)
	return http.ListenAndServe(addr, nil)
}
Exemple #3
0
// 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 certs from SurveyGizmo.com and DraftKings.com are 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.
// Also, lazada.com.ph (mentioned in CFSSL-48) is having a similar problem with GeoTrust CA.
func TestAndroidUbiquitousBundle(t *testing.T) {
	leafs := []string{sgizmoPEM, draftkingsPEM, lazadaPEM}
	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)
	}
}
func TestMetadataFormat(t *testing.T) {
	for _, file := range metadataFiles {
		if err := ubiquity.LoadPlatforms(file); err != nil {
			t.Fatal(err)
		}
	}
}
// bundlerMain is the main CLI of bundler functionality.
func bundlerMain(args []string, c cli.Config) (err error) {
	bundler.IntermediateStash = c.IntDir
	ubiquity.LoadPlatforms(c.Metadata)
	flavor := bundler.BundleFlavor(c.Flavor)
	var b *bundler.Bundler
	// If it is a force bundle, don't require ca bundle and intermediate bundle
	// Otherwise, initialize a bundler with CA bundle and intermediate bundle.
	if flavor == bundler.Force {
		b = &bundler.Bundler{}
	} else {
		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.BundleFromPEMorDER(certPEM, keyPEM, flavor, "")
			if err != nil {
				return
			}
		} else {
			// Bundle the client cert
			bundle, err = b.BundleFromFile(c.CertFile, c.KeyFile, flavor, c.Password)
			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
}
Exemple #6
0
// 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) error {
	// serve doesn't support arguments.
	if len(args) > 0 {
		return errors.New("Arguments is provided but not defined. Please refer to the usage by flag -h.")
	}

	bundler.IntermediateStash = Config.intDir
	ubiquity.LoadPlatforms(Config.metadata)

	err := registerHandlers()
	if err != nil {
		return err
	}

	addr := fmt.Sprintf("%s:%d", Config.address, Config.port)
	log.Info("Now listening on ", addr)
	return http.ListenAndServe(addr, nil)
}
Exemple #7
0
// bundlerMain is the main CLI of bundler functionality.
// TODO(zi): Decide whether to drop the argument list and only use flags to specify all the inputs.
// There are debates on whether flag or arg is more appropriate for required parameters.
func bundlerMain(args []string) (err error) {

	// Grab cert file through args only if flag values for cert and domain are absent
	if Config.certFile == "" && Config.domain == "" {
		Config.certFile, args, err = popFirstArgument(args)
		if err != nil {
			return
		}
	}

	ubiquity.LoadPlatforms(Config.metadata)
	flavor := bundler.BundleFlavor(Config.flavor)
	// Initialize a bundler with CA bundle and intermediate bundle.
	b, err := bundler.NewBundler(Config.caBundleFile, Config.intBundleFile)
	if err != nil {
		return
	}

	var bundle *bundler.Bundle
	if Config.certFile != "" {
		// Bundle the client cert
		bundle, err = b.BundleFromFile(Config.certFile, Config.keyFile, flavor)
		if err != nil {
			return
		}
	} else if Config.domain != "" {
		bundle, err = b.BundleFromRemote(Config.domain, Config.ip)
		if err != nil {
			return
		}
	}
	marshaled, err := bundle.MarshalJSON()
	if err != nil {
		return
	}
	fmt.Printf("%s", marshaled)
	return
}
Exemple #8
0
// 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 {
	conf = c
	// 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 = conf.IntDir
	var err error

	if err = ubiquity.LoadPlatforms(conf.Metadata); err != nil {
		return err
	}

	if c.DBConfigFile != "" {
		db, err = dbconf.DBFromConfig(c.DBConfigFile)
		if err != nil {
			return err
		}
	}

	log.Info("Initializing signer")

	if s, err = sign.SignerFromConfigAndDB(c, db); err != nil {
		log.Warningf("couldn't initialize signer: %v", err)
	}

	if ocspSigner, err = ocspsign.SignerFromConfig(c); err != nil {
		log.Warningf("couldn't initialize ocsp signer: %v", err)
	}

	registerHandlers()

	addr := net.JoinHostPort(conf.Address, strconv.Itoa(conf.Port))

	if conf.TLSCertFile == "" || conf.TLSKeyFile == "" {
		log.Info("Now listening on ", addr)
		return http.ListenAndServe(addr, nil)
	}
	if conf.MutualTLSCAFile != "" {
		clientPool, err := helpers.LoadPEMCertPool(conf.MutualTLSCAFile)
		if err != nil {
			return fmt.Errorf("failed to load mutual TLS CA file: %s", err)
		}

		server := http.Server{
			Addr: addr,
			TLSConfig: &tls.Config{
				ClientAuth: tls.RequireAndVerifyClientCert,
				ClientCAs:  clientPool,
			},
		}

		if conf.MutualTLSCNRegex != "" {
			log.Debugf(`Requiring CN matches regex "%s" for client connections`, conf.MutualTLSCNRegex)
			re, err := regexp.Compile(conf.MutualTLSCNRegex)
			if err != nil {
				return fmt.Errorf("malformed CN regex: %s", err)
			}
			server.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				if r != nil && r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
					if re.MatchString(r.TLS.PeerCertificates[0].Subject.CommonName) {
						http.DefaultServeMux.ServeHTTP(w, r)
						return
					}
					log.Warningf(`Rejected client cert CN "%s" does not match regex %s`,
						r.TLS.PeerCertificates[0].Subject.CommonName, conf.MutualTLSCNRegex)
				}
				http.Error(w, "Invalid CN", http.StatusForbidden)
			})
		}
		log.Info("Now listening with mutual TLS on https://", addr)
		return server.ListenAndServeTLS(conf.TLSCertFile, conf.TLSKeyFile)
	}
	log.Info("Now listening on https://", addr)
	return http.ListenAndServeTLS(addr, conf.TLSCertFile, conf.TLSKeyFile, nil)

}
Exemple #9
0
// 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 {
	conf = c
	// 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 = conf.IntDir
	var err error

	if err = ubiquity.LoadPlatforms(conf.Metadata); err != nil {
		return err
	}

	if c.DBConfigFile != "" {
		db, err = certdb.DBFromConfig(c.DBConfigFile)
		if err != nil {
			return err
		}
	}

	log.Info("Initializing signer")

	if s, err = sign.SignerFromConfigAndDB(c, db); err != nil {
		log.Warningf("couldn't initialize signer: %v", err)
	}

	if ocspSigner, err = ocspsign.SignerFromConfig(c); err != nil {
		log.Warningf("couldn't initialize ocsp signer: %v", err)
	}

	registerHandlers(conf.Stats)

	addr := net.JoinHostPort(conf.Address, strconv.Itoa(conf.Port))

	if conf.TLSCertFile == "" || conf.TLSKeyFile == "" {
		log.Info("Now listening on ", addr)
		return http.ListenAndServe(addr, nil)
	}

	log.Info("Now listening on https://", addr)

	if !conf.RequireClientTLSCertificates {
		fmt.Printf("Client certificates are not required.\n")
		return http.ListenAndServeTLS(addr, conf.TLSCertFile, conf.TLSKeyFile, nil)
	} else {
		server := &http.Server{
			Addr: addr,
			TLSConfig: &tls.Config{
				ClientAuth: tls.RequireAndVerifyClientCert,
			},
		}
		fmt.Printf("Client certificates are required.\n")
		if conf.TrustAnchorFile != "" {
			fmt.Printf("  tls trust anchors: %s\n", conf.TrustAnchorFile)
			pem, err := ioutil.ReadFile(conf.TrustAnchorFile)
			if err != nil {
				return err
			}
			pool := x509.NewCertPool()
			if !pool.AppendCertsFromPEM(pem) {
				return fmt.Errorf("Failed to load: %s\n", conf.TrustAnchorFile)
			}
			server.TLSConfig.ClientCAs = pool
		} else {
			fmt.Printf("  tls trust anchors: <from system>\n")
		}
		return server.ListenAndServeTLS(conf.TLSCertFile, conf.TLSKeyFile)
	}
}