github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/support_infrastructure/SimpleDomainService/simpledomainservice.go (about) 1 // Copyright (c) 2014, 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 "bytes" 17 "crypto/tls" 18 "crypto/x509" 19 "crypto/x509/pkix" 20 "errors" 21 "flag" 22 "log" 23 "math/big" 24 "net" 25 "time" 26 27 "github.com/golang/protobuf/proto" 28 "github.com/jlmucb/cloudproxy/go/support_libraries/domain_policy" 29 "github.com/jlmucb/cloudproxy/go/tao" 30 "github.com/jlmucb/cloudproxy/go/tao/auth" 31 "github.com/jlmucb/cloudproxy/go/util" 32 ) 33 34 var network = flag.String("network", "tcp", "The network to use for connections") 35 var addr = flag.String("addr", "localhost:8124", "The address to listen on") 36 var domainPass = flag.String("password", "xxx", "The domain password") 37 var configPath = flag.String("config", 38 "/Domains/domain.simpleexample/tao.config", "The Tao domain config") 39 var servicePath = flag.String("service_path", 40 "/Domains/domain.simpleexample/SimpleDomainService", "The Tao domain config") 41 42 var SerialNumber int64 43 44 func IsAuthenticationValid(name *string) bool { 45 log.Printf("simpledomainservice, IsAuthenticationValid name is %s\n", *name) 46 if name == nil { 47 return false 48 } 49 log.Printf("simpledomainservice, IsAuthenticationValid returning true\n") 50 return true 51 } 52 53 54 // First return is terminate flag. 55 func DomainRequest(conn net.Conn, policyKey *tao.Keys, guard tao.Guard) (bool, error) { 56 log.Printf("DomainRequest\n") 57 58 // Expect a request with attestation from client. 59 ms := util.NewMessageStream(conn) 60 var request domain_policy.DomainCertRequest 61 err := ms.ReadMessage(&request) 62 if err != nil { 63 log.Printf("DomainRequest: Couldn't read attestation from channel. Error : %v", err) 64 log.Printf("\n") 65 return false, err 66 } 67 68 var a tao.Attestation 69 err = proto.Unmarshal(request.Attestation, &a) 70 if request.KeyType == nil { 71 log.Printf("Domain: Empty key type") 72 return false, errors.New("Empty key type") 73 } 74 75 log.Printf("SimpleDomainService: got attestation and request ") 76 switch *request.KeyType { 77 case "ecdsap256-public", "ecdsap384-public", "ecdsap521-public", 78 "ecdsap256", "ecdsap384", "ecdsap521": 79 break 80 default: 81 log.Printf("Domain: bad key type") 82 return false, errors.New("Domain: bad key type") 83 } 84 85 subjectVerifier, err := tao.VerifierKeyFromCanonicalKeyBytes(request.SubjectPublicKey) 86 if err != nil { 87 log.Printf("DomainRequest: can't get key from der") 88 return false, errors.New("DomainRequest: can't get key from der") 89 } 90 subjectKeyHash, err := subjectVerifier.UniversalKeyNameFromVerifier() 91 if err != nil { 92 log.Printf("SimpleDomain DomainRequest: calculate universal name") 93 return false, errors.New("SimpleDomain DomainRequest: can't get key from der") 94 } 95 peerCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0] 96 log.Printf("\n") 97 log.Printf("\nNumber of peer certs: %d\n", len(conn.(*tls.Conn).ConnectionState().PeerCertificates)) 98 for i := 0; i < len(conn.(*tls.Conn).ConnectionState().PeerCertificates); i++ { 99 tao.PrintPKIXName("Issuer", &conn.(*tls.Conn).ConnectionState().PeerCertificates[i].Issuer) 100 tao.PrintPKIXName("Subject", &conn.(*tls.Conn).ConnectionState().PeerCertificates[i].Subject) 101 log.Printf("\n") 102 } 103 // TODO(jlm): Change this. 104 err = tao.ValidatePeerAttestation(&a, peerCert, guard) 105 /* 106 if err != nil { 107 log.Printf("Domain: RequestCouldn't validate peer attestation:", err) 108 return false, err 109 } 110 fmt.Printf("DomainRequest, peerCert: %x\n", peerCert) 111 */ 112 113 // Sign cert 114 log.Printf("SimpleDomainService: signing cert") 115 116 // Get Program name and key info from delegation. 117 f, err := auth.UnmarshalForm(a.SerializedStatement) 118 if err != nil { 119 log.Printf("DomainRequest: Can't unmarshal a.SerializedStatement\n") 120 return false, err 121 } 122 123 var saysStatement *auth.Says 124 if ptr, ok := f.(*auth.Says); ok { 125 saysStatement = ptr 126 } else if val, ok := f.(auth.Says); ok { 127 saysStatement = &val 128 } 129 sf, ok := saysStatement.Message.(auth.Speaksfor) 130 if ok != true { 131 log.Printf("DomainRequest: says doesnt have speaksfor message\n") 132 return false, err 133 } 134 // this in the new key principal 135 clientKeyPrincipal, ok := sf.Delegate.(auth.Prin) 136 if ok != true { 137 log.Printf("DomainRequest: speaksfor Delegate is not auth.Prin\n") 138 return false, err 139 } 140 141 programPrincipal, ok := sf.Delegator.(auth.Prin) 142 if ok != true { 143 log.Printf("DomainRequest: Can't get subject principal\n") 144 return false, errors.New("Can't get principal name from verifier") 145 } 146 programPrincipalName := programPrincipal.String() 147 verified := IsAuthenticationValid(&programPrincipalName) 148 if !verified { 149 log.Printf("DomainRequest: name verification failed\n") 150 return false, err 151 } 152 log.Printf("SimpleDomainService: key principal: %s, program principal: %s\n", clientKeyPrincipal, programPrincipalName) 153 154 // Is the delegate the same key as was presented in the name in the request? 155 namedHash := clientKeyPrincipal.KeyHash.(auth.Bytes) 156 log.Printf("keyhash: %x\n", namedHash) 157 if bytes.Compare(subjectKeyHash[:], namedHash) != 0 { 158 log.Printf("DomainRequest: named hash is wrong, named: %x, computed: %x\n", 159 namedHash, subjectKeyHash) 160 return false, errors.New("DomainRequest: named hash is wrong") 161 } 162 163 // Sign program certificate. 164 165 notBefore := time.Now() 166 validFor := 365 * 24 * time.Hour 167 notAfter := notBefore.Add(validFor) 168 169 us := "US" 170 localhost := "localhost" 171 x509SubjectName := &pkix.Name{ 172 Organization: []string{programPrincipalName}, 173 OrganizationalUnit: []string{programPrincipalName}, 174 CommonName: localhost, 175 Country: []string{us}, 176 } 177 178 log.Printf("Signing cert for ") 179 tao.PrintPKIXName("Subject", x509SubjectName) 180 log.Printf(" with \n") 181 tao.PrintPKIXName("Issuer", &policyKey.Cert.Issuer) 182 log.Printf("\n") 183 184 SerialNumber = SerialNumber + 1 185 var sn big.Int 186 certificateTemplate := &x509.Certificate{ 187 SerialNumber: &sn, 188 Issuer: policyKey.Cert.Issuer, 189 Subject: *x509SubjectName, 190 NotBefore: notBefore, 191 NotAfter: notAfter, 192 KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageKeyAgreement | x509.KeyUsageDigitalSignature, 193 } 194 195 signerAlg := tao.SignerTypeFromSuiteName(tao.TaoCryptoSuite) 196 if signerAlg == nil { 197 return false, errors.New("Bad suite") 198 } 199 pkAlg := tao.PublicKeyAlgFromSignerAlg(*signerAlg) 200 sigAlg := tao.SignatureAlgFromSignerAlg(*signerAlg) 201 if pkAlg < 0 || sigAlg < 0 { 202 return false, errors.New("Bad signing algs") 203 } 204 clientCert, err := policyKey.SigningKey.CreateSignedX509FromTemplate(policyKey.Cert, certificateTemplate, 205 subjectVerifier, pkAlg, sigAlg) 206 207 zero := int32(0) 208 var ra domain_policy.DomainCertResponse 209 ra.Error = &zero 210 ra.SignedCert = clientCert.Raw 211 212 // Add cert chain (just policy cert for now). 213 ra.CertChain = append(ra.CertChain, policyKey.Cert.Raw) 214 215 _, err = ms.WriteMessage(&ra) 216 if err != nil { 217 log.Printf("DomainRequest: Couldn't return the attestation on the channel. Error: %v", err) 218 log.Printf("\n") 219 return false, err 220 } 221 return false, nil 222 } 223 224 func main() { 225 flag.Parse() 226 domain, err := tao.LoadDomain(*configPath, []byte(*domainPass)) 227 if domain == nil { 228 log.Printf("simpledomainservice: no domain path - %s, pass - %s, err - %s\n", 229 *configPath, *domainPass, err) 230 return 231 } else if err != nil { 232 log.Printf("simpledomainservice: Couldn't load the config path %s: %s\n", 233 *configPath, err) 234 return 235 } 236 log.Printf("simpledomainservice: Loaded domain\n") 237 if domain.Keys.Cert == nil { 238 log.Printf("\nPolicy key Cert is nil\n") 239 } else { 240 log.Printf("\nPolicy Cert Issuer: \n") 241 tao.PrintPKIXName("Issuer", &domain.Keys.Cert.Issuer) 242 log.Printf("\nPolicy Cert Subject: \n") 243 tao.PrintPKIXName("Subject", &domain.Keys.Cert.Subject) 244 log.Printf("\n\n") 245 } 246 log.Printf("\n") 247 248 // Set up temporary keys for the connection, since the only thing that 249 // matters to the remote client is that they receive a correctly-signed new 250 // attestation from the policy key. 251 // JLM: I left this in place but I'm not sure what a TLS connection with a 252 // self signed Cert buys in terms of security. 253 // The security of this protocol should not depend on the 254 // confidentiality or intergity of the channel. All that said, if we 255 // do ever distribute a signed simpledomainservice cert 256 // for this TLS channel, it would be good. 257 keys, err := tao.NewTemporaryKeys(tao.Signing) 258 if keys == nil || err != nil { 259 log.Fatalln("simpledomainservice: Couldn't set up temporary keys for connection:", err) 260 return 261 } 262 pkAlg := tao.PublicKeyAlgFromSignerAlg(*keys.SigningKey.Header.KeyType) 263 sigAlg := tao.SignatureAlgFromSignerAlg(*keys.SigningKey.Header.KeyType) 264 keys.Cert, err = keys.SigningKey.CreateSelfSignedX509(pkAlg, sigAlg, int64(1), 265 &pkix.Name{ 266 Organization: []string{"Google Tao Demo"}}) 267 if err != nil { 268 log.Fatalln("simpledomainservice: Couldn't set up a self-signed cert:", err) 269 return 270 } 271 SerialNumber = int64(time.Now().UnixNano()) / (1000000) 272 policyKey := domain.Keys 273 log.Printf("SimpleDomainService: policyKey: %v\n", policyKey) 274 log.Printf("SimpleDomainService: policyKey Subject: ") 275 tao.PrintPKIXName("Subject", &policyKey.Cert.Subject) 276 log.Printf("\n") 277 278 tlsc, err := tao.EncodeTLSCert(keys) 279 if err != nil { 280 log.Fatalln("simpledomainservice: Couldn't encode a TLS cert:", err) 281 } 282 conf := &tls.Config{ 283 RootCAs: x509.NewCertPool(), 284 Certificates: []tls.Certificate{*tlsc}, 285 InsecureSkipVerify: true, 286 ClientAuth: tls.RequireAnyClientCert, 287 } 288 sock, err := tls.Listen(*network, *addr, conf) 289 if err != nil { 290 log.Printf("simpledomainservice: error: %s\n", err) 291 } 292 if sock == nil { 293 log.Printf("simpledomainservice: Empty socket, terminating\n") 294 return 295 } 296 defer sock.Close() 297 298 log.Printf("simpledomainservice: accepting connections\n") 299 for { 300 conn, err := sock.Accept() 301 if conn == nil { 302 log.Printf("simpledomainservice: Empty connection\n") 303 return 304 } else if err != nil { 305 log.Printf("simpledomainservice: Couldn't accept a connection on %s: %s\n", *addr, err) 306 return 307 } 308 go DomainRequest(conn, policyKey, domain.Guard) 309 } 310 log.Println("simpledomainservice: finishing") 311 }