Example #1
0
// 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)
}
Example #3
0
// 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
}
Example #5
0
// 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())
	}
}