fix: move to crypto/rand for token gen (#794)

Signed-off-by: Spencer Smith <robertspencersmith@gmail.com>
This commit is contained in:
Spencer Smith 2019-06-27 18:08:39 -04:00 committed by GitHub
parent eccbb11081
commit 18f59d8f0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,12 +5,13 @@
package generate package generate
import ( import (
"bufio"
"bytes" "bytes"
"crypto/rand"
stdlibx509 "crypto/x509" stdlibx509 "crypto/x509"
"encoding/base64" "encoding/base64"
"encoding/pem" "encoding/pem"
"errors" "errors"
"math/rand"
"net" "net"
"strings" "strings"
"text/template" "text/template"
@ -64,28 +65,90 @@ type TrustdInfo struct {
Token string Token string
} }
// RandomString returns a string of length n. // randBytes returns a random string consisting of the characters in
func RandomString(n int) string { // validBootstrapTokenChars, with the length customized by the parameter
var letter = []rune("abcdefghijklmnopqrstuvwxy0123456789") func randBytes(length int) (string, error) {
b := make([]rune, n) // validBootstrapTokenChars defines the characters a bootstrap token can consist of
for i := range b { const validBootstrapTokenChars = "0123456789abcdefghijklmnopqrstuvwxyz"
b[i] = letter[rand.Intn(len(letter))]
// len("0123456789abcdefghijklmnopqrstuvwxyz") = 36 which doesn't evenly divide
// the possible values of a byte: 256 mod 36 = 4. Discard any random bytes we
// read that are >= 252 so the bytes we evenly divide the character set.
const maxByteValue = 252
var (
b byte
err error
token = make([]byte, length)
)
reader := bufio.NewReaderSize(rand.Reader, length*2)
for i := range token {
for {
if b, err = reader.ReadByte(); err != nil {
return "", err
}
if b < maxByteValue {
break
}
}
token[i] = validBootstrapTokenChars[int(b)%len(validBootstrapTokenChars)]
} }
return string(b)
return string(token), err
}
//genToken will generate a token of the format abc.123 (like kubeadm/trustd), where the length of the first string (before the dot)
//and length of the second string (after dot) are specified as inputs
func genToken(lenFirst int, lenSecond int) (string, error) {
var err error
var tokenTemp = make([]string, 2)
tokenTemp[0], err = randBytes(lenFirst)
if err != nil {
return "", err
}
tokenTemp[1], err = randBytes(lenSecond)
if err != nil {
return "", err
}
return tokenTemp[0] + "." + tokenTemp[1], nil
} }
// NewInput generates the sensitive data required to generate all userdata // NewInput generates the sensitive data required to generate all userdata
// types. // types.
// nolint: gocyclo // nolint: gocyclo
func NewInput(clustername string, masterIPs []string) (input *Input, err error) { func NewInput(clustername string, masterIPs []string) (input *Input, err error) {
//Gen trustd token strings
kubeadmBootstrapToken, err := genToken(6, 16)
if err != nil {
return nil, err
}
//TODO: Can be dropped
//Gen kubeadm cert key
kubeadmCertKey, err := randBytes(26)
if err != nil {
return nil, err
}
//Gen trustd token strings
trustdToken, err := genToken(6, 16)
if err != nil {
return nil, err
}
kubeadmTokens := &KubeadmTokens{ kubeadmTokens := &KubeadmTokens{
BootstrapToken: RandomString(6) + "." + RandomString(16), BootstrapToken: kubeadmBootstrapToken,
CertKey: RandomString(26), CertKey: kubeadmCertKey,
} }
trustdInfo := &TrustdInfo{ trustdInfo := &TrustdInfo{
Token: RandomString(6) + "." + RandomString(16), Token: trustdToken,
} }
// Generate Kubernetes CA. // Generate Kubernetes CA.