// First return is terminate flag. func handleRequest(conn net.Conn, policyKey *tao.Keys, guard tao.Guard) error { // Expect an attestation from the client. ms := util.NewMessageStream(conn) var a tao.Attestation if err := ms.ReadMessage(&a); err != nil { return err } peerCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0] p, err := tao.ValidatePeerAttestation(&a, peerCert) if err != nil { return err } // TODO(kwalsh) most of this duplicates the work of tao.Conn if !guard.IsAuthorized(p, "Execute", nil) { return fmt.Errorf("peer is not authorized to execute, hence not authorized to connect either") } // Sign cert and put it in attestation statement // a consists of serialized statement, sig and SignerInfo // a is a says speaksfor, Delegate of speaksfor is cert and should be DER encoded // Get underlying says f, err := auth.UnmarshalForm(a.SerializedStatement) if err != nil { return err } var saysStatement *auth.Says if ptr, ok := f.(*auth.Says); ok { saysStatement = ptr } else if val, ok := f.(auth.Says); ok { saysStatement = &val } sf, ok := saysStatement.Message.(auth.Speaksfor) if ok != true { return fmt.Errorf("keynegoserver: says doesn't have a speaksfor message\n") } kprin, ok := sf.Delegate.(auth.Prin) if ok != true { return fmt.Errorf("keynegoserver: speaksfor Delegate is not auth.Prin\n") } subjectPrin, ok := sf.Delegator.(auth.Prin) if ok != true { return fmt.Errorf("keynegoserver: can't get subject principal\n") } subjectName := subjectPrin.String() details := &tao.X509Details{ Country: proto.String("US"), Organization: proto.String("Google"), OrganizationalUnit: proto.String(subjectName), CommonName: proto.String("localhost"), } subjectname := tao.NewX509Name(details) SerialNumber = SerialNumber + 1 verifier, err := tao.FromPrincipal(kprin) if err != nil { return errors.New("can't get principal from kprin") } template := policyKey.SigningKey.X509Template(subjectname) template.IsCA = false clientCert, err := policyKey.CreateSignedX509(verifier, template, "default") if err != nil { return fmt.Errorf("keynegoserver: can't create client certificate: %s\n", err) } clientDERCert := clientCert.Raw err = ioutil.WriteFile("ClientCert", clientDERCert, os.ModePerm) nowTime := time.Now().UnixNano() expireTime := time.Now().AddDate(1, 0, 0).UnixNano() // Replace self signed cert in attest request newSpeaksFor := &auth.Speaksfor{ Delegate: auth.Bytes(clientDERCert), Delegator: sf.Delegator, } keyNegoSays := auth.Says{ Speaker: policyKey.SigningKey.ToPrincipal(), Time: &nowTime, Expiration: &expireTime, Message: newSpeaksFor, } delegator, ok := sf.Delegator.(auth.Prin) if !ok { return fmt.Errorf("keynegoserver: the delegator must be a principal") } found := false for _, sprin := range delegator.Ext { if !found && (sprin.Name == "Program") { found = true } if found { kprin.Ext = append(kprin.Ext, sprin) } } ra, err := tao.GenerateAttestation(policyKey.SigningKey, nil, keyNegoSays) if err != nil { return fmt.Errorf("Couldn't attest to the new says statement: %s", err) } if _, err := ms.WriteMessage(ra); err != nil { return fmt.Errorf("Couldn't return the attestation on the channel: %s", err) } return nil }
// First return is terminate flag. func DomainRequest(conn net.Conn, policyKey *tao.Keys, guard tao.Guard) (bool, error) { fmt.Printf("DomainRequest\n") log.Printf("DomainRequest\n") // Expect a request with attestation from client. ms := util.NewMessageStream(conn) var request domain_policy.DomainCertRequest err := ms.ReadMessage(&request) if err != nil { log.Printf("DomainRequest: Couldn't read attestation from channel:", err) log.Printf("\n") return false, err } var a tao.Attestation err = proto.Unmarshal(request.Attestation, &a) if request.KeyType == nil { log.Printf("Domain: Empty key type") return false, errors.New("Empty key type") } if *request.KeyType != "ECDSA" { log.Printf("Domain: bad key type") return false, errors.New("Domain: bad key type") } subjectPublicKey, err := domain_policy.GetEcdsaKeyFromDer(request.SubjectPublicKey) if err != nil { log.Printf("DomainRequest: can't get key from der") return false, errors.New("DomainRequest: can't get key from der") } // Get hash of the public key subject. serializedKey, err := domain_policy.SerializeEcdsaKeyToInternalName(subjectPublicKey.(*ecdsa.PublicKey)) if err != nil || serializedKey == nil { log.Printf("DomainRequest: Can't serialize key to internal format\n") return false, errors.New("DomainRequest: Can't serialize key to internal format") } subjectKeyHash := domain_policy.GetKeyHash(serializedKey) peerCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0] err = tao.ValidatePeerAttestation(&a, peerCert, guard) /* if err != nil { log.Printf("Domain: RequestCouldn't validate peer attestation:", err) return false, err } fmt.Printf("DomainRequest, peerCert: %x\n", peerCert) */ // Sign cert // Get Program name and key info from delegation. f, err := auth.UnmarshalForm(a.SerializedStatement) if err != nil { log.Printf("DomainRequest: Can't unmarshal a.SerializedStatement\n") return false, err } var saysStatement *auth.Says if ptr, ok := f.(*auth.Says); ok { saysStatement = ptr } else if val, ok := f.(auth.Says); ok { saysStatement = &val } sf, ok := saysStatement.Message.(auth.Speaksfor) if ok != true { log.Printf("DomainRequest: says doesnt have speaksfor message\n") return false, err } // this in the new key principal clientKeyPrincipal, ok := sf.Delegate.(auth.Prin) if ok != true { log.Printf("DomainRequest: speaksfor Delegate is not auth.Prin\n") return false, err } programPrincipal, ok := sf.Delegator.(auth.Prin) if ok != true { log.Printf("DomainRequest: Can't get subject principal\n") return false, errors.New("Can't get principal name from verifier") } programPrincipalName := programPrincipal.String() verified := IsAuthenticationValid(&programPrincipalName) if !verified { log.Printf("DomainRequest: name verification failed\n") return false, err } fmt.Printf("\nSimpleDomainService: key principal: %s, program principal: %s\n", clientKeyPrincipal, programPrincipalName) // Is the delegate the same key as was presented in the name in the request? namedHash := clientKeyPrincipal.KeyHash.(auth.Bytes) fmt.Printf("\nkeyhash: %x\n", namedHash) if bytes.Compare(subjectKeyHash[:], namedHash) != 0 { log.Printf("DomainRequest: named hash is wrong\n") fmt.Printf("DomainRequest: named hash is wrong, named: %x, computed: %x\n", namedHash, subjectKeyHash) return false, errors.New("DomainRequest: named hash is wrong") } // Sign program certificate. notBefore := time.Now() validFor := 365 * 24 * time.Hour notAfter := notBefore.Add(validFor) us := "US" issuerName := "Google" localhost := "localhost" x509SubjectName := &pkix.Name{ Organization: []string{programPrincipalName}, OrganizationalUnit: []string{programPrincipalName}, CommonName: localhost, Country: []string{us}, } x509IssuerName := &pkix.Name{ Organization: []string{issuerName}, OrganizationalUnit: []string{issuerName}, CommonName: localhost, Country: []string{us}, } // issuerName := tao.NewX509Name(&details) SerialNumber = SerialNumber + 1 var sn big.Int certificateTemplate := x509.Certificate{ SerialNumber: &sn, Issuer: *x509IssuerName, Subject: *x509SubjectName, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageKeyAgreement | x509.KeyUsageDigitalSignature, } clientCert, err := x509.CreateCertificate(rand.Reader, &certificateTemplate, policyKey.Cert, subjectPublicKey, policyKey.SigningKey.GetSigner()) if err != nil { fmt.Printf("Can't create client certificate: ", err, "\n") return false, err } zero := int32(0) var ra domain_policy.DomainCertResponse ra.Error = &zero ra.SignedCert = clientCert // Add cert chain (just policy cert for now). ra.CertChain = append(ra.CertChain, policyKey.Cert.Raw) _, err = ms.WriteMessage(&ra) if err != nil { log.Printf("DomainRequest: Couldn't return the attestation on the channel: ", err) log.Printf("\n") return false, err } return false, nil }