// Derive returns a manifest for a principal based on previously published info // and/or the principal name itself. func DeriveManifest(p *auth.Prin) Manifest { m := Manifest{} parent := p.Parent() if parent == nil { if p.Type == "tpm" { pcr := Manifest{} nums, vals, err := ExtractPCRs(*p) if err != nil { pcr["Status"] = "Unknown" } else { for i := 0; i < len(nums) && i < len(vals); i++ { pcr[fmt.Sprintf("PCR %d", nums[i])] = vals[i] } } aik := Manifest{} k, err := ExtractAIK(*p) if err != nil { aik["Status"] = "Unknown" } else { aik["Type"] = "RSA" aik["Size"] = k.N.BitLen() aik["Exponent"] = k.E aik["Modulus"] = k.N.Bytes() } m["Type"] = "Trusted Platform Module" m["TPM"] = Manifest{ "Platform Configuration Registers": pcr, "Public Attestation Identity Key": aik, } } else if p.Type == "key" { key := Manifest{} v, err := FromPrincipal(*p) if err != nil { key["Status"] = "Unknown" } else { switch v := v.PublicKey().(type) { case *ecdsa.PublicKey: key["Algorithm"] = "ECDSA" key["Curve"] = ecdsaCurveName[v.Curve] key["X"] = v.X.Bytes() key["Y"] = v.Y.Bytes() } } m["Type"] = "Public Key Principal" m["Key"] = key } else { m["Type"] = "Unrecognized" } return m } else { m["Subprincipal Extension"] = p.Ext.String() } for _, f := range filenames(p) { b, err := ioutil.ReadFile(f) // TODO(kwalsh) reap expired and malformed files if err != nil { continue } var a Attestation if err = proto.Unmarshal(b, &a); err != nil { glog.Errorf("Ignoring malformed manifest %s\n", f) continue } says, err := a.Validate() if err != nil { glog.Errorf("Ignoring invalid manifest %s\n", f) continue } if !says.Speaker.Identical(parent) { glog.Errorf("Ignoring misplaced manifest %s\n", f) continue } if !says.Active(time.Now().UnixNano()) { glog.Errorf("Ignoring expired manifest %s\n", f) continue } m.Extend(p, says.Message) } m["Parent"] = DeriveManifest(parent) return m }