func TestRevokeCertificate(t *testing.T) { k, err := tao.NewTemporaryKeys(tao.Signing) if k == nil || err != nil { t.Fatal("Can't generate signing key") } serialNumber := big.NewInt(5) says := auth.Says{ Speaker: k.SigningKey.ToPrincipal(), Message: auth.Pred{ Name: "revoke", Arg: []auth.Term{auth.Bytes(serialNumber.Bytes())}}} att, err := tao.GenerateAttestation(k.SigningKey, nil, says) if err != nil { t.Fatal("Error generating attestation.") } serAtt, err := proto.Marshal(att) if err != nil { t.Fatal("Error serializing attestation.") } revokedCerts := []pkix.RevokedCertificate{} revokedCerts, err = RevokeCertificate(serAtt, revokedCerts, &tao.Domain{Keys: k}) if err != nil { t.Fatal(err) } if num := revokedCerts[0].SerialNumber.Int64(); num != 5 { t.Fatal(fmt.Sprintf("Serial number %v doesnt match expected value 5", num)) } }
func generateAttestation(signingKey *tao.Keys, delegator *auth.Prin) (*tao.Keys, *tao.Attestation) { k, err := tao.NewTemporaryKeys(tao.Signing) if k == nil || err != nil { log.Fatalln("Can't generate signing key") } speaksFor := &auth.Speaksfor{ Delegate: k.SigningKey.ToPrincipal(), Delegator: delegator, } says := &auth.Says{ Speaker: signingKey.SigningKey.ToPrincipal(), Time: nil, Expiration: nil, Message: speaksFor, } att, err := tao.GenerateAttestation(signingKey.SigningKey, nil, *says) if err != nil { log.Fatalln(err) } return k, att }
func main() { domain, err := tao.LoadDomain(*configPath, []byte(*domainPass)) if domain == nil { log.Printf("domainserver: no domain path - %s, pass - %s, err - %s\n", *configPath, *domainPass, err) } else if err != nil { log.Printf("domainserver: Couldn't load the config path %s: %s\n", *configPath, err) } policyKey, policyCert := domain.Keys, domain.Keys.Cert if policyCert == nil { log.Fatalln("Policy cert not found") } hostKey, hostAtt := generateAttestation(policyKey, hostName) programKey, programAtt := generateAttestation(hostKey, programName) rawEnd1, err := proto.Marshal(hostAtt) if err != nil { log.Fatalln("Error serializing attestation.") } programAtt.SerializedEndorsements = [][]byte{rawEnd1} cert, err := domain_service.RequestProgramCert(programAtt, programKey.VerifyingKey, *network, *addr) if err != nil { log.Fatalln("Error:", err) } rootCerts := x509.NewCertPool() rootCerts.AddCert(domain.Keys.Cert) options := x509.VerifyOptions{Roots: rootCerts} _, err = cert.Verify(options) if err != nil { log.Fatalln("Program cert fails verification check.", err) } ver, err := tao.FromX509(cert) if err != nil { log.Fatalln("Error getting verifier from Program cert", err) } if v := programKey.VerifyingKey; !v.Equals(cert) { log.Fatalf("Key in Program cert %v differs from expected value %v.", ver, v) } // Test Certificate Revocation. serialNumber := cert.SerialNumber says := auth.Says{ Speaker: domain.Keys.SigningKey.ToPrincipal(), Message: auth.Pred{ Name: "revoke", Arg: []auth.Term{auth.Bytes(serialNumber.Bytes())}}} att, err := tao.GenerateAttestation(domain.Keys.SigningKey, nil, says) if err != nil { log.Fatalln("Error generating attestation for certificate revocation.") } err = domain_service.RequestRevokeCertificate(att, *network, *addr) if err != nil { log.Fatalln("Error revoking certificate: ", err) } crl, err := domain_service.RequestCrl(*network, *addr) if err != nil { log.Fatalln("Error getting CRL: ", err) } revokedCerts := crl.TBSCertList.RevokedCertificates if len(revokedCerts) != 1 { log.Fatalf("Revoked 1 cert and got back CRL with %v revoked certs", len(revokedCerts)) } if num := revokedCerts[0].SerialNumber.Int64(); num != serialNumber.Int64() { log.Fatalf("Serial number %v doesnt match expected value %v", num, serialNumber) } log.Println("YAY!") }
// 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 }