github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/support_infrastructure/domain_service/domain_server/domain_server.go (about) 1 // Copyright (c) 2016, Google Inc. 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 // http://www.apache.org/licenses/LICENSE-2.0 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, 9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 // See the License for the specific language governing permissions and 11 // limitations under the License. 12 13 package main 14 15 import ( 16 "crypto/x509" 17 "crypto/x509/pkix" 18 "errors" 19 "flag" 20 "fmt" 21 "io/ioutil" 22 "log" 23 "net" 24 "syscall" 25 "time" 26 27 "github.com/golang/protobuf/proto" 28 "github.com/jlmucb/cloudproxy/go/tao" 29 "github.com/jlmucb/cloudproxy/go/util" 30 31 // "github.com/golang/crypto/ssh/terminal" 32 "golang.org/x/crypto/ssh/terminal" 33 34 "github.com/jlmucb/cloudproxy/go/support_infrastructure/domain_service" 35 ) 36 37 var network = flag.String("network", "tcp", "The network to use for connections") 38 var addr = flag.String("addr", "localhost:8124", "The address to listen on") 39 var domainPass = flag.String("pass", "", "The domain password") 40 var configTemplate = flag.String("config_template", "./domain_template", "The Tao domain template") 41 var configPath = flag.String("domain_config", "./tao.config", "The Tao domain config file") 42 var trustedEntitiesPath = flag.String("trusted_entities", "./TrustedEntities", "File containing trusted entities.") 43 var createDomainFlag = flag.Bool("create_domain", false, "To create new domain from specified config.") 44 45 var serialNumber = 0 46 var revokedCertificates []pkix.RevokedCertificate 47 48 func getPass() []byte { 49 if domainPass == nil || *domainPass == "" { 50 // Get the password from the user. 51 fmt.Print("Policy key password: ") 52 pwd, err := terminal.ReadPassword(syscall.Stdin) 53 if err != nil { 54 log.Fatalln("Can't get password", err) 55 } 56 fmt.Println() 57 return pwd 58 } else { 59 fmt.Println("Warning: Passwords on the command line are not secure." + 60 "Use -pass option only for testing.") 61 return []byte(*domainPass) 62 } 63 } 64 65 func createDomain() (*tao.Domain, *x509.CertPool, error) { 66 var cfg tao.DomainTemplate 67 d, err := ioutil.ReadFile(*configTemplate) 68 if err != nil { 69 return nil, nil, err 70 } 71 if err := proto.UnmarshalText(string(d), &cfg); err != nil { 72 return nil, nil, err 73 } 74 pwd := getPass() 75 domain, err := tao.CreateDomain(*cfg.Config, *configPath, pwd) 76 if domain == nil { 77 log.Printf("domainserver: no domain path - %s, pass - %s, err - %s\n", 78 *configPath, pwd, err) 79 return nil, nil, err 80 } else if err != nil { 81 log.Printf("domainserver: Couldn't load the config path %s: %s\n", 82 *configPath, err) 83 return nil, nil, err 84 } 85 log.Printf("domainserver: Created domain\n") 86 err = domain.Save() 87 if err != nil { 88 return nil, nil, err 89 } 90 certPool := x509.NewCertPool() 91 certPool.AddCert(domain.Keys.Cert) 92 return domain, certPool, nil 93 } 94 95 func loadDomain() (*tao.Domain, *x509.CertPool, error) { 96 pwd := getPass() 97 domain, err := tao.LoadDomain(*configPath, pwd) 98 if domain == nil { 99 log.Printf("domainserver: no domain path - %s, pass - %s, err - %s\n", 100 *configPath, pwd, err) 101 return nil, nil, err 102 } else if err != nil { 103 log.Printf("domainserver: Couldn't load the config path %s: %s\n", 104 *configPath, err) 105 return nil, nil, err 106 } 107 log.Printf("domainserver: Loaded domain\n") 108 certPool := x509.NewCertPool() 109 certPool.AddCert(domain.Keys.Cert) 110 return domain, certPool, nil 111 } 112 113 func main() { 114 flag.Parse() 115 var domain *tao.Domain 116 var err error 117 if *createDomainFlag { 118 log.Println("Creating new domain...") 119 domain, _, err = createDomain() 120 } else { 121 log.Println("Loading domain info...") 122 domain, _, err = loadDomain() 123 } 124 text, err := ioutil.ReadFile(*trustedEntitiesPath) 125 if err != nil { 126 log.Fatalf("Can't open trusted entities file: %s", *trustedEntitiesPath) 127 } 128 trustedEntities := domain_service.TrustedEntities{} 129 err = proto.UnmarshalText(string(text), &trustedEntities) 130 if err != nil { 131 log.Fatalf("Can't parse trusted entities file: %s", *trustedEntitiesPath) 132 } 133 if err != nil { 134 log.Fatalln("domain_server: could not load domain:", err) 135 } 136 ln, err := net.Listen(*network, *addr) 137 if err != nil { 138 log.Fatalln("domain_server: could not listen at port:", err) 139 } 140 for { 141 conn, err := ln.Accept() 142 if err != nil { 143 log.Fatalln("domain_server: could not accept connection:", err) 144 } 145 // switch case 146 ms := util.NewMessageStream(conn) 147 var request domain_service.DomainServiceRequest 148 if err := ms.ReadMessage(&request); err != nil { 149 log.Printf("domain_server: Couldn't read request from channel: %s\n", err) 150 continue 151 } 152 switch *request.Type { 153 case domain_service.DomainServiceRequest_DOMAIN_CERT_REQUEST: 154 log.Println("Got Program cert request") 155 _, kPrin, prog, err := domain_service.VerifyAttestation(request.GetSerializedHostAttestation(), 156 domain) 157 if err != nil { 158 log.Printf("domain_server: Error verifying host att: %s\n", err) 159 sendError(err, ms) 160 continue 161 } 162 programKeyBytes := request.GetProgramKey() 163 verifier, err := tao.UnmarshalKey(programKeyBytes) 164 if err != nil { 165 log.Printf("domain_server: Error parsing program key: %v\n", err) 166 sendError(err, ms) 167 continue 168 } 169 if !verifier.ToPrincipal().Identical(kPrin) { 170 errStr := "domain_server: Program key in request does not match key being attested to." 171 log.Println(errStr) 172 sendError(errors.New(errStr), ms) 173 continue 174 } 175 prog_is_trusted := false 176 for _, trusted_prog := range trustedEntities.TrustedProgramTaoNames { 177 if trusted_prog == prog.String() { 178 prog_is_trusted = true 179 } 180 } 181 if !prog_is_trusted { 182 errStr := "domain_server: ProgramTaoName in request is not authorized to execute" 183 log.Println(errStr) 184 sendError(errors.New(errStr), ms) 185 continue 186 } 187 log.Println("domain_server: attestation passes verification checks, creating program cert") 188 cert, err := domain_service.GenerateProgramCert(domain, serialNumber, prog, 189 verifier, time.Now(), time.Now().AddDate(1, 0, 0)) 190 if err != nil { 191 log.Printf("domain_server: Error generating program cert: %s\n", err) 192 sendError(err, ms) 193 continue 194 } 195 resp := &domain_service.DomainServiceResponse{ 196 DerProgramCert: cert.Raw} 197 log.Println("domain_server: program cert created. Sending response back to program.") 198 if _, err := ms.WriteMessage(resp); err != nil { 199 log.Printf("domain_server: Error sending cert on the channel: %s\n ", 200 err) 201 continue 202 } 203 case domain_service.DomainServiceRequest_MANAGE_POLICY: 204 // TODO(sidtelang) 205 case domain_service.DomainServiceRequest_REVOKE_CERTIFICATE: 206 revokedCertificates, err = domain_service.RevokeCertificate( 207 request.GetSerializedPolicyAttestation(), revokedCertificates, domain) 208 if err != nil { 209 log.Printf("domain_server: Error revoking certificate: %s\n", err) 210 } 211 sendError(err, ms) 212 case domain_service.DomainServiceRequest_GET_CRL: 213 nowTime := time.Now() 214 expireTime := time.Now().AddDate(1, 0, 0) 215 crl, err := domain.Keys.SigningKey.CreateCRL(domain.Keys.Cert, 216 revokedCertificates, nowTime, expireTime) 217 resp := domain_service.DomainServiceResponse{} 218 if err != nil { 219 errStr := err.Error() 220 resp.ErrorMessage = &errStr 221 } else { 222 resp.Crl = crl 223 } 224 if _, err := ms.WriteMessage(&resp); err != nil { 225 log.Printf("domain_server: Error sending response on the channel: %s\n ", err) 226 } 227 } 228 } 229 } 230 231 func sendError(err error, ms *util.MessageStream) { 232 var errStr = "" 233 if err != nil { 234 errStr = err.Error() 235 } 236 resp := &domain_service.DomainServiceResponse{ErrorMessage: &errStr} 237 if _, err := ms.WriteMessage(resp); err != nil { 238 log.Printf("domain_server: Error sending resp on the channel: %s\n ", err) 239 } 240 }