Example #1
0
// Search implements the subprinPrim custom datalog primitive by parsing
// constant arguments of subprin/3 as principals and reporting any clauses it
// discovers.
func (sp *subprinPrim) Search(target *datalog.Literal, discovered func(c *datalog.Clause)) {
	p := target.Arg[0]
	o := target.Arg[1]
	e := target.Arg[2]
	if p.Constant() && o.Variable() && e.Variable() {
		prin, err := parseCompositePrin(p)
		if err != nil {
			return
		}
		extIndex := len(prin.Ext) - 1
		trimmedPrin := auth.Prin{
			Type: prin.Type,
			Key:  prin.Key,
			Ext:  prin.Ext[:extIndex],
		}
		extPrin := auth.PrinTail{
			Ext: []auth.PrinExt{prin.Ext[extIndex]},
		}

		parentIdent := dlengine.NewIdent(fmt.Sprintf("%q", trimmedPrin.String()))
		extIdent := dlengine.NewIdent(fmt.Sprintf("%q", extPrin.String()))
		discovered(datalog.NewClause(datalog.NewLiteral(sp, p, parentIdent, extIdent)))
	} else if p.Variable() && o.Constant() && e.Constant() {
		oprin, eprin, err := parseRootExtPrins(o, e)
		if err != nil {
			return
		}
		oprin.Ext = append(oprin.Ext, eprin.Ext...)
		oeIdent := dlengine.NewIdent(fmt.Sprintf("%q", oprin.String()))
		if len(oprin.Ext)+1 <= sp.max {
			discovered(datalog.NewClause(datalog.NewLiteral(sp, oeIdent, o, e)))
		}
	} else if p.Constant() && o.Constant() && e.Constant() {
		// Check that the constraint holds and report it as discovered.
		prin, err := parseCompositePrin(p)
		if err != nil {
			return
		}
		oprin, eprin, err := parseRootExtPrins(o, e)
		if err != nil {
			return
		}

		// Extend the root principal with the extension from the ext principal
		// and check identity. Make sure the constructed principal does
		// not exceed the given maximum principal length.
		oprin.Ext = append(oprin.Ext, eprin.Ext...)
		if prin.Identical(oprin) {
			discovered(datalog.NewClause(datalog.NewLiteral(sp, p, o, e)))
		}
	}
}
Example #2
0
func filenames(p *auth.Prin) []string {
	hash := fmt.Sprintf("%02x", sha256.Sum256([]byte(p.String())))
	dir := path.Join(Directory, hash)
	fi, err := ioutil.ReadDir(dir)
	if err != nil {
		return nil
	}
	var names []string
	for _, f := range fi {
		if f.IsDir() {
			continue
		}
		names = append(names, path.Join(dir, f.Name()))
	}
	return names
}
Example #3
0
// This function generates a Program Certificate. In particular, it generates an attestation
// signed by the domain policy key, with a statement of the form
// 'policyKey says programCert speaksFor program'
// where programCert is a X509 cert signed by the policy key with subject CommonName being the
// Tao name of the program and subject public key being programKey.
// Certificate expiration time is one year from issuing time.
func GenerateProgramCert(domain *tao.Domain, serialNumber int, programPrin *auth.Prin,
	verifier *tao.Verifier, now, expiry time.Time) (*x509.Certificate, error) {

	policyCert := domain.Keys.Cert
	x509Info := domain.Config.GetX509Info()
	programName := programPrin.String()
	x509Info.CommonName = &programName
	x509Info.OrganizationalUnit = &programName
	subjectName := tao.NewX509Name(x509Info)
	clientCert, err := domain.Keys.SigningKey.CreateSignedX509(
		policyCert, serialNumber, verifier, subjectName)
	if err != nil {
		return nil, err
	}
	return clientCert, nil
}
Example #4
0
func (m *idMap) add(prin auth.Prin) string {
	// Pick ids for the base principal name, i.e. the tao host
	//   key(...) --> keyi
	//   tpm(...) --> tpmi
	// Pick ids for all the subprincipal names
	//   Prog(...) --> Programi
	//   etc.
	p := prin.String()
	if s, ok := m.ids[p]; ok {
		return s
	}
	ext := prin.Ext
	prin.Ext = nil
	s := m.pick(template.HTMLEscapeString(prin.Type), prin.String())
	for _, e := range ext {
		s += "." + m.pick(e.Name, e.String())
	}
	tag := `<span class="id">[ %s ]<span class="pop"><span class="prin">%s</span></span></span>`
	m.ids[p] = fmt.Sprintf(tag, s, template.HTMLEscapeString(p))
	return m.ids[p]
}
Example #5
0
func main() {
	verbose.Set(true)
	options.Parse()

	profiling.ProfilePath = *options.String["profile"]

	if !verbose.Enabled {
		taoca.ConfirmNames = false
	}

	if *options.String["config"] != "" && !*options.Bool["init"] {
		err := options.Load(*options.String["config"])
		options.FailIf(err, "Can't load configuration")
	}

	fmt.Println("https/tls Certificate Authority")

	manualMode = *options.Bool["manual"]
	learnMode = *options.Bool["learn"]

	if !manualMode && tao.Parent() == nil {
		options.Fail(nil, "can't continue: automatic mode, but no host Tao available")
	}

	if *options.Bool["root"] == (*options.String["subsidiary"] != "") {
		options.Usage("must supply exactly one of -root or -subsidiary options")
	}

	host := *options.String["host"]
	port := *options.String["port"]
	addr := net.JoinHostPort(host, port)

	// TODO(kwalsh) extend tao name with operating mode and policy

	cpath := *options.String["config"]
	kdir := *options.String["keys"]
	if kdir == "" && cpath != "" {
		kdir = path.Dir(cpath)
	} else if kdir == "" {
		options.Fail(nil, "Option -keys or -config is required")
	}
	ppath := path.Join(kdir, "policy")

	var err error

	if *options.Bool["init"] {
		if cpath != "" {
			err := options.Save(cpath, "HTTPS/TLS certificate authority configuration", "persistent")
			options.FailIf(err, "Can't save configuration")
		}
		fmt.Println("" +
			"Initializing fresh HTTP/TLS CA signing key. Provide the following information,\n" +
			"to be include in the CA's own x509 certificate. Leave the response blank to\n" +
			"accept the default value.\n" +
			"\n" +
			"Configuration file: " + cpath + "\n" +
			"Keys directory: " + kdir + "\n")

		var caName *pkix.Name
		if taoca.ConfirmNames {
			if *options.Bool["root"] {
				caName = taoca.ConfirmName(caRootName)
			} else {
				caName = taoca.ConfirmName(caSubsidiaryName)
			}
		} else {
			if *options.Bool["root"] {
				caName = caRootName
			} else {
				caName = caSubsidiaryName
			}
		}

		if manualMode {
			pwd := options.Password("Choose an HTTPS/TLS CA signing key password", "pass")
			caKeys, err = tao.InitOnDiskPBEKeys(tao.Signing, pwd, kdir, caName)
			tao.ZeroBytes(pwd)
		} else {
			caKeys, err = tao.InitOnDiskTaoSealedKeys(tao.Signing, caName, tao.Parent(), kdir, tao.SealPolicyDefault)
		}
		options.FailIf(err, "Can't initialize fresh HTTPS/TLS CA signing key")
		if *options.Bool["root"] {
			fmt.Printf(""+
				"Note: To install this CA's key in the Chrome browser, go to\n"+
				"  'Settings', 'Show advanced settings...', 'Manage Certificates...', 'Authorities'\n"+
				"  then import the following file:\n"+
				"     %s\n"+
				"  Select 'Trust this certificate for identifying websites' and/or other\n"+
				"  options, then click 'OK'\n", caKeys.X509Path("default"))
		} else {
			csr := taoca.NewCertificateSigningRequest(caKeys.VerifyingKey, caName)
			*csr.IsCa = true
			srv := *options.String["subsidiary"]
			taoca.DefaultServerName = srv
			taoca.SubmitAndInstall(caKeys, csr)
		}

		if !manualMode {
			f, err := os.Open(ppath)
			if err == nil {
				f.Close()
				fmt.Printf("Using existing certificate-granting policy: %s\n", ppath)
			} else {
				fmt.Printf("Creating default certificate-granting policy: %s\n", ppath)
				fmt.Printf("Edit that file to define the certificate-granting policy.\n")
				err := util.WritePath(ppath, []byte(policy.Default), 0755, 0755)
				options.FailIf(err, "Can't save policy rules")
			}
		}
	} else {
		if manualMode {
			pwd := options.Password("HTTPS/TLS CA signing key password", "pass")
			caKeys, err = tao.LoadOnDiskPBEKeys(tao.Signing, pwd, kdir)
			tao.ZeroBytes(pwd)
		} else {
			caKeys, err = tao.LoadOnDiskTaoSealedKeys(tao.Signing, tao.Parent(), kdir, tao.SealPolicyDefault)
		}
		options.FailIf(err, "Can't load HTTP/TLS CA signing key")
	}

	netlog.Log("https_ca: start")
	netlog.Log("https_ca: manual? %v", manualMode)

	if !manualMode {
		guard, err = policy.Load(ppath)
		options.FailIf(err, "Can't load certificate-granting policy")
	}

	var prin auth.Prin
	if tao.Parent() != nil {
		prin, err = tao.Parent().GetTaoName()
		options.FailIf(err, "Can't get tao name")
	} else {
		rendezvous.DefaultServer.Connect(caKeys)
		prin = caKeys.SigningKey.ToPrincipal()
	}

	name := *options.String["name"]
	if name != "" {
		err = rendezvous.Register(rendezvous.Binding{
			Name:      proto.String(name),
			Host:      proto.String(host),
			Port:      proto.String(port),
			Protocol:  proto.String("protoc/rpc/https_ca"),
			Principal: proto.String(prin.String()),
		})
		options.FailIf(err, "Can't register with rendezvous service")
	}

	statsdelay := *options.String["stats"]
	var srv *tao.Server
	if statsdelay != "" {
		go profiling.ShowStats(&stats, statsdelay, "sign certificates")
		srv = tao.NewOpenServer(tao.ConnHandlerFunc(doResponseWithStats))
	} else {
		srv = tao.NewOpenServer(tao.ConnHandlerFunc(doResponseWithoutStats))
	}

	srv.Keys = caKeys
	fmt.Printf("Listening at %s using Tao-authenticated channels\n", addr)
	err = srv.ListenAndServe(addr)
	options.FailIf(err, "server died")

	fmt.Println("Server Done")
	netlog.Log("https_ca: done")
}