github.com/david-imola/snapd@v0.0.0-20210611180407-2de8ddeece6d/overlord/devicestate/crypto.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 /* 3 * Copyright (C) 2016-2017 Canonical Ltd 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 3 as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * 17 */ 18 19 package devicestate 20 21 import ( 22 "crypto/rsa" 23 "crypto/x509" 24 "encoding/pem" 25 "errors" 26 "io/ioutil" 27 "os" 28 "os/exec" 29 "path/filepath" 30 "strconv" 31 32 "github.com/snapcore/snapd/osutil" 33 ) 34 35 func generateRSAKey(keyLength int) (*rsa.PrivateKey, error) { 36 // The temporary directory is created with mode 37 // 0700 by ioutil.TempDir, see: 38 // https://github.com/golang/go/blob/master/src/io/ioutil/tempfile.go#L84 39 tempDir, err := ioutil.TempDir(os.TempDir(), "snapd") 40 if err != nil { 41 return nil, err 42 } 43 44 defer os.RemoveAll(tempDir) 45 46 rsaKeyFile := filepath.Join(tempDir, "rsa.key") 47 48 cmd := exec.Command("ssh-keygen", "-t", "rsa", "-b", strconv.Itoa(keyLength), "-N", "", "-f", rsaKeyFile, "-m", "PEM") 49 out, err := cmd.CombinedOutput() 50 if err != nil { 51 return nil, osutil.OutputErr(out, err) 52 } 53 54 d, err := ioutil.ReadFile(rsaKeyFile) 55 if err != nil { 56 return nil, err 57 } 58 59 blk, _ := pem.Decode(d) 60 if blk == nil { 61 return nil, errors.New("cannot decode PEM block") 62 } 63 64 key, err := x509.ParsePKCS1PrivateKey(blk.Bytes) 65 if err != nil { 66 return nil, err 67 } 68 69 err = key.Validate() 70 if err != nil { 71 return nil, err 72 } 73 74 err = os.RemoveAll(tempDir) 75 if err != nil { 76 return nil, err 77 } 78 79 return key, err 80 }