1package gpg 2 3import ( 4 "fmt" 5 "sort" 6 "time" 7) 8 9// Key is a GPG key (public or secret) 10type Key struct { 11 KeyType string 12 KeyLength int 13 Validity string 14 CreationDate time.Time 15 ExpirationDate time.Time 16 Ownertrust string 17 Fingerprint string 18 Identities map[string]Identity 19 SubKeys map[string]struct{} 20} 21 22// IsUseable returns true if GPG would assume this key is useable for encryption 23func (k Key) IsUseable(alwaysTrust bool) bool { 24 if !k.ExpirationDate.IsZero() && k.ExpirationDate.Before(time.Now()) { 25 return false 26 } 27 if alwaysTrust { 28 return true 29 } 30 switch k.Validity { 31 case "m": 32 return true 33 case "f": 34 return true 35 case "u": 36 return true 37 } 38 return false 39} 40 41// String implement fmt.Stringer. This method produces output that is close to, but 42// not exactly the same, as the output form GPG itself 43func (k Key) String() string { 44 fp := "" 45 if len(k.Fingerprint) > 24 { 46 fp = k.Fingerprint[24:] 47 } 48 out := fmt.Sprintf("%s %dD/0x%s %s", k.KeyType, k.KeyLength, fp, k.CreationDate.Format("2006-01-02")) 49 if !k.ExpirationDate.IsZero() { 50 out += fmt.Sprintf(" [expires: %s]", k.ExpirationDate.Format("2006-01-02")) 51 } 52 out += "\n Key fingerprint = " + k.Fingerprint 53 for _, id := range k.Identities { 54 out += fmt.Sprintf("\n" + id.String()) 55 } 56 return out 57} 58 59// OneLine prints a terse representation of this key on one line (includes only 60// the first identity!) 61func (k Key) OneLine() string { 62 if len(k.Fingerprint) < 24 { 63 return fmt.Sprintf("(invalid:%s)", k.Fingerprint) 64 } 65 return fmt.Sprintf("0x%s - %s", k.Fingerprint[24:], k.Identity().ID()) 66} 67 68// Identity returns the first identity 69func (k Key) Identity() Identity { 70 ids := make([]Identity, 0, len(k.Identities)) 71 for _, i := range k.Identities { 72 ids = append(ids, i) 73 } 74 sort.Slice(ids, func(i, j int) bool { 75 return ids[i].CreationDate.After(ids[j].CreationDate) 76 }) 77 for _, i := range ids { 78 return i 79 } 80 return Identity{} 81} 82 83// ID returns the short fingerprint 84func (k Key) ID() string { 85 if len(k.Fingerprint) < 25 { 86 return "" 87 } 88 return fmt.Sprintf("0x%s", k.Fingerprint[24:]) 89} 90