gitee.com/mysnapcore/mysnapd@v0.1.0/asserts/signtool/keymgr.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2021 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package signtool 21 22 import ( 23 "errors" 24 "fmt" 25 "os" 26 27 "golang.org/x/crypto/ssh/terminal" 28 29 "gitee.com/mysnapcore/mysnapd/asserts" 30 "gitee.com/mysnapcore/mysnapd/i18n" 31 ) 32 33 // KeypairManager is an interface for common methods of ExternalKeypairManager 34 // and GPGPKeypairManager. 35 type KeypairManager interface { 36 asserts.KeypairManager 37 38 GetByName(keyNname string) (asserts.PrivateKey, error) 39 Export(keyName string) ([]byte, error) 40 List() ([]asserts.ExternalKeyInfo, error) 41 DeleteByName(keyName string) error 42 } 43 44 // GetKeypairManager returns a KeypairManager - either the standrd gpg-based 45 // or external one if set via SNAPD_EXT_KEYMGR environment variable. 46 func GetKeypairManager() (KeypairManager, error) { 47 keymgrPath := os.Getenv("SNAPD_EXT_KEYMGR") 48 if keymgrPath != "" { 49 keypairMgr, err := asserts.NewExternalKeypairManager(keymgrPath) 50 if err != nil { 51 return nil, fmt.Errorf(i18n.G("cannot setup external keypair manager: %v"), err) 52 } 53 return keypairMgr, nil 54 } 55 keypairMgr := asserts.NewGPGKeypairManager() 56 return keypairMgr, nil 57 } 58 59 type takingPassKeyGen interface { 60 Generate(passphrase string, keyName string) error 61 } 62 63 type ownSecuringKeyGen interface { 64 Generate(keyName string) error 65 } 66 67 // GenerateKey generates a private RSA key using the provided keypairMgr. 68 func GenerateKey(keypairMgr KeypairManager, keyName string) error { 69 switch keyGen := keypairMgr.(type) { 70 case takingPassKeyGen: 71 return takePassGenKey(keyGen, keyName) 72 case ownSecuringKeyGen: 73 err := keyGen.Generate(keyName) 74 if _, ok := err.(*asserts.ExternalUnsupportedOpError); ok { 75 return fmt.Errorf(i18n.G("cannot generate external keypair manager key via snap command, use the appropriate external procedure to create a 4096-bit RSA key under the name/label %q"), keyName) 76 } 77 return err 78 default: 79 return fmt.Errorf("internal error: unsupported keypair manager %T", keypairMgr) 80 } 81 } 82 83 func takePassGenKey(keyGen takingPassKeyGen, keyName string) error { 84 fmt.Fprint(Stdout, i18n.G("Passphrase: ")) 85 passphrase, err := terminal.ReadPassword(0) 86 fmt.Fprint(Stdout, "\n") 87 if err != nil { 88 return err 89 } 90 fmt.Fprint(Stdout, i18n.G("Confirm passphrase: ")) 91 confirmPassphrase, err := terminal.ReadPassword(0) 92 fmt.Fprint(Stdout, "\n") 93 if err != nil { 94 return err 95 } 96 if string(passphrase) != string(confirmPassphrase) { 97 return errors.New(i18n.G("passphrases do not match")) 98 } 99 100 return keyGen.Generate(string(passphrase), keyName) 101 }