github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/apps/demo/demo_server/demo_server.go (about)

     1  // Copyright (c) 2014, Kevin Walsh.  All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package main
    16  
    17  import (
    18  	"bufio"
    19  	"crypto/tls"
    20  	"crypto/x509"
    21  	"crypto/x509/pkix"
    22  	"flag"
    23  	"fmt"
    24  	"net"
    25  	"os"
    26  	"path"
    27  	"strings"
    28  
    29  	"github.com/jlmucb/cloudproxy/go/tao"
    30  	"github.com/jlmucb/cloudproxy/go/util/options"
    31  )
    32  
    33  var serverHost = flag.String("host", "0.0.0.0", "address for client/server")
    34  var serverPort = flag.String("port", "8123", "port for client/server")
    35  var serverAddr string // see main()
    36  var pingCount = flag.Int("n", 5, "Number of client/server pings")
    37  var demoAuth = flag.String("auth", "tao", "\"tcp\", \"tls\", or \"tao\"")
    38  var domainPathFlag = flag.String("tao_domain", "", "The Tao domain directory")
    39  var ca = flag.String("ca", "", "address for Tao CA, if any")
    40  
    41  var subprinRule = "(forall P: forall Hash: TrustedProgramHash(Hash) and Subprin(P, %v, Hash) implies Authorized(P, \"Execute\"))"
    42  
    43  func newTempCAGuard(v *tao.Verifier) (tao.Guard, error) {
    44  	g := tao.NewTemporaryDatalogGuard()
    45  	vprin := v.ToPrincipal()
    46  	rule := fmt.Sprintf(subprinRule, vprin)
    47  
    48  	if err := g.AddRule(rule); err != nil {
    49  		return nil, err
    50  	}
    51  	return g, nil
    52  }
    53  
    54  func doResponse(conn net.Conn, responseOk chan<- bool) {
    55  	defer conn.Close()
    56  
    57  	// Both the TLS and the Tao/TLS connections and listeners handle
    58  	// authorization during the Accept operation. So, no extra authorization is
    59  	// needed here.
    60  	msg, err := bufio.NewReader(conn).ReadString('\n')
    61  	if err != nil {
    62  		fmt.Fprintf(os.Stderr, "server: can't read: %s\n", err)
    63  		responseOk <- false
    64  		return
    65  	}
    66  	msg = strings.TrimSpace(msg)
    67  	fmt.Printf("server: got message: %s\n", msg)
    68  	responseOk <- true
    69  	fmt.Fprintf(conn, "echo(%s)\n", msg)
    70  }
    71  
    72  func doServer() {
    73  	var sock net.Listener
    74  	var err error
    75  	var keys *tao.Keys
    76  	network := "tcp"
    77  	domain, err := tao.LoadDomain(configPath(), nil)
    78  	options.FailIf(err, "error: couldn't load the tao domain from %s\n", configPath())
    79  
    80  	switch *demoAuth {
    81  	case "tcp":
    82  		sock, err = net.Listen(network, serverAddr)
    83  		options.FailIf(err, "server: couldn't listen to the network")
    84  
    85  	case "tls", "tao":
    86  		// Generate a private/public key for this hosted program (hp) and
    87  		// request attestation from the host of the statement "hp speaksFor
    88  		// host". The resulting certificate, keys.Delegation, is a chain of
    89  		// "says" statements extending to the policy key. The policy is
    90  		// checked by the host before this program is executed.
    91  		keys, err = tao.NewTemporaryTaoDelegatedKeys(tao.Signing, tao.Parent())
    92  		options.FailIf(err, "server: failed to generate delegated keys")
    93  
    94  		// Create a certificate for the hp.
    95  		pkInt := tao.PublicKeyAlgFromSignerAlg(*keys.SigningKey.Header.KeyType)
    96  		sigInt := tao.SignatureAlgFromSignerAlg(*keys.SigningKey.Header.KeyType)
    97  		keys.Cert, err = keys.SigningKey.CreateSelfSignedX509(pkInt, sigInt, int64(1),
    98  			&pkix.Name{
    99  				Organization: []string{"Google Tao Demo"}})
   100  		options.FailIf(err, "server: couldn't create certificate")
   101  
   102  		g := domain.Guard
   103  		if *ca != "" {
   104  			// Replace keys.Delegation with a "says" statement directly from
   105  			// the policy key.
   106  			na, err := tao.RequestTruncatedAttestation(network, *ca, keys, domain.Keys.VerifyingKey)
   107  			options.FailIf(err, "server: truncated attestation request failed")
   108  			keys.Delegation = na
   109  
   110  			g, err = newTempCAGuard(domain.Keys.VerifyingKey)
   111  			options.FailIf(err, "server: couldn't set up a new guard")
   112  		}
   113  
   114  		tlsc, err := tao.EncodeTLSCert(keys)
   115  		options.FailIf(err, "server: couldn't encode TLS certificate")
   116  
   117  		conf := &tls.Config{
   118  			RootCAs:            x509.NewCertPool(),
   119  			Certificates:       []tls.Certificate{*tlsc},
   120  			InsecureSkipVerify: true,
   121  			ClientAuth:         tls.RequireAnyClientCert,
   122  		}
   123  
   124  		if *demoAuth == "tao" {
   125  			sock, err = tao.Listen(network, serverAddr, conf, g, domain.Keys.VerifyingKey, keys.Delegation)
   126  			options.FailIf(err, "sever: couldn't create a taonet listener")
   127  		} else {
   128  			sock, err = tls.Listen(network, serverAddr, conf)
   129  			options.FailIf(err, "server: couldn't create a tls listener")
   130  		}
   131  	}
   132  
   133  	fmt.Printf("server: listening at %s using %s authentication.\n", serverAddr, *demoAuth)
   134  	defer sock.Close()
   135  
   136  	pings := make(chan bool, 5)
   137  	connCount := 0
   138  
   139  	go func() {
   140  		for connCount = 0; connCount < *pingCount || *pingCount < 0; connCount++ { // negative means forever
   141  			conn, err := sock.Accept()
   142  			options.FailIf(err, "server: can't accept connection")
   143  			go doResponse(conn, pings)
   144  		}
   145  	}()
   146  
   147  	pingGood := 0
   148  	pingFail := 0
   149  
   150  	for {
   151  		select {
   152  		case ok := <-pings:
   153  			if ok {
   154  				pingGood++
   155  			} else {
   156  				pingFail++
   157  			}
   158  		}
   159  	}
   160  }
   161  
   162  func main() {
   163  	flag.Parse()
   164  	serverAddr = net.JoinHostPort(*serverHost, *serverPort)
   165  	switch *demoAuth {
   166  	case "tcp", "tls", "tao":
   167  	default:
   168  		options.Usage("unrecognized authentication mode: %s\n", *demoAuth)
   169  		return
   170  	}
   171  
   172  	fmt.Println("Go Tao Demo Server")
   173  
   174  	if tao.Parent() == nil {
   175  		options.Fail(nil, "can't continue: No host Tao available")
   176  	}
   177  
   178  	doServer()
   179  	fmt.Println("Server Done")
   180  }
   181  
   182  func domainPath() string {
   183  	if *domainPathFlag != "" {
   184  		return *domainPathFlag
   185  	}
   186  	if path := os.Getenv("TAO_DOMAIN"); path != "" {
   187  		return path
   188  	}
   189  	options.Usage("Must supply -tao_domain or set $TAO_DOMAIN")
   190  	return ""
   191  }
   192  
   193  func configPath() string {
   194  	return path.Join(domainPath(), "tao.config")
   195  }