1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
13 // UserId contains text that is intended to represent the name and email
14 // address of the key holder. See RFC 4880, section 5.11. By convention, this
15 // takes the form "Full Name (Comment) <email@example.com>"
17 Id string // By convention, this takes the form "Full Name (Comment) <email@example.com>" which is split out in the fields below.
19 Name, Comment, Email string
22 func hasInvalidCharacters(s string) bool {
25 case '(', ')', '<', '>', 0:
32 // NewUserId returns a UserId or nil if any of the arguments contain invalid
33 // characters. The invalid characters are '\x00', '(', ')', '<' and '>'
34 func NewUserId(name, comment, email string) *UserId {
35 // RFC 4880 doesn't deal with the structure of userid strings; the
36 // name, comment and email form is just a convention. However, there's
37 // no convention about escaping the metacharacters and GPG just refuses
38 // to create user ids where, say, the name contains a '('. We mirror
41 if hasInvalidCharacters(name) || hasInvalidCharacters(comment) || hasInvalidCharacters(email) {
46 uid.Name, uid.Comment, uid.Email = name, comment, email
67 func (uid *UserId) parse(r io.Reader) (err error) {
68 // RFC 4880, section 5.11
69 b, err := ioutil.ReadAll(r)
74 uid.Name, uid.Comment, uid.Email = parseUserId(uid.Id)
78 // Serialize marshals uid to w in the form of an OpenPGP packet, including
80 func (uid *UserId) Serialize(w io.Writer) error {
81 err := serializeHeader(w, packetTypeUserId, len(uid.Id))
85 _, err = w.Write([]byte(uid.Id))
89 // parseUserId extracts the name, comment and email from a user id string that
90 // is formatted as "Full Name (Comment) <email@example.com>".
91 func parseUserId(id string) (name, comment, email string) {
97 for offset, rune := range id {
109 } else if rune == '<' {
125 // Between comment and email
156 name = strings.TrimSpace(id[n.start:n.end])
157 comment = strings.TrimSpace(id[c.start:c.end])
158 email = strings.TrimSpace(id[e.start:e.end])