Exemplo n.º 1
0
// Input: Der encoded endorsement cert and handles
// quote key is certified key unlike in the tpm2.go library
// Returns ProgramCertRequestMessage
func Tpm2ConstructClientRequest(rw io.ReadWriter, derEkCert []byte, pcrs []int,
	qh tpm2.Handle, parentPassword string, ownerPassword string,
	keyName string) (*tpm2.ProgramCertRequestMessage, error) {

	// Generate Request
	request := new(tpm2.ProgramCertRequestMessage)
	request.ProgramKey = new(tpm2.ProgramKeyParameters)
	request.EndorsementCertBlob = derEkCert
	req_id := "001"
	request.RequestId = &req_id

	// Quote key
	keyBlob, tpm2QuoteName, _, err := tpm2.ReadPublic(rw, qh)
	if err != nil {
		return nil, err
	}
	rsaQuoteParams, err := tpm2.DecodeRsaBuf(keyBlob)
	if err != nil {
		return nil, err
	}

	modSize := int32(rsaQuoteParams.Mod_sz)

	keyType := "rsa"
	request.ProgramKey.ProgramName = &keyName
	request.ProgramKey.ProgramKeyType = &keyType
	request.ProgramKey.ProgramBitModulusSize = &modSize

	request.ProgramKey.ProgramKeyExponent = []byte{0, 1, 0, 1}
	request.ProgramKey.ProgramKeyModulus = rsaQuoteParams.Modulus
	serializedProgramKey := proto.CompactTextString(request.ProgramKey)
	sha1Hash := sha1.New()
	sha1Hash.Write([]byte(serializedProgramKey))
	hashProgramKey := sha1Hash.Sum(nil)

	sigAlg := uint16(tpm2.AlgTPM_ALG_NULL)
	attest, sig, err := tpm2.Quote(rw, qh, parentPassword, ownerPassword,
		hashProgramKey, pcrs, sigAlg)
	if err != nil {
		return nil, err
	}

	// Quote key info.
	request.QuoteKeyInfo = new(tpm2.QuoteKeyInfoMessage)
	request.QuoteKeyInfo.Name = tpm2QuoteName
	request.QuoteKeyInfo.PublicKey = new(tpm2.PublicKeyMessage)
	request.QuoteKeyInfo.PublicKey.RsaKey = new(tpm2.RsaPublicKeyMessage)
	request.QuoteKeyInfo.PublicKey.RsaKey.KeyName = &keyName

	var encAlg string
	var hashAlg string
	if rsaQuoteParams.Enc_alg == tpm2.AlgTPM_ALG_RSA {
		encAlg = "rsa"
	} else {
		return nil, err
	}
	if rsaQuoteParams.Hash_alg == tpm2.AlgTPM_ALG_SHA1 {
		hashAlg = "sha1"
	} else if rsaQuoteParams.Hash_alg == tpm2.AlgTPM_ALG_SHA256 {
		hashAlg = "sha256"
	} else {
		return nil, err
	}
	request.QuoteKeyInfo.PublicKey.KeyType = &encAlg
	request.QuoteKeyInfo.PublicKey.RsaKey.BitModulusSize = &modSize
	request.QuoteKeyInfo.PublicKey.RsaKey.Modulus = rsaQuoteParams.Modulus
	request.QuoteSignAlg = &encAlg
	request.QuoteSignHashAlg = &hashAlg

	request.ProgramKey = new(tpm2.ProgramKeyParameters)
	request.ProgramKey.ProgramName = &keyName
	request.ProgramKey.ProgramKeyType = &encAlg
	request.ProgramKey.ProgramBitModulusSize = &modSize
	request.ProgramKey.ProgramKeyModulus = rsaQuoteParams.Modulus

	request.QuotedBlob = attest
	request.QuoteSignature = sig
	return request, nil
}
Exemplo n.º 2
0
// Attest requests the Tao host seal a statement on behalf of the caller. The
// optional issuer, time and expiration will be given default values if nil.
func (tt *TPM2Tao) Attest(issuer *auth.Prin, start, expiration *int64,
	message auth.Form) (*Attestation, error) {
	fmt.Fprintf(os.Stderr, "About to load the quote key in attest\n")
	qh, err := tt.loadQuote()
	if err != nil {
		return nil, err
	}
	defer tpm2.FlushContext(tt.rw, qh)

	if issuer == nil {
		issuer = &tt.name
	} else if !auth.SubprinOrIdentical(*issuer, tt.name) {
		return nil, errors.New("invalid issuer in statement")
	}

	// TODO(tmroeder): we assume here that the PCRs haven't changed (e.g., been
	// extended) since this TPM2Tao was created. If they have, then the PCRs will
	// be wrong when we extend the principal here with them as the first
	// component. This doesn't matter at the moment, since we don't currently
	// support extending the PCRs or clearing them, but it will need to be
	// changed when we do.
	stmt := auth.Says{
		Speaker:    *issuer,
		Time:       start,
		Expiration: expiration,
		Message:    message,
	}

	// This is done in GenerateAttestation, but the TPM attestation is sealed
	// differently, so we do the time calculations here.
	t := time.Now()
	if stmt.Time == nil {
		i := t.UnixNano()
		stmt.Time = &i
	}

	if stmt.Expiration == nil {
		i := t.Add(365 * 24 * time.Hour).UnixNano()
		stmt.Expiration = &i
	}

	ser := auth.Marshal(stmt)

	var pcrVals [][]byte
	toQuote, err := tpm2.FormatTpm2Quote(ser, tt.pcrs, pcrVals)
	if err != nil {
		return nil, errors.New("Can't format tpm2 Quote")
	}

	// TODO(tmroeder): check the pcrVals for sanity once we support extending or
	// clearing the PCRs.
	quote_struct, sig, err := tpm2.Quote(tt.rw, qh, "", tt.password,
		toQuote, tt.pcrs, uint16(tpm2.AlgTPM_ALG_NULL))
	if err != nil {
		return nil, err
	}
	fmt.Printf("toQuote: %x\n", toQuote)
	fmt.Printf("Quote: %x\n", quote_struct)
	fmt.Printf("sig: %x\n", sig)

	quoteKey, err := x509.MarshalPKIXPublicKey(tt.verifier)
	if err != nil {
		return nil, err
	}

	// TODO(kwalsh) remove Tpm2QuoteStructure from Attestation structure
	a := &Attestation{
		SerializedStatement: ser,
		Signature:           sig,
		SignerType:          proto.String("tpm2"),
		SignerKey:           quoteKey,
		Tpm2QuoteStructure:  quote_struct,
	}

	return a, nil
}