// GetTaoName implements part of the Tao interface. func (t *RPC) GetTaoName() (auth.Prin, error) { r := &RPCRequest{} data, _, err := t.call(t.serviceName+".GetTaoName", r, wantData) if err != nil { return auth.Prin{}, err } return auth.UnmarshalPrin(data) }
// HostName is the client stub for LinuxHost.HostName. func (client LinuxHostAdminClient) HostName() (auth.Prin, error) { req := &LinuxHostAdminRPCRequest{} resp := new(LinuxHostAdminRPCResponse) err := client.Call("LinuxHost.HostName", req, resp) if err != nil { return auth.Prin{}, err } return auth.UnmarshalPrin(resp.Prin) }
// AddEndorsements reads the SerializedEndorsements in an attestation and adds // the ones that are predicates signed by the policy key. func AddEndorsements(guard Guard, a *Attestation, v *Verifier) error { // Before validating against the guard, check to see if there are any // predicates endorsed by the policy key. This allows truncated principals // to get the Tao CA to sign a statement of the form // TrustedHash(ext.Program(...)). for _, e := range a.SerializedEndorsements { var ea Attestation if err := proto.Unmarshal(e, &ea); err != nil { return err } f, err := auth.UnmarshalForm(ea.SerializedStatement) if err != nil { return err } says, ok := f.(auth.Says) if !ok { return fmt.Errorf("a serialized endorsement must be an auth.Says") } // TODO(tmroeder): check that this endorsement hasn't expired. pred, ok := says.Message.(auth.Pred) if !ok { return fmt.Errorf("the message in an endorsement must be a predicate") } signerPrin, err := auth.UnmarshalPrin(ea.Signer) if err != nil { return err } if !signerPrin.Identical(says.Speaker) { return fmt.Errorf("the speaker of an endorsement must be the signer") } if !v.ToPrincipal().Identical(signerPrin) { return fmt.Errorf("the signer of an endorsement must be the policy key") } if ok, err := v.Verify(ea.SerializedStatement, AttestationSigningContext, ea.Signature); (err != nil) || !ok { return fmt.Errorf("the signature on an endorsement didn't pass verification") } return guard.AddRule(pred.String()) } return nil }
// Attest is the server stub for Tao.Attest. func (server linuxHostTaoServerStub) Attest(r *RPCRequest, s *RPCResponse) error { stmt, err := auth.UnmarshalForm(r.Data) if err != nil { return err } var issuer *auth.Prin if r.Issuer != nil { p, err := auth.UnmarshalPrin(r.Issuer) if err != nil { return err } issuer = &p } a, err := server.lh.Attest(server.child, issuer, r.Time, r.Expiration, stmt) if err != nil { return err } s.Data, err = proto.Marshal(a) return err }
// ValidSigner checks the signature on an attestation and, if so, returns the signer. func (a *Attestation) ValidSigner() (auth.Prin, error) { signer, err := auth.UnmarshalPrin(a.Signer) if err != nil { return auth.Prin{}, err } if len(signer.Ext) != 0 { return auth.Prin{}, newError("tao: attestation signer principal malformed: %s", signer) } switch signer.Type { case "tpm": // The PCRs are contained in the Speaker of an auth.Says statement that // makes up the a.SerializedStatement. f, err := auth.UnmarshalForm(a.SerializedStatement) if err != nil { return auth.Prin{}, newError("tao: couldn't unmarshal the statement: %s", err) } // A TPM attestation must be an auth.Says. says, ok := f.(auth.Says) if !ok { return auth.Prin{}, newError("tao: the attestation statement was not an auth.Says statement") } // Signer is tpm; use tpm-specific signature verification. Extract the // PCRs from the issuer name, unmarshal the key as an RSA key, and call // tpm.VerifyQuote(). speaker, ok := says.Speaker.(auth.Prin) if !ok { return auth.Prin{}, newError("tao: the speaker of an attestation must be an auth.Prin") } pcrNums, pcrVals, err := ExtractPCRs(speaker) if err != nil { return auth.Prin{}, newError("tao: couldn't extract PCRs from the signer: %s", err) } pk, err := ExtractAIK(speaker) if err != nil { return auth.Prin{}, newError("tao: couldn't extract the AIK from the signer: %s", err) } if err := tpm.VerifyQuote(pk, a.SerializedStatement, a.Signature, pcrNums, pcrVals); err != nil { return auth.Prin{}, newError("tao: TPM quote failed verification: %s", err) } return signer, nil case "key": // Signer is ECDSA key, use Tao signature verification. v, err := FromPrincipal(signer) if err != nil { return auth.Prin{}, err } ok, err := v.Verify(a.SerializedStatement, AttestationSigningContext, a.Signature) if err != nil { return auth.Prin{}, err } if !ok { return auth.Prin{}, newError("tao: attestation signature invalid") } return signer, nil default: return auth.Prin{}, newError("tao: attestation signer principal unrecognized: %s", signer.String()) } }