コード例 #1
0
func doResponses(conn *tao.Conn) {
	defer conn.Close()

	var peer *string
	if conn.Peer() != nil {
		peer = proto.String(conn.Peer().String())
		verbose.Printf("Processing connection requests for peer %s\n", *peer)
		netlog.Log("rendezvous: connection from peer %s", *peer)
	} else {
		verbose.Printf("Processing connection requests for anonymous peer\n")
		netlog.Log("rendezvous: connection from anonymous")
	}

	for {
		var req rendezvous.Request
		if err := conn.ReadMessage(&req); err != nil {
			if err != io.EOF {
				doError(conn, err, rendezvous.ResponseStatus_RENDEZVOUS_BAD_REQUEST, "failed to read request")
			}
			break
		}
		doResponse(&req, conn, peer)
	}
	lock.Lock()
	for k, v := range bindings {
		if v.expiration.IsZero() && v.conn == conn {
			delete(bindings, k)
			verbose.Printf("Expired binding upon close: %s\n", k)
		}
	}
	lock.Unlock()
	verbose.Println("Done processing connection requests")

	if peer == nil {
		netlog.Log("rendezvous: connection closed from anonymous")
	} else {
		netlog.Log("rendezvous: connection closed from peer %s", *peer)
	}
}
コード例 #2
0
func main() {
	verbose.Set(true)
	options.Parse()

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

	if *options.Bool["init"] {
		cpath := *options.String["config"]
		if cpath == "" {
			options.Fail(nil, "Option -init requires option -config")
		}
		fmt.Println("Initializing configuration file: " + cpath)
		err := options.Save(cpath, "Tao rendezvous configuration", "persistent")
		options.FailIf(err, "Can't save configuration")
	}

	fmt.Println("Cloudproxy Rendezvous Service")

	if tao.Parent() == nil {
		options.Fail(nil, "can't continue: no host Tao available")
	}

	allowAnon = *options.Bool["anon"]
	manualMode = *options.Bool["manual"]
	fcfsMode = *options.Bool["fcfs"]
	addr := *options.String["addr"]

	netlog.Log("rendezvous: init")
	netlog.Log("rendezvous: allow anon? %v", allowAnon)
	netlog.Log("rendezvous: manual? %v", manualMode)
	netlog.Log("rendezvous: fcfs? %v", fcfsMode)
	netlog.Log("rendezvous: addr = %v", addr)

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

	err := tao.NewOpenServer(tao.ConnHandlerFunc(doResponses)).ListenAndServe(addr)
	options.FailIf(err, "server died")

	netlog.Log("rendezvous: done")
}
コード例 #3
0
ファイル: server.go プロジェクト: kevinawalsh/taoca
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")
}
コード例 #4
0
ファイル: server.go プロジェクト: kevinawalsh/taoca
func doResponse(conn *tao.Conn) bool {
	// conn.Trace = tao.NewTrace(6, 1)
	T := profiling.NewTrace(10, 1)
	T.Start()
	defer conn.Close()

	var req taoca.Request

	if err := conn.ReadMessage(&req); err != nil {
		doError(conn, err, taoca.ResponseStatus_TAOCA_BAD_REQUEST, "failed to read request")
		return false
	}
	T.Sample("got msg") // 1

	peer := "anonymous"
	if conn.Peer() != nil {
		peer = conn.Peer().String()
	}
	T.Sample("got peer") // 2

	var errmsg string

	// Check whether the CSR is well-formed
	name := req.CSR.Name
	sanitize(name.Country, "Country", &errmsg)
	sanitize(name.State, "State/Province", &errmsg)
	sanitize(name.City, "City/Locality", &errmsg)
	sanitize(name.Organization, "Organization", &errmsg)
	ou := sanitize(name.OrganizationalUnit, "OrganizationalUnit", &errmsg)
	cn := sanitize(name.CommonName, "CommonName", &errmsg)
	years := *req.CSR.Years
	if years <= 0 {
		errmsg = "invalid validity period"
	}
	if errmsg != "" {
		doError(conn, nil, taoca.ResponseStatus_TAOCA_BAD_REQUEST, errmsg)
		return false
	}
	T.Sample("sanitized") // 3

	var ck tao.CryptoKey
	if err := proto.Unmarshal(req.CSR.PublicKey, &ck); err != nil {
		doError(conn, err, taoca.ResponseStatus_TAOCA_BAD_REQUEST, "can't unmarshal key")
		return false
	}
	subjectKey, err := tao.UnmarshalVerifierProto(&ck)
	if err != nil {
		doError(conn, err, taoca.ResponseStatus_TAOCA_BAD_REQUEST, "can't unmarshal key")
		return false
	}
	T.Sample("got subject") // 4

	// TODO(kwalsh) more robust generation of serial numbers?
	var serial int64
	if err := binary.Read(rand.Reader, binary.LittleEndian, &serial); err != nil {
		doError(conn, err, taoca.ResponseStatus_TAOCA_ERROR, "could not generate random serial number")
	}
	if serial < 0 {
		serial = ^serial
	}
	T.Sample("made serial") // 5

	if verbose.Enabled {
		printRequest(&req, subjectKey, serial, peer)
	}

	var cps, unotice string
	if manualMode {
		lock.Lock()
		var ok string
		for {
			ok = options.Confirm("Approve this request?", "no")
			if ok == "yes" || ok == "no" {
				break
			}
			fmt.Printf("I don't understand %q. Please type yes or no.\n", ok)
		}
		lock.Unlock()

		if ok != "yes" {
			doError(conn, nil, taoca.ResponseStatus_TAOCA_REQUEST_DENIED, "request is denied")
			return false
		}

		fmt.Printf("Issuing certificate.\n")

		cps = cpsTemplate + cpsManual
	} else {
		// Consult guard to enforce policy.
		if conn.Peer() == nil {
			doError(conn, nil, taoca.ResponseStatus_TAOCA_REQUEST_DENIED, "anonymous request is denied")
			return false
		}

		if learnMode {
			prin := *conn.Peer()
			if len(prin.Ext) > 0 {
				last := prin.Ext[len(prin.Ext)-1]
				tail := auth.PrinTail{
					Ext: auth.SubPrin([]auth.PrinExt{last}),
				}
				prinHash := fmt.Sprintf("Known(%v)", tail)
				if !knownHashes[prinHash] {
					fmt.Printf("Learned: %s\n", prinHash)
					knownHashes[prinHash] = true
					if err := guard.AddRule(prinHash); err != nil {
						fmt.Println("Error adding rule: %s\n", err)
					}
				}
			}
		}

		if !guard.IsAuthorized(*conn.Peer(), "ClaimCertificate", []string{*name.OrganizationalUnit, *name.CommonName}) &&
			!guard.IsAuthorized(*conn.Peer(), "ClaimCertificate", nil) {
			fmt.Printf("Policy (as follows) does not allow this request\n")
			fmt.Printf("%s\n", guard.String())
			doError(conn, nil, taoca.ResponseStatus_TAOCA_REQUEST_DENIED, "request is denied")
			return false
		}

		if _, ok := guard.(*tao.ACLGuard); ok {
			cps = cpsTemplate + cpsACL
		} else {
			cps = cpsTemplate + cpsDatalog
		}
		cps += "\n" + guard.String()
	}
	T.Sample("authenticated") // 6

	if conn.Peer() != nil {
		unotice = fmt.Sprintf(unoticeTemplate+
			"* The certificate was requested by the following Tao principal:\n\n   %v\n",
			*conn.Peer())
	} else {
		unotice = fmt.Sprintf(unoticeTemplate +
			"* The certificate was requested anonymously.\n")
	}
	cpsUrl, err := publish([]byte(cps))
	unoticeUrl, err := publish([]byte(unotice))

	// ext, err := taoca.NewUserNotice("Hello user, how are you?")
	ext, err := taoca.NewCertficationPolicy(cpsUrl, unoticeUrl)
	if err != nil {
		doError(conn, err, taoca.ResponseStatus_TAOCA_ERROR, "failed to generate certificate policy extension")
		return false
	}
	T.Sample("made cps") // 7

	netlog.Log("https_ca: issuing certificate for ou=%q cn=%q to %s", ou, cn, peer)

	template := caKeys.SigningKey.X509Template(NewX509Name(name), ext)
	template.IsCA = *req.CSR.IsCa
	template.SerialNumber.SetInt64(serial)
	cert, err := caKeys.CreateSignedX509(subjectKey, template, "default")
	if err != nil {
		doError(conn, err, taoca.ResponseStatus_TAOCA_ERROR, "failed to generate certificate")
		return false
	}
	T.Sample("signed cert") // 8

	status := taoca.ResponseStatus_TAOCA_OK
	resp := &taoca.Response{
		Status: &status,
		Cert:   []*taoca.Cert{&taoca.Cert{X509Cert: cert.Raw}},
	}
	for _, parent := range caKeys.CertChain("default") {
		resp.Cert = append(resp.Cert, &taoca.Cert{X509Cert: parent.Raw})
	}
	T.Sample("built response") // 9

	sendResponse(conn, resp)
	T.Sample("sent response") // 10
	//fmt.Println(T)
	return true
}