/usr/share/gocode/src/github.com/lxc/lxd/shared/cert.go is in golang-github-lxc-lxd-dev 2.0.2-0ubuntu1~16.04.1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | // http://golang.org/src/pkg/crypto/tls/generate_cert.go
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package shared
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"io/ioutil"
"log"
"math/big"
"net"
"os"
"os/user"
"path"
"time"
)
// CertInfo is the representation of a Certificate in the API.
type CertInfo struct {
Certificate string `json:"certificate"`
Fingerprint string `json:"fingerprint"`
Type string `json:"type"`
}
/*
* Generate a list of names for which the certificate will be valid.
* This will include the hostname and ip address
*/
func mynames() ([]string, error) {
h, err := os.Hostname()
if err != nil {
return nil, err
}
ret := []string{h}
ifs, err := net.Interfaces()
if err != nil {
return nil, err
}
for _, iface := range ifs {
if IsLoopback(&iface) {
continue
}
addrs, err := iface.Addrs()
if err != nil {
return nil, err
}
for _, addr := range addrs {
ret = append(ret, addr.String())
}
}
return ret, nil
}
func FindOrGenCert(certf string, keyf string) error {
if PathExists(certf) && PathExists(keyf) {
return nil
}
/* If neither stat succeeded, then this is our first run and we
* need to generate cert and privkey */
err := GenCert(certf, keyf)
if err != nil {
return err
}
return nil
}
// GenCert will create and populate a certificate file and a key file
func GenCert(certf string, keyf string) error {
/* Create the basenames if needed */
dir := path.Dir(certf)
err := os.MkdirAll(dir, 0750)
if err != nil {
return err
}
dir = path.Dir(keyf)
err = os.MkdirAll(dir, 0750)
if err != nil {
return err
}
certBytes, keyBytes, err := GenerateMemCert()
if err != nil {
return err
}
certOut, err := os.Create(certf)
if err != nil {
log.Fatalf("failed to open %s for writing: %s", certf, err)
return err
}
certOut.Write(certBytes)
certOut.Close()
keyOut, err := os.OpenFile(keyf, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
log.Printf("failed to open %s for writing: %s", keyf, err)
return err
}
keyOut.Write(keyBytes)
keyOut.Close()
return nil
}
// GenerateMemCert creates a certificate and key pair, returning them as byte
// arrays in memory.
func GenerateMemCert() ([]byte, []byte, error) {
privk, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
log.Fatalf("failed to generate key")
return nil, nil, err
}
hosts, err := mynames()
if err != nil {
log.Fatalf("Failed to get my hostname")
return nil, nil, err
}
validFrom := time.Now()
validTo := validFrom.Add(10 * 365 * 24 * time.Hour)
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Fatalf("failed to generate serial number: %s", err)
return nil, nil, err
}
userEntry, err := user.Current()
var username string
if err == nil {
username = userEntry.Username
if username == "" {
username = "UNKNOWN"
}
} else {
username = "UNKNOWN"
}
hostname, err := os.Hostname()
if err != nil {
hostname = "UNKNOWN"
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"linuxcontainers.org"},
CommonName: fmt.Sprintf("%s@%s", username, hostname),
},
NotBefore: validFrom,
NotAfter: validTo,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
for _, h := range hosts {
if ip := net.ParseIP(h); ip != nil {
template.IPAddresses = append(template.IPAddresses, ip)
} else {
template.DNSNames = append(template.DNSNames, h)
}
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privk.PublicKey, privk)
if err != nil {
log.Fatalf("Failed to create certificate: %s", err)
return nil, nil, err
}
cert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
key := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privk)})
return cert, key, nil
}
func ReadCert(fpath string) (*x509.Certificate, error) {
cf, err := ioutil.ReadFile(fpath)
if err != nil {
return nil, err
}
certBlock, _ := pem.Decode(cf)
if certBlock == nil {
return nil, fmt.Errorf("Invalid certificate file")
}
return x509.ParseCertificate(certBlock.Bytes)
}
|