entropychecker.GetEntropy   A
last analyzed

Complexity

Conditions 3

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.0416

Importance

Changes 0
Metric Value
cc 3
dl 0
loc 10
ccs 5
cts 6
cp 0.8333
crap 3.0416
rs 10
c 0
b 0
f 0
eloc 7
nop 0
1
package entropychecker
2
3
import (
4
	"errors"
5
	"io/ioutil"
6
	"runtime"
7
	"strconv"
8
	"strings"
9
	"time"
10
)
11
12
// MinimumEntropy is the minimum amount of entropy that will be considered safe.
13
// Set this to what you consider to be a 'safe' minimum entropy amount (in bits)
14
var MinimumEntropy = 128
15
16
// Timeout sets the maximum amount of time to wait for entropy.
17
// Waiting for entropy will time out after this amount of time. Setting to zero will never time out.
18
var Timeout = time.Second * 10
19
20
// The only supported OS is linux at this time.
21
var supportedOS = "linux"
22
23
// ErrTimeout is for when the system waits too long and gives up
24
var ErrTimeout = errors.New("entropychecker: Timed out waiting for sufficient entropy")
25
26
// ErrUnsupportedOS is for for an invalid OS that does not provide entropy estimates
27
var ErrUnsupportedOS = errors.New("entropychecker: Unsupported OS. Only Linux is supported")
28
29
// GetEntropy gets the entropy estimate. Returns the estimated entropy in bits
30
func GetEntropy() (int, error) {
31 1
	if runtime.GOOS != supportedOS {
32 1
		return 0, ErrUnsupportedOS
33
	}
34
35 1
	text, err := ioutil.ReadFile("/proc/sys/kernel/random/entropy_avail")
36 1
	if err != nil {
37
		return 0, err
38
	}
39 1
	return strconv.Atoi(strings.TrimSuffix(string(text), "\n"))
40
}
41
42
// WaitForEntropy blocks until sufficient entropy is available
43
func WaitForEntropy() error {
44 1
	if runtime.GOOS != supportedOS {
45 1
		return ErrUnsupportedOS
46
	}
47
48
	// set up the timeout
49 1
	timeout := make(chan bool, 1)
50 1
	if Timeout != 0 {
51 1
		go func(timeoutDuration time.Duration) {
52 1
			time.Sleep(timeoutDuration)
53 1
			timeout <- true
54
		}(Timeout)
55
	}
56
57 1
	for {
58 1
		entropy, err := GetEntropy()
59
60 1
		switch {
61
		case err != nil:
62
			return err
63
		case entropy > MinimumEntropy:
64 1
			return nil
65
		default:
66 1
			select {
67
			case <-timeout:
68 1
				return ErrTimeout
69
			default:
70 1
				time.Sleep(50 * time.Millisecond)
71
			}
72
		}
73
	}
74
}
75