aboutsummaryrefslogtreecommitdiff
path: root/cvss/score.go
blob: 94a15a574309d2a254b4f466dd57399b66965ab9 (plain)
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
package cvss

import (
  "fmt"
)

// Individual CVSS score.
//
// Note: since scores range from 0.0 to 10.0 with one decimal place of
// precision, they can be safely represented as a uint8.
type Score uint8

// Return floating point representation of score.
func NewScore(val float64) (Score, error) {
  // check score range
  if val < 0.0 || val > 10.0 {
    return Score(0), fmt.Errorf("score value out of range [0, 10]: %f", val)
  }

  // convert to score, return success
  return Score(uint8(10.0 * val)), nil
}

// Return string representation of score.
func (s Score) String() string {
  return fmt.Sprintf("%d.%d", s / 10, s % 10)
}

// Return floating point representation of score.
func (s Score) Float() float32 {
  return float32(s) / 10.0
}

// Score to severity mapping.
var scoreSeverities = []struct {
  min       uint8     // min score (inclusive)
  max       uint8     // max score (inclusive)
  severity  Severity  // severity
} {
  {  0,   0, None },
  {  1,  39, Low },
  { 40,  69, Medium },
  { 70,  89, High },
  { 90, 100, Critical },
}

// Return score severity.
//
// Returns Unknown if the score does not map to a known severity.
//
// Score severity is based on mapping from section 5 of CVSS 3.1
// specification.
func (s Score) Severity() Severity {
  for _, row := range(scoreSeverities) {
    if uint8(s) >= row.min && uint8(s) <= row.max {
      return row.severity
    }
  }

  // return unknown severity
  return Unknown
}