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 }