parse.go (1931B)
1 // Copyright 2019 Google LLC 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file or at 5 // https://developers.google.com/open-source/licenses/bsd 6 7 package main 8 9 import ( 10 "bufio" 11 "fmt" 12 "io" 13 "io/ioutil" 14 "os" 15 "strings" 16 17 "github.com/FiloSottile/age/internal/age" 18 ) 19 20 func parseRecipient(arg string) (age.Recipient, error) { 21 switch { 22 case strings.HasPrefix(arg, "pubkey:"): 23 return age.ParseX25519Recipient(arg) 24 case strings.HasPrefix(arg, "ssh-"): 25 return age.ParseSSHRecipient(arg) 26 } 27 28 return nil, fmt.Errorf("unknown recipient type: %q", arg) 29 } 30 31 func parseIdentitiesFile(name string) ([]age.Identity, error) { 32 f, err := os.Open(name) 33 if err != nil { 34 return nil, fmt.Errorf("failed to open file: %v", err) 35 } 36 37 var ids []age.Identity 38 scanner := bufio.NewScanner(f) 39 for scanner.Scan() { 40 line := scanner.Text() 41 if strings.HasPrefix(line, "#") || line == "" { 42 continue 43 } 44 i, err := age.ParseX25519Identity(line) 45 if err != nil { 46 return nil, fmt.Errorf("malformed secret keys file %q: %v", name, err) 47 } 48 ids = append(ids, i) 49 } 50 if err := scanner.Err(); err != nil { 51 return nil, fmt.Errorf("failed to read %q: %v", name, err) 52 } 53 54 if len(ids) == 0 { 55 return nil, fmt.Errorf("no secret keys found in %q", name) 56 } 57 return ids, nil 58 } 59 60 func parseSSHIdentity(name string) ([]age.Identity, error) { 61 f, err := os.Open(name) 62 if err != nil { 63 return nil, fmt.Errorf("failed to open file: %v", err) 64 } 65 defer f.Close() 66 67 // Don't allow unbounded reads. 68 // TODO: support for multiple keys in the same stream, such as user.keys 69 // on GitHub. 70 pemBytes, err := ioutil.ReadAll(io.LimitReader(f, 1<<20)) 71 if err != nil { 72 return nil, fmt.Errorf("failed to read %q: %v", name, err) 73 } 74 75 id, err := age.ParseSSHIdentity(pemBytes) 76 if err != nil { 77 return nil, fmt.Errorf("malformed SSH identity in %q: %v", name, err) 78 } 79 80 return []age.Identity{id}, nil 81 }