Greenbone Vulnerability Management Libraries 22.32.0
cvss.c File Reference

CVSS utility functions. More...

#include "cvss.h"
#include <glib.h>
#include <math.h>
#include <strings.h>
Include dependency graph for cvss.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  impact_item
 Describe a CVSS impact element. More...
struct  cvss
 Describe a CVSS metrics. More...
struct  cvss4_metric_def_t
 String to enum mapping and allowed values for a CVSS 4.0 metric. More...
struct  cvss4_macrovector_mapping_t
 Key-Value mappings of CVSS 4.0 macrovectors to scores. More...

Macros

#define G_LOG_DOMAIN   "libgvm base"
 GLib log domain.
#define AV_NETWORK   1.0
 AccessVector (AV) Constants.
#define AV_ADJACENT_NETWORK   0.646
#define AV_LOCAL   0.395
#define AC_LOW   0.71
 AccessComplexity (AC) Constants.
#define AC_MEDIUM   0.61
#define AC_HIGH   0.35
#define Au_MULTIPLE_INSTANCES   0.45
 Authentication (Au) Constants.
#define Au_SINGLE_INSTANCE   0.56
#define Au_NONE   0.704
#define C_NONE   0.0
 ConfidentialityImpact (C) Constants.
#define C_PARTIAL   0.275
#define C_COMPLETE   0.660
#define I_NONE   0.0
 IntegrityImpact (I) Constants.
#define I_PARTIAL   0.275
#define I_COMPLETE   0.660
#define A_NONE   0.0
 AvailabilityImpact (A) Constants.
#define A_PARTIAL   0.275
#define A_COMPLETE   0.660
#define CVSS_METRICS_STR_BLANK   "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
 Blank simplified CVSS 4.0 metrics string.
#define CVSS_MACROVECTOR_BLANK   "XXXXXX"
 Blank simplified CVSS 4.0 macrovector string.

Enumerations

enum  base_metrics {
  A , I , C , Au ,
  AC , AV
}
 CVSS v2 Base metrics. More...
enum  cvss4_metric_t {
  CVSS4_AV , CVSS4_AC , CVSS4_AT , CVSS4_PR ,
  CVSS4_UI , CVSS4_VC , CVSS4_VI , CVSS4_VA ,
  CVSS4_SC , CVSS4_SI , CVSS4_SA , CVSS4_E ,
  CVSS4_CR , CVSS4_IR , CVSS4_AR , CVSS4_MAV ,
  CVSS4_MAC , CVSS4_MAT , CVSS4_MPR , CVSS4_MUI ,
  CVSS4_MVC , CVSS4_MVI , CVSS4_MVA , CVSS4_MSC ,
  CVSS4_MSI , CVSS4_MSA , CVSS4_S , CVSS4_AU ,
  CVSS4_R , CVSS4_V , CVSS4_RE , CVSS4_U ,
  CVSS4_METRICS_MAX
}
 CVSS 4.0 metrics. More...

Functions

static double get_cvss_score_from_base_metrics_v3 (const char *cvss_str)
 Calculate CVSS Score.
static double get_cvss_score_from_metrics_v4 (const char *cvss_str)
 Calculate CVSS 4.0 Score.
static int toenum (const char *str, enum base_metrics *res)
 Determine base metric enumeration from a string.
static double get_impact_subscore (const struct cvss *cvss)
 Calculate Impact Sub Score.
static double get_exploitability_subscore (const struct cvss *cvss)
 Calculate Exploitability Sub Score.
static int set_impact_from_str (const char *value, enum base_metrics metric, struct cvss *cvss)
 Set impact score from string representation.
static double __get_cvss_score (struct cvss *cvss)
 Final CVSS score computation helper.
double get_cvss_score_from_base_metrics (const char *cvss_str)
 Calculate CVSS Score.
static double roundup (double cvss)
 Round final score as in spec.
static double v3_impact (const char *value)
 Get impact.
static void cvss4_init_macrovector_table ()
 Initialize the CVSS 4.0 macrovector lookup table.
static double cvss4_macrovector_score (const char *vector)
 Get the CVSS 4.0 score for a given macrovector string.
static char cvss4_m (const char *simplified_vec, cvss4_metric_t metric)
 Get the effective value of a metric in a simplified CVSS4 vector.
static gchar * simplify_cvss4_vector (const char *cvss_str)
 Simplify CVSS 4.0 base vector so metrics can be indexed by enum.
static gchar * cvss4_vector_expand (const char *vec)
 Expands a simplified CVSS 4.0 vector into its full string form.
static gchar * cvss4_macrovector (const char *vec)
 Calculate CVSS 4.0 macrovector from a simplified vector.
static void cvss4_maximal_scoring_differences (const char *macrovector, double *available_distance_eq1, double *available_distance_eq2, double *available_distance_eq3eq6, double *available_distance_eq4, double *available_distance_eq5)
 Calulate the maximal scoring differences from a CVSS 4.0 macrovector.
static gchar ** cvss4_max_vectors (const char *macrovector)
 Composes a list of max vectors for the given CVSS 4.0 macrovector.
static double cvss4_metric_level (cvss4_metric_t metric, char value)
 Get the index of a CVSS 4.0 metric value for severity distances.
static double cvss4_severity_distance (cvss4_metric_t metric, const char *vec, const char *max_vec)
 Calculate severity distance for a metric in two CVSS 4.0 vectors.
static void cvss4_current_severity_distances (const char *vec, const char *macrovector, double *current_severity_distance_eq1, double *current_severity_distance_eq2, double *current_severity_distance_eq3eq6, double *current_severity_distance_eq4, double *current_severity_distance_eq5)
 Calculate current severity distances for given CVSS 4.0 vector.
static void cvss4_max_severities (const char *macrovector, double *max_severity_eq1, double *max_severity_eq2, double *max_severity_eq3eq6, double *max_severity_eq4)
 Get the max severity values for a CVSS 4.0 macrovector.

Variables

static const struct impact_item impact_map [][3]
static cvss4_metric_def_t cvss4_metric_defs []
 String to enum mappings and allowed values for CVSS 4.0 metrics.
static const cvss4_macrovector_mapping_t cvss4_macrovector_mappings []
 CVSS 4.0 macrovector mappings.
static GHashTable * cvss4_macrovector_table = NULL
 Hashtable for quick lookup of CVSS macrovector scores.

Detailed Description

CVSS utility functions.

This file contains utility functions for handling CVSS v2, v3 and v4. get_cvss_score_from_base_metrics calculates the CVSS base score from a CVSS base vector.

CVSS v4.0:

See the CVSS v4 calculator reference implementation at https://github.com/FIRSTdotorg/cvss-v4-calculator and the CVSS 4.0 specification document at https://www.first.org/cvss/v4.0/specification-document (especially sections 7., 8.2 and 8.3).

CVSS v3.1:

See equations at https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator and constants at https://www.first.org/cvss/v3.1/specification-document (section 7.4. Metric Values).

CVSS v3.0:

See equations at https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator and constants at https://www.first.org/cvss/v3.0/specification-document (section 8.4. Metric Levels).

CVSS v2:

The base equation is the foundation of CVSS scoring. The base equation is: BaseScore6 = round_to_1_decimal(((0.6*Impact)+(0.4*Exploitability)–1.5)*f(Impact))

Impact = 10.41*(1-(1-ConfImpact)*(1-IntegImpact)*(1-AvailImpact))

Exploitability = 20* AccessVector*AccessComplexity*Authentication

f(impact)= 0 if Impact=0, 1.176 otherwise AccessVector = case AccessVector of requires local access: 0.395 adjacent network accessible: 0.646 network accessible: 1.0 AccessComplexity = case AccessComplexity of high: 0.35 medium: 0.61 low: 0.71 Authentication = case Authentication of requires multiple instances of authentication: 0.45 requires single instance of authentication: 0.56 requires no authentication: 0.704 ConfImpact = case ConfidentialityImpact of none: 0.0 partial: 0.275 complete: 0.660 IntegImpact = case IntegrityImpact of none: 0.0 partial: 0.275 complete: 0.660 AvailImpact = case AvailabilityImpact of none: 0.0 partial: 0.275 complete: 0.660

Definition in file cvss.c.

Macro Definition Documentation

◆ A_COMPLETE

#define A_COMPLETE   0.660

Complete Availability Impact.

Definition at line 136 of file cvss.c.

◆ A_NONE

#define A_NONE   0.0

AvailabilityImpact (A) Constants.

No Availability Impact.

Definition at line 134 of file cvss.c.

◆ A_PARTIAL

#define A_PARTIAL   0.275

Partial Availability Impact.

Definition at line 135 of file cvss.c.

◆ AC_HIGH

#define AC_HIGH   0.35

Access Complexity High.

Definition at line 108 of file cvss.c.

◆ AC_LOW

#define AC_LOW   0.71

AccessComplexity (AC) Constants.

Access Complexity Low.

Definition at line 106 of file cvss.c.

◆ AC_MEDIUM

#define AC_MEDIUM   0.61

Access Complexity Medium.

Definition at line 107 of file cvss.c.

◆ Au_MULTIPLE_INSTANCES

#define Au_MULTIPLE_INSTANCES   0.45

Authentication (Au) Constants.

Authentication multiple instances.

Definition at line 113 of file cvss.c.

◆ Au_NONE

#define Au_NONE   0.704

No Authentication.

Definition at line 115 of file cvss.c.

◆ Au_SINGLE_INSTANCE

#define Au_SINGLE_INSTANCE   0.56

Authentication single instances.

Definition at line 114 of file cvss.c.

◆ AV_ADJACENT_NETWORK

#define AV_ADJACENT_NETWORK   0.646

Access Vector Adjacent Network.

Definition at line 100 of file cvss.c.

◆ AV_LOCAL

#define AV_LOCAL   0.395

Access Vector Local.

Definition at line 101 of file cvss.c.

◆ AV_NETWORK

#define AV_NETWORK   1.0

AccessVector (AV) Constants.

Access Vector Network.

Definition at line 99 of file cvss.c.

◆ C_COMPLETE

#define C_COMPLETE   0.660

Complete Confidentiality Impact.

Definition at line 122 of file cvss.c.

◆ C_NONE

#define C_NONE   0.0

ConfidentialityImpact (C) Constants.

No Confidentiality Impact.

Definition at line 120 of file cvss.c.

◆ C_PARTIAL

#define C_PARTIAL   0.275

Partial Confidentiality Impact.

Definition at line 121 of file cvss.c.

◆ CVSS_MACROVECTOR_BLANK

#define CVSS_MACROVECTOR_BLANK   "XXXXXX"

Blank simplified CVSS 4.0 macrovector string.

Definition at line 268 of file cvss.c.

Referenced by cvss4_macrovector().

◆ CVSS_METRICS_STR_BLANK

#define CVSS_METRICS_STR_BLANK   "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

Blank simplified CVSS 4.0 metrics string.

Definition at line 263 of file cvss.c.

Referenced by simplify_cvss4_vector().

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "libgvm base"

GLib log domain.

Definition at line 83 of file cvss.c.

◆ I_COMPLETE

#define I_COMPLETE   0.660

Complete Integrity Impact.

Definition at line 129 of file cvss.c.

◆ I_NONE

#define I_NONE   0.0

IntegrityImpact (I) Constants.

No Integrity Impact.

Definition at line 127 of file cvss.c.

◆ I_PARTIAL

#define I_PARTIAL   0.275

Partial Integrity Impact.

Definition at line 128 of file cvss.c.

Enumeration Type Documentation

◆ base_metrics

CVSS v2 Base metrics.

Enumerator

Availability Impact.

Integrity Impact.

Confidentiality Impact.

Au 

Authentication.

AC 

Access Complexity.

AV 

Access Vector.

Definition at line 142 of file cvss.c.

143{
144 A,
145 I,
146 C,
147 Au,
148 AC,
149 AV
150};
@ AC
Definition cvss.c:148
@ A
Definition cvss.c:144
@ C
Definition cvss.c:146
@ Au
Definition cvss.c:147
@ I
Definition cvss.c:145
@ AV
Definition cvss.c:149

◆ cvss4_metric_t

CVSS 4.0 metrics.

Enumerator
CVSS4_AV 

Attack Vector

CVSS4_AC 

Attack Complexity

CVSS4_AT 

Attack Requirements

CVSS4_PR 

Privileges Required

CVSS4_UI 

User Interaction

CVSS4_VC 

Confidentiality Impact to the Vulnerable System

CVSS4_VI 

Integrity Impact to the Vulnerable System

CVSS4_VA 

Availability Impact to the Vulnerable System

CVSS4_SC 

Confidentiality Impact to the Subsequent System

CVSS4_SI 

Integrity Impact to the Subsequent System

CVSS4_SA 

Availability Impact to the Subsequent System

CVSS4_E 

Exploit Maturity

CVSS4_CR 

Confidentiality Requirement

CVSS4_IR 

Integrity Requirement

CVSS4_AR 

Availability Requirement

CVSS4_MAV 

Modified Attack Vector

CVSS4_MAC 

Modified Attack Complexity

CVSS4_MAT 

Modified Attack Requirements

CVSS4_MPR 

Modified Privileges Required

CVSS4_MUI 

Modified User Interaction

CVSS4_MVC 

Modified Confidentiality Impact to the Vulnerable System

CVSS4_MVI 

Modified Integrity Impact to the Vulnerable System

CVSS4_MVA 

Modified Availability Impact to the Vulnerable System

CVSS4_MSC 

Modified Confidentiality Impact to the Subsequent System

CVSS4_MSI 

Modified Integrity Impact to the Subsequent System

CVSS4_MSA 

Modified Availability Impact to the Subsequent System

CVSS4_S 

Safety

CVSS4_AU 

Automatable

CVSS4_R 

Recovery

CVSS4_V 

Value Density

CVSS4_RE 

Vulnerability Response Effort

CVSS4_U 

Provider Urgency

CVSS4_METRICS_MAX 

Maximum number of metrics

Definition at line 218 of file cvss.c.

219{
220 // Base (11 metrics)
221 CVSS4_AV,
222 CVSS4_AC,
223 CVSS4_AT,
224 CVSS4_PR,
225 CVSS4_UI,
226 CVSS4_VC,
227 CVSS4_VI,
228 CVSS4_VA,
229 CVSS4_SC,
230 CVSS4_SI,
231 CVSS4_SA,
232 // Threat (1 metric)
233 CVSS4_E,
234 // Environmental (14 metrics)
235 CVSS4_CR,
236 CVSS4_IR,
237 CVSS4_AR,
238 CVSS4_MAV,
239 CVSS4_MAC,
240 CVSS4_MAT,
241 CVSS4_MPR,
242 CVSS4_MUI,
243 CVSS4_MVC,
244 CVSS4_MVI,
245 CVSS4_MVA,
246 CVSS4_MSC,
247 CVSS4_MSI,
248 CVSS4_MSA,
249 // Supplemental (6 metrics)
250 CVSS4_S,
251 CVSS4_AU,
252 CVSS4_R,
253 CVSS4_V,
254 CVSS4_RE,
255 CVSS4_U,
256 // Maximum number
cvss4_metric_t
CVSS 4.0 metrics.
Definition cvss.c:219
@ CVSS4_PR
Definition cvss.c:224
@ CVSS4_VA
Definition cvss.c:228
@ CVSS4_V
Definition cvss.c:253
@ CVSS4_AV
Definition cvss.c:221
@ CVSS4_MSA
Definition cvss.c:248
@ CVSS4_MAC
Definition cvss.c:239
@ CVSS4_MSC
Definition cvss.c:246
@ CVSS4_E
Definition cvss.c:233
@ CVSS4_RE
Definition cvss.c:254
@ CVSS4_U
Definition cvss.c:255
@ CVSS4_MAV
Definition cvss.c:238
@ CVSS4_AR
Definition cvss.c:237
@ CVSS4_R
Definition cvss.c:252
@ CVSS4_SA
Definition cvss.c:231
@ CVSS4_S
Definition cvss.c:250
@ CVSS4_VI
Definition cvss.c:227
@ CVSS4_MPR
Definition cvss.c:241
@ CVSS4_UI
Definition cvss.c:225
@ CVSS4_VC
Definition cvss.c:226
@ CVSS4_SC
Definition cvss.c:229
@ CVSS4_AU
Definition cvss.c:251
@ CVSS4_MSI
Definition cvss.c:247
@ CVSS4_MVC
Definition cvss.c:243
@ CVSS4_MUI
Definition cvss.c:242
@ CVSS4_MAT
Definition cvss.c:240
@ CVSS4_AT
Definition cvss.c:223
@ CVSS4_AC
Definition cvss.c:222
@ CVSS4_CR
Definition cvss.c:235
@ CVSS4_MVI
Definition cvss.c:244
@ CVSS4_METRICS_MAX
Definition cvss.c:257
@ CVSS4_MVA
Definition cvss.c:245
@ CVSS4_SI
Definition cvss.c:230
@ CVSS4_IR
Definition cvss.c:236

Function Documentation

◆ __get_cvss_score()

double __get_cvss_score ( struct cvss * cvss)
static

Final CVSS score computation helper.

Parameters
[in]cvssThe CVSS structure that contains the different metrics and associated scores.
Returns
the CVSS score, as a double.

Definition at line 561 of file cvss.c.

562{
563 double impact = 1.176;
564 double impact_sub;
565 double exploitability_sub;
566
567 impact_sub = get_impact_subscore (cvss);
568 exploitability_sub = get_exploitability_subscore (cvss);
569
570 if (impact_sub < 0.1)
571 impact = 0.0;
572
573 return (((0.6 * impact_sub) + (0.4 * exploitability_sub) - 1.5) * impact)
574 + 0.0;
575}
static double get_exploitability_subscore(const struct cvss *cvss)
Calculate Exploitability Sub Score.
Definition cvss.c:488
static double get_impact_subscore(const struct cvss *cvss)
Calculate Impact Sub Score.
Definition cvss.c:471
Describe a CVSS metrics.
Definition cvss.c:165

References get_exploitability_subscore(), and get_impact_subscore().

Referenced by get_cvss_score_from_base_metrics().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cvss4_current_severity_distances()

void cvss4_current_severity_distances ( const char * vec,
const char * macrovector,
double * current_severity_distance_eq1,
double * current_severity_distance_eq2,
double * current_severity_distance_eq3eq6,
double * current_severity_distance_eq4,
double * current_severity_distance_eq5 )
static

Calculate current severity distances for given CVSS 4.0 vector.

Parameters
[in]vecThe vector in simplified form
[in]macrovectorCorresponding macrovector
[out]current_severity_distance_eq1Distance for EQ1
[out]current_severity_distance_eq2Distance for EQ2
[out]current_severity_distance_eq3eq6Distance for EQ3 and EQ6
[out]current_severity_distance_eq4Distance for EQ4
[out]current_severity_distance_eq5Distance for EQ5

Definition at line 1604 of file cvss.c.

1610{
1611 double severity_distance_AV, severity_distance_PR, severity_distance_UI;
1612 double severity_distance_AC, severity_distance_AT;
1613 double severity_distance_VC, severity_distance_VI, severity_distance_VA;
1614 double severity_distance_SC, severity_distance_SI, severity_distance_SA;
1615 double severity_distance_CR, severity_distance_IR, severity_distance_AR;
1616
1617 severity_distance_AV = severity_distance_PR = severity_distance_UI = -99.0;
1618 severity_distance_AC = severity_distance_AT = -99.0;
1619 severity_distance_VC = severity_distance_VI = severity_distance_VA = -99.0;
1620 severity_distance_SC = severity_distance_SI = severity_distance_SA = -99.0;
1621 severity_distance_CR = severity_distance_IR = severity_distance_AR = -99.0;
1622
1623 char **max_vectors, **max_vec;
1624 max_vectors = cvss4_max_vectors (macrovector);
1625 for (max_vec = max_vectors; *max_vec != NULL; max_vec++)
1626 {
1627 severity_distance_AV = cvss4_severity_distance (CVSS4_AV, vec, *max_vec);
1628 severity_distance_PR = cvss4_severity_distance (CVSS4_PR, vec, *max_vec);
1629 severity_distance_UI = cvss4_severity_distance (CVSS4_UI, vec, *max_vec);
1630
1631 severity_distance_AC = cvss4_severity_distance (CVSS4_AC, vec, *max_vec);
1632 severity_distance_AT = cvss4_severity_distance (CVSS4_AT, vec, *max_vec);
1633
1634 severity_distance_VC = cvss4_severity_distance (CVSS4_VC, vec, *max_vec);
1635 severity_distance_VI = cvss4_severity_distance (CVSS4_VI, vec, *max_vec);
1636 severity_distance_VA = cvss4_severity_distance (CVSS4_VA, vec, *max_vec);
1637
1638 severity_distance_SC = cvss4_severity_distance (CVSS4_SC, vec, *max_vec);
1639 severity_distance_SI = cvss4_severity_distance (CVSS4_SI, vec, *max_vec);
1640 severity_distance_SA = cvss4_severity_distance (CVSS4_SA, vec, *max_vec);
1641
1642 severity_distance_CR = cvss4_severity_distance (CVSS4_CR, vec, *max_vec);
1643 severity_distance_IR = cvss4_severity_distance (CVSS4_IR, vec, *max_vec);
1644 severity_distance_AR = cvss4_severity_distance (CVSS4_AR, vec, *max_vec);
1645
1646 if (severity_distance_AV < 0.0 || severity_distance_PR < 0.0
1647 || severity_distance_UI < 0.0 || severity_distance_AC < 0.0
1648 || severity_distance_AT < 0.0 || severity_distance_VC < 0.0
1649 || severity_distance_VI < 0.0 || severity_distance_VA < 0.0
1650 || severity_distance_SC < 0.0 || severity_distance_SI < 0.0
1651 || severity_distance_SA < 0.0 || severity_distance_CR < 0.0
1652 || severity_distance_IR < 0.0 || severity_distance_AR < 0.0)
1653 continue;
1654
1655 g_debug ("%s AV:%0.1f PR:%0.1f UI:%0.1f |"
1656 " AC:%0.1f AT:%0.1f |"
1657 " VC:%0.1f VI:%0.1f VA:%0.1f |"
1658 " SC:%0.1f SI:%0.1f SA:%0.1f |"
1659 " CR:%0.1f IR:%0.1f AR:%0.1f",
1660 __func__, severity_distance_AV, severity_distance_PR,
1661 severity_distance_UI, severity_distance_AC, severity_distance_AT,
1662 severity_distance_VC, severity_distance_VI, severity_distance_VA,
1663 severity_distance_SC, severity_distance_SI, severity_distance_SA,
1664 severity_distance_CR, severity_distance_IR,
1665 severity_distance_AR);
1666 break;
1667 }
1668
1669 gchar *max_vec_expanded = cvss4_vector_expand (*max_vec);
1670 g_debug ("%s: max_vec: %s", __func__, max_vec_expanded);
1671 g_free (max_vec_expanded);
1672 g_strfreev (max_vectors);
1673
1674 *current_severity_distance_eq1 =
1675 severity_distance_AV + severity_distance_PR + severity_distance_UI;
1676 *current_severity_distance_eq2 = severity_distance_AC + severity_distance_AT;
1677 *current_severity_distance_eq3eq6 =
1678 severity_distance_VC + severity_distance_VI + severity_distance_VA
1679 + severity_distance_CR + severity_distance_IR + severity_distance_AR;
1680 *current_severity_distance_eq4 =
1681 severity_distance_SC + severity_distance_SI + severity_distance_SA;
1682 *current_severity_distance_eq5 = 0.0;
1683}
static gchar * cvss4_vector_expand(const char *vec)
Expands a simplified CVSS 4.0 vector into its full string form.
Definition cvss.c:1049
static double cvss4_severity_distance(cvss4_metric_t metric, const char *vec, const char *max_vec)
Calculate severity distance for a metric in two CVSS 4.0 vectors.
Definition cvss.c:1585
static gchar ** cvss4_max_vectors(const char *macrovector)
Composes a list of max vectors for the given CVSS 4.0 macrovector.
Definition cvss.c:1332

References CVSS4_AC, CVSS4_AR, CVSS4_AT, CVSS4_AV, CVSS4_CR, CVSS4_IR, cvss4_max_vectors(), CVSS4_PR, CVSS4_SA, CVSS4_SC, cvss4_severity_distance(), CVSS4_SI, CVSS4_UI, CVSS4_VA, CVSS4_VC, cvss4_vector_expand(), and CVSS4_VI.

Referenced by get_cvss_score_from_metrics_v4().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cvss4_init_macrovector_table()

void cvss4_init_macrovector_table ( )
static

Initialize the CVSS 4.0 macrovector lookup table.

Definition at line 840 of file cvss.c.

841{
843 return;
844
845 int index = 0;
846 cvss4_macrovector_table = g_hash_table_new (g_str_hash, g_str_equal);
847 while (cvss4_macrovector_mappings[index].vector != NULL)
848 {
849 g_hash_table_insert (cvss4_macrovector_table,
850 (gpointer) cvss4_macrovector_mappings[index].vector,
851 (gpointer) &cvss4_macrovector_mappings[index].score);
852
853 index++;
854 }
855}
static const cvss4_macrovector_mapping_t cvss4_macrovector_mappings[]
CVSS 4.0 macrovector mappings.
Definition cvss.c:350
static GHashTable * cvss4_macrovector_table
Hashtable for quick lookup of CVSS macrovector scores.
Definition cvss.c:427

References cvss4_macrovector_mappings, and cvss4_macrovector_table.

Referenced by cvss4_macrovector_score().

Here is the caller graph for this function:

◆ cvss4_m()

char cvss4_m ( const char * simplified_vec,
cvss4_metric_t metric )
static

Get the effective value of a metric in a simplified CVSS4 vector.

As this only returns the first character, the Provider Urgency metric (CVSS4_U) needs special handling to get the full string.

Parameters
[in]simplified_vecThe simplified vector string to get value from.
[in]metricThe metric to get the value of.
Returns
The metric value as a single character.

Definition at line 888 of file cvss.c.

889{
890 char selected = simplified_vec[metric];
891
892 // If E=X it will default to the worst case i.e. E=A
893 if (metric == CVSS4_E && selected == 'X')
894 return 'A';
895
896 // If CR=X, IR=X or AR=X they will default to the worst case
897 // i.e. CR=H, IR=H and AR=H
898 if ((metric == CVSS4_CR || metric == CVSS4_IR || metric == CVSS4_AR)
899 && selected == 'X')
900 return 'H';
901
902 // All other environmental metrics just overwrite base score values,
903 // so if they’re not defined just use the base score value.
904 if (metric >= CVSS4_AV && metric <= CVSS4_SA)
905 {
906 char modified_selected = simplified_vec[metric - CVSS4_AV + CVSS4_MAV];
907 if (modified_selected != 'X')
908 return modified_selected;
909 }
910
911 return selected;
912}

References CVSS4_AR, CVSS4_AV, CVSS4_CR, CVSS4_E, CVSS4_IR, CVSS4_MAV, and CVSS4_SA.

Referenced by cvss4_macrovector(), and cvss4_severity_distance().

Here is the caller graph for this function:

◆ cvss4_macrovector()

gchar * cvss4_macrovector ( const char * vec)
inlinestatic

Calculate CVSS 4.0 macrovector from a simplified vector.

Parameters
[in]vecThe simplified vector to get the macrovector of
Returns
The macrovector.

Definition at line 1098 of file cvss.c.

1099{
1100 gchar *macrovector;
1101 if (vec == NULL)
1102 return NULL;
1103
1104 macrovector = g_strdup (CVSS_MACROVECTOR_BLANK);
1105
1106 // EQ1: 0-AV:N and PR:N and UI:N
1107 // 1-(AV:N or PR:N or UI:N) and not (AV:N and PR:N and UI:N) and not AV:P
1108 // 2-AV:P or not(AV:N or PR:N or UI:N)
1109 char av = cvss4_m (vec, CVSS4_AV);
1110 char pr = cvss4_m (vec, CVSS4_PR);
1111 char ui = cvss4_m (vec, CVSS4_UI);
1112
1113 if (av == 'N' && pr == 'N' && ui == 'N')
1114 macrovector[0] = '0';
1115 else if ((av == 'N' || pr == 'N' || ui == 'N') && !(av == 'P'))
1116 macrovector[0] = '1';
1117 else
1118 macrovector[0] = '2';
1119
1120 // EQ2: 0-(AC:L and AT:N)
1121 // 1-(not(AC:L and AT:N))
1122 char ac = cvss4_m (vec, CVSS4_AC);
1123 char at = cvss4_m (vec, CVSS4_AT);
1124
1125 if (ac == 'L' && at == 'N')
1126 macrovector[1] = '0';
1127 else
1128 macrovector[1] = '1';
1129
1130 // EQ3: 0-(VC:H and VI:H)
1131 // 1-(not(VC:H and VI:H) and (VC:H or VI:H or VA:H))
1132 // 2-not (VC:H or VI:H or VA:H)
1133 char vc = cvss4_m (vec, CVSS4_VC);
1134 char vi = cvss4_m (vec, CVSS4_VI);
1135 char va = cvss4_m (vec, CVSS4_VA);
1136
1137 if (vc == 'H' && vi == 'H')
1138 macrovector[2] = '0';
1139 else if (vc == 'H' || vi == 'H' || va == 'H')
1140 macrovector[2] = '1';
1141 else
1142 macrovector[2] = '2';
1143
1144 // EQ4: 0-(MSI:S or MSA:S)
1145 // 1-not (MSI:S or MSA:S) and (SC:H or SI:H or SA:H)
1146 // 2-not (MSI:S or MSA:S) and not (SC:H or SI:H or SA:H)
1147 //
1148 // "Effective" SI and SA are the same as MSI and MSA for the purposes of
1149 // checking for the "Safety" value.
1150 char sc = cvss4_m (vec, CVSS4_SC);
1151 char si = cvss4_m (vec, CVSS4_SI);
1152 char sa = cvss4_m (vec, CVSS4_SA);
1153 if (si == 'S' || sa == 'S')
1154 macrovector[3] = '0';
1155 else if (sc == 'H' || si == 'H' || sa == 'H')
1156 macrovector[3] = '1';
1157 else
1158 macrovector[3] = '2';
1159
1160 // EQ5: 0-E:A
1161 // 1-E:P
1162 // 2-E:U
1163 char e = cvss4_m (vec, CVSS4_E);
1164 if (e == 'A')
1165 macrovector[4] = '0';
1166 else if (e == 'P')
1167 macrovector[4] = '1';
1168 else
1169 macrovector[4] = '2';
1170
1171 // EQ6: 0-(CR:H and VC:H) or (IR:H and VI:H) or (AR:H and VA:H)
1172 // 1-not[(CR:H and VC:H) or (IR:H and VI:H) or (AR:H and VA:H)]
1173 char cr = cvss4_m (vec, CVSS4_CR);
1174 char ir = cvss4_m (vec, CVSS4_IR);
1175 char ar = cvss4_m (vec, CVSS4_AR);
1176 if ((cr == 'H' && vc == 'H') || (ir == 'H' && vi == 'H')
1177 || (ar == 'H' && va == 'H'))
1178 macrovector[5] = '0';
1179 else
1180 macrovector[5] = '1';
1181
1182 return macrovector;
1183}
#define CVSS_MACROVECTOR_BLANK
Blank simplified CVSS 4.0 macrovector string.
Definition cvss.c:268
static char cvss4_m(const char *simplified_vec, cvss4_metric_t metric)
Get the effective value of a metric in a simplified CVSS4 vector.
Definition cvss.c:888

References CVSS4_AC, CVSS4_AR, CVSS4_AT, CVSS4_AV, CVSS4_CR, CVSS4_E, CVSS4_IR, cvss4_m(), CVSS4_PR, CVSS4_SA, CVSS4_SC, CVSS4_SI, CVSS4_UI, CVSS4_VA, CVSS4_VC, CVSS4_VI, and CVSS_MACROVECTOR_BLANK.

Referenced by get_cvss_score_from_metrics_v4().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cvss4_macrovector_score()

double cvss4_macrovector_score ( const char * vector)
inlinestatic

Get the CVSS 4.0 score for a given macrovector string.

Parameters
[in]vectorThe macrovector to look up.
Returns
The score of the given vector or -1.0 if the macrovector is invalid.

Definition at line 865 of file cvss.c.

866{
867 double *score_ptr;
868
870 score_ptr = g_hash_table_lookup (cvss4_macrovector_table, vector);
871 if (score_ptr)
872 return *score_ptr;
873 return -1.0;
874}
static void cvss4_init_macrovector_table()
Initialize the CVSS 4.0 macrovector lookup table.
Definition cvss.c:840

References cvss4_init_macrovector_table(), and cvss4_macrovector_table.

Referenced by cvss4_maximal_scoring_differences(), and get_cvss_score_from_metrics_v4().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cvss4_max_severities()

void cvss4_max_severities ( const char * macrovector,
double * max_severity_eq1,
double * max_severity_eq2,
double * max_severity_eq3eq6,
double * max_severity_eq4 )
static

Get the max severity values for a CVSS 4.0 macrovector.

The values are the MaxSeverity values already multiplied by 0.1

Parameters
[in]macrovectorThe macrovector to get the max severity values for
[out]max_severity_eq1Max severity for EQ1
[out]max_severity_eq2Max severity for EQ2
[out]max_severity_eq3eq6Max severity for EQ3 and EQ6
[out]max_severity_eq4Max severity for EQ4

Definition at line 1697 of file cvss.c.

1700{
1701 switch (macrovector[0])
1702 {
1703 case '0':
1704 *max_severity_eq1 = 0.1;
1705 break;
1706 case '1':
1707 *max_severity_eq1 = 0.4;
1708 break;
1709 case '2':
1710 *max_severity_eq1 = 0.5;
1711 break;
1712 default:
1713 *max_severity_eq1 = -99.0;
1714 }
1715
1716 switch (macrovector[1])
1717 {
1718 case '0':
1719 *max_severity_eq2 = 0.1;
1720 break;
1721 case '1':
1722 *max_severity_eq2 = 0.2;
1723 break;
1724 default:
1725 *max_severity_eq2 = -99.0;
1726 }
1727
1728 switch (macrovector[2])
1729 {
1730 case '0':
1731 if (macrovector[5] == '0')
1732 *max_severity_eq3eq6 = 0.7;
1733 else
1734 *max_severity_eq3eq6 = 0.6;
1735 break;
1736 case '1':
1737 *max_severity_eq3eq6 = 0.8;
1738 break;
1739 case '2':
1740 *max_severity_eq3eq6 = 1.0;
1741 break;
1742 default:
1743 *max_severity_eq3eq6 = -99.0;
1744 }
1745
1746 switch (macrovector[3])
1747 {
1748 case '0':
1749 *max_severity_eq4 = 0.6;
1750 break;
1751 case '1':
1752 *max_severity_eq4 = 0.5;
1753 break;
1754 case '2':
1755 *max_severity_eq4 = 0.4;
1756 break;
1757 default:
1758 *max_severity_eq4 = -99.0;
1759 }
1760}

Referenced by get_cvss_score_from_metrics_v4().

Here is the caller graph for this function:

◆ cvss4_max_vectors()

gchar ** cvss4_max_vectors ( const char * macrovector)
static

Composes a list of max vectors for the given CVSS 4.0 macrovector.

Parameters
[in]macrovectorThe macrovector to get the max vectors of.
Returns
NULL-terminated array of vectors in simplified form.

Definition at line 1332 of file cvss.c.

1333{
1334 const char **eq1_maxes, **eq2_maxes, **eq3eq6_maxes;
1335 const char *eq4_max, *eq5_max;
1336 gchar **ret;
1337
1338 // EQ1
1339 static const char *eq1_maxes_0[] = {"AV:N/PR:N/UI:N/", NULL};
1340 static const char *eq1_maxes_1[] = {"AV:A/PR:N/UI:N/", "AV:N/PR:L/UI:N/",
1341 "AV:N/PR:N/UI:P/", NULL};
1342 static const char *eq1_maxes_2[] = {"AV:P/PR:N/UI:N/", "AV:A/PR:L/UI:P/",
1343 NULL};
1344 if (macrovector[0] == '0')
1345 eq1_maxes = eq1_maxes_0;
1346 else if (macrovector[0] == '1')
1347 eq1_maxes = eq1_maxes_1;
1348 else
1349 eq1_maxes = eq1_maxes_2;
1350
1351 // EQ2
1352 static const char *eq2_maxes_0[] = {"AC:L/AT:N/", NULL};
1353 static const char *eq2_maxes_1[] = {"AC:H/AT:N/", "AC:L/AT:P/", NULL};
1354 if (macrovector[1] == '0')
1355 eq2_maxes = eq2_maxes_0;
1356 else
1357 eq2_maxes = eq2_maxes_1;
1358
1359 // EQ3+EQ6
1360 static const char *eq3eq6_maxes_00[] = {"VC:H/VI:H/VA:H/CR:H/IR:H/AR:H/",
1361 NULL};
1362 static const char *eq3eq6_maxes_01[] = {
1363 "VC:H/VI:H/VA:L/CR:M/IR:M/AR:H/", "VC:H/VI:H/VA:H/CR:M/IR:M/AR:M/", NULL};
1364 static const char *eq3eq6_maxes_10[] = {
1365 "VC:L/VI:H/VA:H/CR:H/IR:H/AR:H/", "VC:H/VI:L/VA:H/CR:H/IR:H/AR:H/", NULL};
1366 static const char *eq3eq6_maxes_11[] = {
1367 "VC:L/VI:H/VA:L/CR:H/IR:M/AR:H/", "VC:L/VI:H/VA:H/CR:H/IR:M/AR:M/",
1368 "VC:H/VI:L/VA:H/CR:M/IR:H/AR:M/", "VC:H/VI:L/VA:L/CR:M/IR:H/AR:H/",
1369 "VC:L/VI:L/VA:H/CR:H/IR:H/AR:M/", NULL};
1370 static const char *eq3eq6_maxes_21[] = {"VC:L/VI:L/VA:L/CR:H/IR:H/AR:H/",
1371 NULL};
1372 if ((macrovector[2] == '0'))
1373 {
1374 if (macrovector[5] == '0')
1375 eq3eq6_maxes = eq3eq6_maxes_00;
1376 else
1377 eq3eq6_maxes = eq3eq6_maxes_01;
1378 }
1379 else if ((macrovector[2] == '1'))
1380 {
1381 if (macrovector[5] == '0')
1382 eq3eq6_maxes = eq3eq6_maxes_10;
1383 else
1384 eq3eq6_maxes = eq3eq6_maxes_11;
1385 }
1386 else
1387 eq3eq6_maxes = eq3eq6_maxes_21;
1388
1389 // EQ4
1390 if (macrovector[3] == '0')
1391 eq4_max = "SC:H/SI:S/SA:S/";
1392 else if (macrovector[3] == '1')
1393 eq4_max = "SC:H/SI:H/SA:H/";
1394 else
1395 eq4_max = "SC:L/SI:L/SA:L/";
1396
1397 // EQ5
1398 if (macrovector[4] == '0')
1399 eq5_max = "E:A/";
1400 else if (macrovector[4] == '1')
1401 eq5_max = "E:P/";
1402 else
1403 eq5_max = "E:U/";
1404
1405 GPtrArray *max_vectors = g_ptr_array_new ();
1406 const char **eq1_max, **eq2_max, **eq3eq6_max;
1407 for (eq1_max = eq1_maxes; *eq1_max != NULL; eq1_max++)
1408 {
1409 for (eq2_max = eq2_maxes; *eq2_max != NULL; eq2_max++)
1410 {
1411 for (eq3eq6_max = eq3eq6_maxes; *eq3eq6_max != NULL; eq3eq6_max++)
1412 {
1413 gchar *full_vector =
1414 g_strdup_printf ("%s%s%s%s%s", *eq1_max, *eq2_max, *eq3eq6_max,
1415 eq4_max, eq5_max);
1416 gchar *vector = simplify_cvss4_vector (full_vector);
1417 if (vector == NULL)
1418 g_warning ("%s: generated vector %s is invalid", __func__,
1419 full_vector);
1420 else
1421 g_ptr_array_add (max_vectors, vector);
1422 g_free (full_vector);
1423 }
1424 }
1425 }
1426
1427 g_ptr_array_add (max_vectors, NULL);
1428
1429 ret = (gchar **) max_vectors->pdata;
1430 g_ptr_array_free (max_vectors, FALSE);
1431 return ret;
1432}
static gchar * simplify_cvss4_vector(const char *cvss_str)
Simplify CVSS 4.0 base vector so metrics can be indexed by enum.
Definition cvss.c:929

References simplify_cvss4_vector().

Referenced by cvss4_current_severity_distances().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cvss4_maximal_scoring_differences()

void cvss4_maximal_scoring_differences ( const char * macrovector,
double * available_distance_eq1,
double * available_distance_eq2,
double * available_distance_eq3eq6,
double * available_distance_eq4,
double * available_distance_eq5 )
static

Calulate the maximal scoring differences from a CVSS 4.0 macrovector.

Parameters
[in]macrovector
[out]available_distance_eq1Maximal scoring diff. for EQ1
[out]available_distance_eq2Maximal scoring diff. for EQ2
[out]available_distance_eq3eq6Maximal scoring diff. for EQ3 and EQ6
[out]available_distance_eq4Maximal scoring diff. for EQ4
[out]available_distance_eq5Maximal scoring diff. for EQ5

Definition at line 1196 of file cvss.c.

1202{
1203 double value = cvss4_macrovector_score (macrovector);
1204 double score_eq1_next_lower_macro, score_eq2_next_lower_macro;
1205 double score_eq3eq6_next_lower_macro;
1206 double score_eq4_next_lower_macro, score_eq5_next_lower_macro;
1207
1208 // Next lower macrovector for EQ1 only exists if EQ1 is 0 or 1.
1209 if (macrovector[0] <= '1')
1210 {
1211 gchar *eq1_next_lower_macro = g_strdup (macrovector);
1212 eq1_next_lower_macro[0]++;
1213 score_eq1_next_lower_macro =
1214 cvss4_macrovector_score (eq1_next_lower_macro);
1215 g_free (eq1_next_lower_macro);
1216 }
1217 else
1218 score_eq1_next_lower_macro = -1.0;
1219
1220 // Next lower macrovector for EQ2 only exists if EQ2 is 0.
1221 if (macrovector[1] == '0')
1222 {
1223 gchar *eq2_next_lower_macro = g_strdup (macrovector);
1224 eq2_next_lower_macro[1]++;
1225 score_eq2_next_lower_macro =
1226 cvss4_macrovector_score (eq2_next_lower_macro);
1227 g_free (eq2_next_lower_macro);
1228 }
1229 else
1230 score_eq2_next_lower_macro = -1.0;
1231
1232 // Next lower macrovector for EQ3.
1233 if ((macrovector[2] == '0' || macrovector[2] == '1') && macrovector[5] == '1')
1234 {
1235 gchar *eq3eq6_next_lower_macro = g_strdup (macrovector);
1236 eq3eq6_next_lower_macro[2]++;
1237 score_eq3eq6_next_lower_macro =
1238 cvss4_macrovector_score (eq3eq6_next_lower_macro);
1239 g_free (eq3eq6_next_lower_macro);
1240 }
1241 else if (macrovector[2] == '1' && macrovector[5] == '0')
1242 {
1243 gchar *eq3eq6_next_lower_macro = g_strdup (macrovector);
1244 eq3eq6_next_lower_macro[5]++;
1245 score_eq3eq6_next_lower_macro =
1246 cvss4_macrovector_score (eq3eq6_next_lower_macro);
1247 g_free (eq3eq6_next_lower_macro);
1248 }
1249 else if (macrovector[2] == '0' && macrovector[5] == '0')
1250 {
1251 gchar *eq3eq6_next_lower_macro_left = g_strdup (macrovector);
1252 eq3eq6_next_lower_macro_left[5]++;
1253 gchar *eq3eq6_next_lower_macro_right = g_strdup (macrovector);
1254 eq3eq6_next_lower_macro_right[2]++;
1255 double score_eq3eq6_next_lower_macro_left =
1256 cvss4_macrovector_score (eq3eq6_next_lower_macro_left);
1257 double score_eq3eq6_next_lower_macro_right =
1258 cvss4_macrovector_score (eq3eq6_next_lower_macro_right);
1259
1260 if (score_eq3eq6_next_lower_macro_left
1261 > score_eq3eq6_next_lower_macro_right)
1262 score_eq3eq6_next_lower_macro = score_eq3eq6_next_lower_macro_left;
1263 else
1264 score_eq3eq6_next_lower_macro = score_eq3eq6_next_lower_macro_right;
1265
1266 g_free (eq3eq6_next_lower_macro_left);
1267 g_free (eq3eq6_next_lower_macro_right);
1268 }
1269 else
1270 score_eq3eq6_next_lower_macro = -1.0;
1271
1272 // Next lower macrovector for EQ4 only exists if EQ4 is 0 or 1.
1273 if (macrovector[3] <= '1')
1274 {
1275 gchar *eq4_next_lower_macro = g_strdup (macrovector);
1276 eq4_next_lower_macro[3]++;
1277 score_eq4_next_lower_macro =
1278 cvss4_macrovector_score (eq4_next_lower_macro);
1279 g_free (eq4_next_lower_macro);
1280 }
1281 else
1282 score_eq4_next_lower_macro = -1.0;
1283
1284 // Next lower macrovector for EQ5 only exists if EQ5 is 0 or 1.
1285 if (macrovector[4] <= '1')
1286 {
1287 gchar *eq5_next_lower_macro = g_strdup (macrovector);
1288 eq5_next_lower_macro[4]++;
1289 score_eq5_next_lower_macro =
1290 cvss4_macrovector_score (eq5_next_lower_macro);
1291 g_free (eq5_next_lower_macro);
1292 }
1293 else
1294 score_eq5_next_lower_macro = -1.0;
1295
1296 if (value != -1.0)
1297 {
1298 *available_distance_eq1 = score_eq1_next_lower_macro != -1.0
1299 ? value - score_eq1_next_lower_macro
1300 : -1.0;
1301 *available_distance_eq2 = score_eq2_next_lower_macro != -1.0
1302 ? value - score_eq2_next_lower_macro
1303 : -1.0;
1304 *available_distance_eq3eq6 = score_eq3eq6_next_lower_macro != -1.0
1305 ? value - score_eq3eq6_next_lower_macro
1306 : -1.0;
1307 *available_distance_eq4 = score_eq4_next_lower_macro != -1.0
1308 ? value - score_eq4_next_lower_macro
1309 : -1.0;
1310 *available_distance_eq5 = score_eq5_next_lower_macro != -1.0
1311 ? value - score_eq5_next_lower_macro
1312 : -1.0;
1313 }
1314 else
1315 {
1316 *available_distance_eq1 = -1.0;
1317 *available_distance_eq2 = -1.0;
1318 *available_distance_eq3eq6 = -1.0;
1319 *available_distance_eq4 = -1.0;
1320 *available_distance_eq5 = -1.0;
1321 }
1322}
static double cvss4_macrovector_score(const char *vector)
Get the CVSS 4.0 score for a given macrovector string.
Definition cvss.c:865

References cvss4_macrovector_score().

Referenced by get_cvss_score_from_metrics_v4().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cvss4_metric_level()

double cvss4_metric_level ( cvss4_metric_t metric,
char value )
static

Get the index of a CVSS 4.0 metric value for severity distances.

Parameters
[in]metricThe metric to check.
[in]valueThe value of the given metric.
Returns
The index value

Definition at line 1443 of file cvss.c.

1444{
1445 switch (metric)
1446 {
1447 case CVSS4_AV:
1448 switch (value)
1449 {
1450 case 'N':
1451 return 0.0;
1452 case 'A':
1453 return 0.1;
1454 case 'L':
1455 return 0.2;
1456 case 'P':
1457 return 0.3;
1458 default:
1459 return -99.0;
1460 }
1461 break;
1462 case CVSS4_PR:
1463 switch (value)
1464 {
1465 case 'N':
1466 return 0.0;
1467 case 'L':
1468 return 0.1;
1469 case 'H':
1470 return 0.2;
1471 default:
1472 return -99.0;
1473 }
1474 break;
1475 case CVSS4_UI:
1476 switch (value)
1477 {
1478 case 'N':
1479 return 0.0;
1480 case 'P':
1481 return 0.1;
1482 case 'A':
1483 return 0.2;
1484 default:
1485 return -99.0;
1486 }
1487 break;
1488 case CVSS4_AC:
1489 switch (value)
1490 {
1491 case 'L':
1492 return 0.0;
1493 case 'H':
1494 return 0.1;
1495 default:
1496 return -99.0;
1497 }
1498 break;
1499 case CVSS4_AT:
1500 switch (value)
1501 {
1502 case 'N':
1503 return 0.0;
1504 case 'P':
1505 return 0.1;
1506 default:
1507 return -99.0;
1508 }
1509 break;
1510 case CVSS4_VC:
1511 case CVSS4_VI:
1512 case CVSS4_VA:
1513 switch (value)
1514 {
1515 case 'H':
1516 return 0.0;
1517 case 'L':
1518 return 0.1;
1519 case 'N':
1520 return 0.2;
1521 default:
1522 return -99.0;
1523 }
1524 break;
1525 case CVSS4_SC:
1526 case CVSS4_SI:
1527 case CVSS4_SA:
1528 switch (value)
1529 {
1530 case 'S':
1531 return 0.0;
1532 case 'H':
1533 return 0.1;
1534 case 'L':
1535 return 0.2;
1536 case 'N':
1537 return 0.3;
1538 default:
1539 return -99.0;
1540 }
1541 break;
1542 case CVSS4_CR:
1543 case CVSS4_IR:
1544 case CVSS4_AR:
1545 switch (value)
1546 {
1547 case 'H':
1548 return 0.0;
1549 case 'M':
1550 return 0.1;
1551 case 'L':
1552 return 0.2;
1553 default:
1554 return -99.0;
1555 }
1556 break;
1557
1558 // The Exploit Maturity metric is included in the reference implementation
1559 // but never used
1560 /*
1561 case CVSS4_E:
1562 switch (value)
1563 {
1564 case 'A': return 0.0;
1565 case 'P': return 0.1;
1566 case 'U': return 0.2;
1567 }
1568 break;
1569 */
1570 default:
1571 return -99.0;
1572 }
1573}

References CVSS4_AC, CVSS4_AR, CVSS4_AT, CVSS4_AV, CVSS4_CR, CVSS4_IR, CVSS4_PR, CVSS4_SA, CVSS4_SC, CVSS4_SI, CVSS4_UI, CVSS4_VA, CVSS4_VC, and CVSS4_VI.

Referenced by cvss4_severity_distance().

Here is the caller graph for this function:

◆ cvss4_severity_distance()

double cvss4_severity_distance ( cvss4_metric_t metric,
const char * vec,
const char * max_vec )
inlinestatic

Calculate severity distance for a metric in two CVSS 4.0 vectors.

Parameters
[in]metricThe metric to calculate severity distance for.
[in]vecThe vector to be scored in simplified form.
[in]max_vecThe max vector to subtract in simplified form.
Returns
The severity distance.

Definition at line 1585 of file cvss.c.

1587{
1588 return cvss4_metric_level (metric, cvss4_m (vec, metric))
1589 - cvss4_metric_level (metric, max_vec[metric]);
1590}
static double cvss4_metric_level(cvss4_metric_t metric, char value)
Get the index of a CVSS 4.0 metric value for severity distances.
Definition cvss.c:1443

References cvss4_m(), and cvss4_metric_level().

Referenced by cvss4_current_severity_distances().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cvss4_vector_expand()

gchar * cvss4_vector_expand ( const char * vec)
static

Expands a simplified CVSS 4.0 vector into its full string form.

Parameters
[in]vecThe simplified vector to expand
Returns
The full vector, including the "CVSS:4.0/" prefix

Definition at line 1049 of file cvss.c.

1050{
1051 cvss4_metric_t metric;
1052 GString *str = g_string_new ("CVSS:4.0");
1053 for (metric = 0; metric < CVSS4_METRICS_MAX; metric++)
1054 {
1055 const char *expanded_value;
1056 if (vec[metric] == 'X')
1057 continue;
1059 if (metric == CVSS4_U)
1060 {
1061 switch (vec[metric])
1062 {
1063 case 'R':
1064 expanded_value = "Red";
1065 break;
1066 case 'A':
1067 expanded_value = "Amber";
1068 break;
1069 case 'G':
1070 expanded_value = "Green";
1071 break;
1072 case 'C':
1073 expanded_value = "Clear";
1074 break;
1075 default:
1076 expanded_value = NULL;
1077 }
1078 }
1079 else
1080 expanded_value = NULL;
1081
1082 if (expanded_value)
1083 g_string_append_printf (str, "/%s:%s", def.metric_str, expanded_value);
1084 else
1085 g_string_append_printf (str, "/%s:%c", def.metric_str, vec[metric]);
1086 }
1087 return g_string_free (str, FALSE);
1088}
static cvss4_metric_def_t cvss4_metric_defs[]
String to enum mappings and allowed values for CVSS 4.0 metrics.
Definition cvss.c:294
String to enum mapping and allowed values for a CVSS 4.0 metric.
Definition cvss.c:278
const char * metric_str
Definition cvss.c:279

References cvss4_metric_defs, CVSS4_METRICS_MAX, CVSS4_U, and cvss4_metric_def_t::metric_str.

Referenced by cvss4_current_severity_distances().

Here is the caller graph for this function:

◆ get_cvss_score_from_base_metrics()

double get_cvss_score_from_base_metrics ( const char * cvss_str)

Calculate CVSS Score.

Parameters
cvss_strBase vector string from which to compute score.
Returns
The resulting score. -1 upon error during parsing.

Definition at line 585 of file cvss.c.

586{
587 struct cvss cvss;
588 char *token, *base_str, *base_metrics;
589
590 if (cvss_str == NULL)
591 return -1.0;
592
593 if (g_str_has_prefix (cvss_str, "CVSS:3.1/")
594 || g_str_has_prefix (cvss_str, "CVSS:3.0/"))
596 + strlen ("CVSS:3.X/"));
597 if (g_str_has_prefix (cvss_str, "CVSS:4.0/"))
598 return get_cvss_score_from_metrics_v4 (cvss_str + strlen ("CVSS:4.X/"));
599
600 memset (&cvss, 0x00, sizeof (struct cvss));
601
602 base_str = base_metrics = g_strdup_printf ("%s/", cvss_str);
603
604 while ((token = strchr (base_metrics, '/')) != NULL)
605 {
606 char *token2 = strtok (base_metrics, ":");
607 char *metric_name = token2;
608 char *metric_value;
609 enum base_metrics mval;
610 int rc;
611
612 *token++ = '\0';
613
614 if (metric_name == NULL)
615 goto ret_err;
616
617 metric_value = strtok (NULL, ":");
618
619 if (metric_value == NULL)
620 goto ret_err;
621
622 rc = toenum (metric_name, &mval);
623 if (rc)
624 goto ret_err;
625
626 if (set_impact_from_str (metric_value, mval, &cvss))
627 goto ret_err;
628
629 base_metrics = token;
630 }
631
632 g_free (base_str);
633 return __get_cvss_score (&cvss);
634
635ret_err:
636 g_free (base_str);
637 return (double) -1;
638}
static int set_impact_from_str(const char *value, enum base_metrics metric, struct cvss *cvss)
Set impact score from string representation.
Definition cvss.c:504
static int toenum(const char *str, enum base_metrics *res)
Determine base metric enumeration from a string.
Definition cvss.c:438
static double get_cvss_score_from_metrics_v4(const char *)
Calculate CVSS 4.0 Score.
Definition cvss.c:1770
base_metrics
CVSS v2 Base metrics.
Definition cvss.c:143
static double get_cvss_score_from_base_metrics_v3(const char *)
Calculate CVSS Score.
Definition cvss.c:696
static double __get_cvss_score(struct cvss *cvss)
Final CVSS score computation helper.
Definition cvss.c:561

References __get_cvss_score(), get_cvss_score_from_base_metrics_v3(), get_cvss_score_from_metrics_v4(), set_impact_from_str(), and toenum().

Referenced by add_tags_to_nvt(), and Ensure().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_cvss_score_from_base_metrics_v3()

double get_cvss_score_from_base_metrics_v3 ( const char * cvss_str)
static

Calculate CVSS Score.

Parameters
cvss_strVector from which to compute score, without prefix.
Returns
CVSS score, or -1 on error.

Definition at line 696 of file cvss.c.

697{
698 gchar **split, **point;
699 int scope_changed;
700 double impact_conf, impact_integ, impact_avail;
701 double vector, complexity, privilege, user;
702 double isc_base, impact, exploitability, base;
703
704 /* https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator
705 * https://www.first.org/cvss/v3.1/specification-document
706 * https://www.first.org/cvss/v3.0/specification-document */
707
708 scope_changed = -1;
709 impact_conf = -1.0;
710 impact_integ = -1.0;
711 impact_avail = -1.0;
712 vector = -1.0;
713 complexity = -1.0;
714 privilege = -1.0;
715 user = -1.0;
716
717 /* AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N */
718
719 split = g_strsplit (cvss_str, "/", 0);
720 point = split;
721 while (*point)
722 {
723 /* Scope. */
724 if (strncasecmp ("S:", *point, 2) == 0)
725 {
726 if (strcasecmp (*point + 2, "U") == 0)
727 scope_changed = 0;
728 else if (strcasecmp (*point + 2, "C") == 0)
729 scope_changed = 1;
730 }
731
732 /* Confidentiality. */
733 if (strncasecmp ("C:", *point, 2) == 0)
734 impact_conf = v3_impact (*point + 2);
735
736 /* Integrity. */
737 if (strncasecmp ("I:", *point, 2) == 0)
738 impact_integ = v3_impact (*point + 2);
739
740 /* Availability. */
741 if (strncasecmp ("A:", *point, 2) == 0)
742 impact_avail = v3_impact (*point + 2);
743
744 /* Attack Vector. */
745 if (strncasecmp ("AV:", *point, 3) == 0)
746 {
747 if (strcasecmp (*point + 3, "N") == 0)
748 vector = 0.85;
749 else if (strcasecmp (*point + 3, "A") == 0)
750 vector = 0.62;
751 else if (strcasecmp (*point + 3, "L") == 0)
752 vector = 0.55;
753 else if (strcasecmp (*point + 3, "P") == 0)
754 vector = 0.2;
755 }
756
757 /* Attack Complexity. */
758 if (strncasecmp ("AC:", *point, 3) == 0)
759 {
760 if (strcasecmp (*point + 3, "L") == 0)
761 complexity = 0.77;
762 else if (strcasecmp (*point + 3, "H") == 0)
763 complexity = 0.44;
764 }
765
766 /* Privileges Required. */
767 if (strncasecmp ("PR:", *point, 3) == 0)
768 {
769 if (strcasecmp (*point + 3, "N") == 0)
770 privilege = 0.85;
771 else if (strcasecmp (*point + 3, "L") == 0)
772 privilege = 0.62;
773 else if (strcasecmp (*point + 3, "H") == 0)
774 privilege = 0.27;
775 else
776 privilege = -1.0;
777 }
778
779 /* User Interaction. */
780 if (strncasecmp ("UI:", *point, 3) == 0)
781 {
782 if (strcasecmp (*point + 3, "N") == 0)
783 user = 0.85;
784 else if (strcasecmp (*point + 3, "R") == 0)
785 user = 0.62;
786 }
787
788 point++;
789 }
790
791 g_strfreev (split);
792
793 /* All of the base metrics are required. */
794
795 if (scope_changed == -1 || impact_conf == -1.0 || impact_integ == -1.0
796 || impact_avail == -1.0 || vector == -1.0 || complexity == -1.0
797 || privilege == -1.0 || user == -1.0)
798 return -1.0;
799
800 /* Privileges Required has a special case for S:C. */
801
802 if (scope_changed && privilege == 0.62)
803 privilege = 0.68;
804 else if (scope_changed && privilege == 0.27)
805 privilege = 0.5;
806
807 /* Impact. */
808
809 isc_base = 1 - ((1 - impact_conf) * (1 - impact_integ) * (1 - impact_avail));
810
811 if (scope_changed)
812 impact = 7.52 * (isc_base - 0.029) - 3.25 * pow ((isc_base - 0.02), 15);
813 else
814 impact = 6.42 * isc_base;
815
816 if (impact <= 0)
817 return 0.0;
818
819 /* Exploitability. */
820
821 exploitability = 8.22 * vector * complexity * privilege * user;
822
823 /* Final. */
824
825 if (scope_changed)
826 base = 1.08 * (impact + exploitability);
827 else
828 base = impact + exploitability;
829
830 if (base > 10.0)
831 return 10.0;
832
833 return roundup (base);
834}
static double v3_impact(const char *value)
Get impact.
Definition cvss.c:677
static double roundup(double cvss)
Round final score as in spec.
Definition cvss.c:650

References roundup(), and v3_impact().

Referenced by get_cvss_score_from_base_metrics().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_cvss_score_from_metrics_v4()

double get_cvss_score_from_metrics_v4 ( const char * cvss_str)
static

Calculate CVSS 4.0 Score.

Parameters
cvss_strVector from which to compute score, without prefix.
Returns
CVSS score, or -1 on error.

Definition at line 1770 of file cvss.c.

1771{
1772 char *vec = NULL;
1773 char *macrovector = NULL;
1774
1775 double available_distance_eq1, available_distance_eq2;
1776 double available_distance_eq3eq6;
1777 double available_distance_eq4, available_distance_eq5;
1778
1779 double current_severity_distance_eq1, current_severity_distance_eq2;
1780 double current_severity_distance_eq3eq6;
1781 double current_severity_distance_eq4, current_severity_distance_eq5;
1782
1783 double max_severity_eq1, max_severity_eq2, max_severity_eq3eq6;
1784 double max_severity_eq4;
1785
1786 double mean_distance, value;
1787
1788 int n_existing_lower = 0;
1789
1790 // Convert vector to simplified, enum-indexed string
1791 g_debug ("%s: CVSS string: %s", __func__, cvss_str);
1792 vec = simplify_cvss4_vector (cvss_str);
1793 g_debug ("%s: simplified vector: %s", __func__, vec);
1794 if (vec == NULL)
1795 return -1.0;
1796
1797 // Calculate macrovector
1798 macrovector = cvss4_macrovector (vec);
1799 value = cvss4_macrovector_score (macrovector);
1800 g_debug ("%s: macrovector: %s, value: %0.1f", __func__, macrovector, value);
1801 if (macrovector == NULL || value == -1.0)
1802 {
1803 g_free (vec);
1804 return -1.0;
1805 }
1806
1807 // Calculate maximum distances
1809 macrovector, &available_distance_eq1, &available_distance_eq2,
1810 &available_distance_eq3eq6, &available_distance_eq4,
1811 &available_distance_eq5);
1812 g_debug ("%s: maximal scoring diffs:"
1813 " EQ1:%0.1f EQ2:%0.1f EQ3+EQ6:%0.1f EQ5:%0.1f EQ6:%0.1f",
1814 __func__, available_distance_eq1, available_distance_eq2,
1815 available_distance_eq3eq6, available_distance_eq4,
1816 available_distance_eq5);
1817
1818 // Calculate current severity distances
1820 vec, macrovector, &current_severity_distance_eq1,
1821 &current_severity_distance_eq2, &current_severity_distance_eq3eq6,
1822 &current_severity_distance_eq4, &current_severity_distance_eq5);
1823
1824 g_debug ("%s: current severity distances:"
1825 "EQ1:%0.1f EQ2:%0.1f EQ3+EQ6:%0.1f EQ4:%0.1f EQ5:%0.1f",
1826 __func__, current_severity_distance_eq1,
1827 current_severity_distance_eq2, current_severity_distance_eq3eq6,
1828 current_severity_distance_eq4, current_severity_distance_eq5);
1829
1830 // Get MaxSeverity
1831 cvss4_max_severities (macrovector, &max_severity_eq1, &max_severity_eq2,
1832 &max_severity_eq3eq6, &max_severity_eq4);
1833
1834 g_free (vec);
1835 g_free (macrovector);
1836
1837 // Calculate mean distances
1838 mean_distance = 0.0;
1839 if (available_distance_eq1 >= 0.0)
1840 {
1841 n_existing_lower++;
1842 double percent_to_next_severity =
1843 (current_severity_distance_eq1) / max_severity_eq1;
1844 mean_distance += (available_distance_eq1 * percent_to_next_severity);
1845 }
1846
1847 if (available_distance_eq2 >= 0.0)
1848 {
1849 n_existing_lower++;
1850 double percent_to_next_severity =
1851 (current_severity_distance_eq2) / max_severity_eq2;
1852 mean_distance += (available_distance_eq2 * percent_to_next_severity);
1853 }
1854
1855 if (available_distance_eq3eq6 >= 0.0)
1856 {
1857 n_existing_lower++;
1858 double percent_to_next_severity =
1859 (current_severity_distance_eq3eq6) / max_severity_eq3eq6;
1860 mean_distance += (available_distance_eq3eq6 * percent_to_next_severity);
1861 }
1862
1863 if (available_distance_eq4 >= 0.0)
1864 {
1865 n_existing_lower++;
1866 double percent_to_next_severity =
1867 (current_severity_distance_eq4) / max_severity_eq4;
1868 mean_distance += (available_distance_eq4 * percent_to_next_severity);
1869 }
1870
1871 if (available_distance_eq5 >= 0.0)
1872 {
1873 // For EQ5 the percentage is always 0
1874 n_existing_lower++;
1875 }
1876
1877 mean_distance = mean_distance / n_existing_lower;
1878
1879 // Get and adjust macrovector score
1880 value = value - mean_distance;
1881 if (value < 0.0)
1882 value = 0.0;
1883 else if (value > 10.0)
1884 value = 10.0;
1885
1886 return round (value * 10.0) / 10.0;
1887}
static void cvss4_current_severity_distances(const char *vec, const char *macrovector, double *current_severity_distance_eq1, double *current_severity_distance_eq2, double *current_severity_distance_eq3eq6, double *current_severity_distance_eq4, double *current_severity_distance_eq5)
Calculate current severity distances for given CVSS 4.0 vector.
Definition cvss.c:1604
static gchar * cvss4_macrovector(const char *vec)
Calculate CVSS 4.0 macrovector from a simplified vector.
Definition cvss.c:1098
static void cvss4_max_severities(const char *macrovector, double *max_severity_eq1, double *max_severity_eq2, double *max_severity_eq3eq6, double *max_severity_eq4)
Get the max severity values for a CVSS 4.0 macrovector.
Definition cvss.c:1697
static void cvss4_maximal_scoring_differences(const char *macrovector, double *available_distance_eq1, double *available_distance_eq2, double *available_distance_eq3eq6, double *available_distance_eq4, double *available_distance_eq5)
Calulate the maximal scoring differences from a CVSS 4.0 macrovector.
Definition cvss.c:1196

References cvss4_current_severity_distances(), cvss4_macrovector(), cvss4_macrovector_score(), cvss4_max_severities(), cvss4_maximal_scoring_differences(), and simplify_cvss4_vector().

Referenced by get_cvss_score_from_base_metrics().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_exploitability_subscore()

double get_exploitability_subscore ( const struct cvss * cvss)
static

Calculate Exploitability Sub Score.

Parameters
[in]cvssContains the subscores associated to the metrics.
Returns
The resulting subscore.

Definition at line 488 of file cvss.c.

489{
492}
double access_vector
Definition cvss.c:169
double authentication
Definition cvss.c:171
double access_complexity
Definition cvss.c:170

References cvss::access_complexity, cvss::access_vector, and cvss::authentication.

Referenced by __get_cvss_score().

Here is the caller graph for this function:

◆ get_impact_subscore()

double get_impact_subscore ( const struct cvss * cvss)
static

Calculate Impact Sub Score.

Parameters
[in]cvssContains the subscores associated to the metrics.
Returns
The resulting subscore.

Definition at line 471 of file cvss.c.

472{
473 return 10.41
474 * (1
475 - (1 - cvss->conf_impact) * (1 - cvss->integ_impact)
476 * (1 - cvss->avail_impact));
477}
double integ_impact
Definition cvss.c:167
double avail_impact
Definition cvss.c:168
double conf_impact
Definition cvss.c:166

References cvss::avail_impact, cvss::conf_impact, and cvss::integ_impact.

Referenced by __get_cvss_score().

Here is the caller graph for this function:

◆ roundup()

double roundup ( double cvss)
static

Round final score as in spec.

Parameters
cvssCVSS score.
Returns
Rounded score.

Definition at line 650 of file cvss.c.

651{
652 int trim;
653
654 /* "Roundup returns the smallest number, specified to 1 decimal place,
655 * that is equal to or higher than its input. For example, Roundup (4.02)
656 * returns 4.1; and Roundup (4.00) returns 4.0." */
657
658 /* 3.020000000 => 3.1 */
659 /* 3.000000001 => 3.0 */
660 /* 5.299996 => 5.3 */
661 /* 5.500320 => 5.6 */
662
663 trim = round (cvss * 100000);
664 if ((trim % 10000) == 0)
665 return ((double) trim) / 100000;
666 return (floor (trim / 10000) + 1) / 10.0;
667}

Referenced by Ensure(), and get_cvss_score_from_base_metrics_v3().

Here is the caller graph for this function:

◆ set_impact_from_str()

int set_impact_from_str ( const char * value,
enum base_metrics metric,
struct cvss * cvss )
inlinestatic

Set impact score from string representation.

Parameters
[in]valueThe literal value associated to the metric.
[in]metricThe enumeration constant identifying the metric.
[out]cvssThe structure to update with the score.
Returns
0 on success, -1 on error.

Definition at line 504 of file cvss.c.

506{
507 int i;
508
509 for (i = 0; i < 3; i++)
510 {
511 const struct impact_item *impact;
512
513 impact = &impact_map[metric][i];
514
515 if (g_strcmp0 (impact->name, value) == 0)
516 {
517 switch (metric)
518 {
519 case A:
520 cvss->avail_impact = impact->nvalue;
521 break;
522
523 case I:
524 cvss->integ_impact = impact->nvalue;
525 break;
526
527 case C:
528 cvss->conf_impact = impact->nvalue;
529 break;
530
531 case Au:
532 cvss->authentication = impact->nvalue;
533 break;
534
535 case AV:
536 cvss->access_vector = impact->nvalue;
537 break;
538
539 case AC:
540 cvss->access_complexity = impact->nvalue;
541 break;
542
543 default:
544 return -1;
545 }
546 return 0;
547 }
548 }
549 return -1;
550}
static const struct impact_item impact_map[][3]
Definition cvss.c:174
Describe a CVSS impact element.
Definition cvss.c:156
const char * name
Definition cvss.c:157
double nvalue
Definition cvss.c:158

References A, AC, cvss::access_complexity, cvss::access_vector, Au, cvss::authentication, AV, cvss::avail_impact, C, cvss::conf_impact, I, impact_map, cvss::integ_impact, impact_item::name, and impact_item::nvalue.

Referenced by get_cvss_score_from_base_metrics().

Here is the caller graph for this function:

◆ simplify_cvss4_vector()

gchar * simplify_cvss4_vector ( const char * cvss_str)
static

Simplify CVSS 4.0 base vector so metrics can be indexed by enum.

The vector is simplified to a strictly ordered character array with each character index corresponding to the cvss4_base_metrics enum value and using 'X' for undefined metric values.

This relies on all allowed values being single characters, or having unique first characters in case of the Provider Urgency metric.

Parameters
[in]cvss_strThe original vector without the prefix "CVSS:4.0/".
Returns
A simplified vector string as described above or NULL on error.

Definition at line 929 of file cvss.c.

930{
931 gchar **split_cvss_str, **split_cvss_point;
932 gboolean valid = TRUE;
933 gchar *vec = NULL;
934 cvss4_metric_t metric;
935
936 if (cvss_str == NULL || strcmp (cvss_str, "") == 0)
937 return NULL;
938
939 vec = g_strdup (CVSS_METRICS_STR_BLANK);
940
941 split_cvss_str = g_strsplit (cvss_str, "/", -1);
942 split_cvss_point = split_cvss_str;
943 while (valid && *split_cvss_point)
944 {
945 if (strcmp (*split_cvss_point, "") == 0)
946 {
947 split_cvss_point++;
948 continue;
949 }
950
951 gchar **split_component = g_strsplit (*split_cvss_point, ":", 2);
952 const gchar *metric_str = split_component[0], *value = split_component[1];
953
954 valid = FALSE;
955
956 if (value == NULL)
957 {
958 g_debug ("%s: value for metric %s missing", __func__, metric_str);
959 g_strfreev (split_component);
960 break;
961 }
962 else if (strcasecmp (metric_str, "U") == 0)
963 {
964 // Special case for the Provider Urgency metric
965 if (strcasecmp (value, "Red") && strcasecmp (value, "Amber")
966 && strcasecmp (value, "Green") && strcasecmp (value, "Clear")
967 && strcasecmp (value, "X"))
968 {
969 g_debug ("%s: value for metric %s must be one of"
970 " 'Red', 'Amber', 'Green', 'Clear', 'X'",
971 __func__, metric_str);
972 g_strfreev (split_component);
973 break;
974 }
975 else
976 valid = TRUE;
977 }
978 else if (strlen (value) != 1)
979 {
980 g_debug ("%s: value for metric %s must be 1 character", __func__,
981 metric_str);
982 g_strfreev (split_component);
983 break;
984 }
985
986 cvss4_metric_def_t *metric_def = &cvss4_metric_defs[0];
987 while (metric_def->metric_str)
988 {
989 if (strcasecmp (metric_str, metric_def->metric_str) == 0)
990 {
991 char value_char = g_ascii_toupper (value[0]);
992
993 // Reject duplicate metrics
994 if (vec[metric_def->metric] != 'X')
995 {
996 g_debug ("%s: duplicate metric %s", __func__, metric_str);
997 break;
998 }
999
1000 // Set the metric in the simplified vector
1001 if (strchr (metric_def->values, value_char))
1002 {
1003 valid = TRUE;
1004 vec[metric_def->metric] = value_char;
1005 }
1006 else
1007 {
1008 g_debug ("%s: invalid metric: %s:%c", __func__, metric_str,
1009 value_char);
1010 }
1011 break;
1012 }
1013 metric_def++;
1014 }
1015
1016 split_cvss_point++;
1017 g_strfreev (split_component);
1018 }
1019 g_strfreev (split_cvss_str);
1020
1021 for (metric = CVSS4_AV; valid && metric <= CVSS4_SA; metric++)
1022 {
1023 if (vec[metric] == 'X')
1024 {
1025 g_debug ("%s: mandatory metric %s is undefined", __func__,
1026 cvss4_metric_defs[metric].metric_str);
1027 valid = FALSE;
1028 }
1029 }
1030
1031 if (!valid)
1032 {
1033 g_debug ("%s: vector %s is invalid", __func__, cvss_str);
1034 g_free (vec);
1035 return NULL;
1036 }
1037
1038 return vec;
1039}
#define CVSS_METRICS_STR_BLANK
Blank simplified CVSS 4.0 metrics string.
Definition cvss.c:263
const char * values
Definition cvss.c:281
const cvss4_metric_t metric
Definition cvss.c:280

References CVSS4_AV, cvss4_metric_defs, CVSS4_SA, CVSS_METRICS_STR_BLANK, cvss4_metric_def_t::metric, cvss4_metric_def_t::metric_str, and cvss4_metric_def_t::values.

Referenced by cvss4_max_vectors(), and get_cvss_score_from_metrics_v4().

Here is the caller graph for this function:

◆ toenum()

int toenum ( const char * str,
enum base_metrics * res )
static

Determine base metric enumeration from a string.

Parameters
[in]strBase metric in string form, for example "A".
[out]resWhere to write the desired value.
Returns
0 on success, -1 on error.

Definition at line 438 of file cvss.c.

439{
440 int rc = 0; /* let's be optimistic */
441
442 if (g_strcmp0 (str, "A") == 0)
443 *res = A;
444 else if (g_strcmp0 (str, "I") == 0)
445 *res = I;
446 else if (g_strcmp0 (str, "C") == 0)
447 *res = C;
448 else if (g_strcmp0 (str, "Au") == 0)
449 *res = Au;
450 else if (g_strcmp0 (str, "AU") == 0)
451 *res = Au;
452 else if (g_strcmp0 (str, "AV") == 0)
453 *res = AV;
454 else if (g_strcmp0 (str, "AC") == 0)
455 *res = AC;
456 else
457 rc = -1;
458
459 return rc;
460}

References A, AC, Au, AV, C, and I.

Referenced by get_cvss_score_from_base_metrics().

Here is the caller graph for this function:

◆ v3_impact()

double v3_impact ( const char * value)
static

Get impact.

Parameters
valueMetric value.
Returns
Impact.

Definition at line 677 of file cvss.c.

678{
679 if (strcasecmp (value, "N") == 0)
680 return 0.0;
681 if (strcasecmp (value, "L") == 0)
682 return 0.22;
683 if (strcasecmp (value, "H") == 0)
684 return 0.56;
685 return -1.0;
686}

Referenced by get_cvss_score_from_base_metrics_v3().

Here is the caller graph for this function:

Variable Documentation

◆ cvss4_macrovector_mappings

const cvss4_macrovector_mapping_t cvss4_macrovector_mappings[]
static

CVSS 4.0 macrovector mappings.

This list has been generated from the lookup table in the FIRST CVSS calculator reference implementation at https://github.com/FIRSTdotorg/cvss-v4-calculator/blob/main/cvss_lookup.js

Definition at line 350 of file cvss.c.

350 {
351 {"000000", 10}, {"000001", 9.9}, {"000010", 9.8}, {"000011", 9.5},
352 {"000020", 9.5}, {"000021", 9.2}, {"000100", 10}, {"000101", 9.6},
353 {"000110", 9.3}, {"000111", 8.7}, {"000120", 9.1}, {"000121", 8.1},
354 {"000200", 9.3}, {"000201", 9}, {"000210", 8.9}, {"000211", 8},
355 {"000220", 8.1}, {"000221", 6.8}, {"001000", 9.8}, {"001001", 9.5},
356 {"001010", 9.5}, {"001011", 9.2}, {"001020", 9}, {"001021", 8.4},
357 {"001100", 9.3}, {"001101", 9.2}, {"001110", 8.9}, {"001111", 8.1},
358 {"001120", 8.1}, {"001121", 6.5}, {"001200", 8.8}, {"001201", 8},
359 {"001210", 7.8}, {"001211", 7}, {"001220", 6.9}, {"001221", 4.8},
360 {"002001", 9.2}, {"002011", 8.2}, {"002021", 7.2}, {"002101", 7.9},
361 {"002111", 6.9}, {"002121", 5}, {"002201", 6.9}, {"002211", 5.5},
362 {"002221", 2.7}, {"010000", 9.9}, {"010001", 9.7}, {"010010", 9.5},
363 {"010011", 9.2}, {"010020", 9.2}, {"010021", 8.5}, {"010100", 9.5},
364 {"010101", 9.1}, {"010110", 9}, {"010111", 8.3}, {"010120", 8.4},
365 {"010121", 7.1}, {"010200", 9.2}, {"010201", 8.1}, {"010210", 8.2},
366 {"010211", 7.1}, {"010220", 7.2}, {"010221", 5.3}, {"011000", 9.5},
367 {"011001", 9.3}, {"011010", 9.2}, {"011011", 8.5}, {"011020", 8.5},
368 {"011021", 7.3}, {"011100", 9.2}, {"011101", 8.2}, {"011110", 8},
369 {"011111", 7.2}, {"011120", 7}, {"011121", 5.9}, {"011200", 8.4},
370 {"011201", 7}, {"011210", 7.1}, {"011211", 5.2}, {"011220", 5},
371 {"011221", 3}, {"012001", 8.6}, {"012011", 7.5}, {"012021", 5.2},
372 {"012101", 7.1}, {"012111", 5.2}, {"012121", 2.9}, {"012201", 6.3},
373 {"012211", 2.9}, {"012221", 1.7}, {"100000", 9.8}, {"100001", 9.5},
374 {"100010", 9.4}, {"100011", 8.7}, {"100020", 9.1}, {"100021", 8.1},
375 {"100100", 9.4}, {"100101", 8.9}, {"100110", 8.6}, {"100111", 7.4},
376 {"100120", 7.7}, {"100121", 6.4}, {"100200", 8.7}, {"100201", 7.5},
377 {"100210", 7.4}, {"100211", 6.3}, {"100220", 6.3}, {"100221", 4.9},
378 {"101000", 9.4}, {"101001", 8.9}, {"101010", 8.8}, {"101011", 7.7},
379 {"101020", 7.6}, {"101021", 6.7}, {"101100", 8.6}, {"101101", 7.6},
380 {"101110", 7.4}, {"101111", 5.8}, {"101120", 5.9}, {"101121", 5},
381 {"101200", 7.2}, {"101201", 5.7}, {"101210", 5.7}, {"101211", 5.2},
382 {"101220", 5.2}, {"101221", 2.5}, {"102001", 8.3}, {"102011", 7},
383 {"102021", 5.4}, {"102101", 6.5}, {"102111", 5.8}, {"102121", 2.6},
384 {"102201", 5.3}, {"102211", 2.1}, {"102221", 1.3}, {"110000", 9.5},
385 {"110001", 9}, {"110010", 8.8}, {"110011", 7.6}, {"110020", 7.6},
386 {"110021", 7}, {"110100", 9}, {"110101", 7.7}, {"110110", 7.5},
387 {"110111", 6.2}, {"110120", 6.1}, {"110121", 5.3}, {"110200", 7.7},
388 {"110201", 6.6}, {"110210", 6.8}, {"110211", 5.9}, {"110220", 5.2},
389 {"110221", 3}, {"111000", 8.9}, {"111001", 7.8}, {"111010", 7.6},
390 {"111011", 6.7}, {"111020", 6.2}, {"111021", 5.8}, {"111100", 7.4},
391 {"111101", 5.9}, {"111110", 5.7}, {"111111", 5.7}, {"111120", 4.7},
392 {"111121", 2.3}, {"111200", 6.1}, {"111201", 5.2}, {"111210", 5.7},
393 {"111211", 2.9}, {"111220", 2.4}, {"111221", 1.6}, {"112001", 7.1},
394 {"112011", 5.9}, {"112021", 3}, {"112101", 5.8}, {"112111", 2.6},
395 {"112121", 1.5}, {"112201", 2.3}, {"112211", 1.3}, {"112221", 0.6},
396 {"200000", 9.3}, {"200001", 8.7}, {"200010", 8.6}, {"200011", 7.2},
397 {"200020", 7.5}, {"200021", 5.8}, {"200100", 8.6}, {"200101", 7.4},
398 {"200110", 7.4}, {"200111", 6.1}, {"200120", 5.6}, {"200121", 3.4},
399 {"200200", 7}, {"200201", 5.4}, {"200210", 5.2}, {"200211", 4},
400 {"200220", 4}, {"200221", 2.2}, {"201000", 8.5}, {"201001", 7.5},
401 {"201010", 7.4}, {"201011", 5.5}, {"201020", 6.2}, {"201021", 5.1},
402 {"201100", 7.2}, {"201101", 5.7}, {"201110", 5.5}, {"201111", 4.1},
403 {"201120", 4.6}, {"201121", 1.9}, {"201200", 5.3}, {"201201", 3.6},
404 {"201210", 3.4}, {"201211", 1.9}, {"201220", 1.9}, {"201221", 0.8},
405 {"202001", 6.4}, {"202011", 5.1}, {"202021", 2}, {"202101", 4.7},
406 {"202111", 2.1}, {"202121", 1.1}, {"202201", 2.4}, {"202211", 0.9},
407 {"202221", 0.4}, {"210000", 8.8}, {"210001", 7.5}, {"210010", 7.3},
408 {"210011", 5.3}, {"210020", 6}, {"210021", 5}, {"210100", 7.3},
409 {"210101", 5.5}, {"210110", 5.9}, {"210111", 4}, {"210120", 4.1},
410 {"210121", 2}, {"210200", 5.4}, {"210201", 4.3}, {"210210", 4.5},
411 {"210211", 2.2}, {"210220", 2}, {"210221", 1.1}, {"211000", 7.5},
412 {"211001", 5.5}, {"211010", 5.8}, {"211011", 4.5}, {"211020", 4},
413 {"211021", 2.1}, {"211100", 6.1}, {"211101", 5.1}, {"211110", 4.8},
414 {"211111", 1.8}, {"211120", 2}, {"211121", 0.9}, {"211200", 4.6},
415 {"211201", 1.8}, {"211210", 1.7}, {"211211", 0.7}, {"211220", 0.8},
416 {"211221", 0.2}, {"212001", 5.3}, {"212011", 2.4}, {"212021", 1.4},
417 {"212101", 2.4}, {"212111", 1.2}, {"212121", 0.5}, {"212201", 1},
418 {"212211", 0.3}, {"212221", 0.1}, {NULL, 0.0}};

Referenced by cvss4_init_macrovector_table().

◆ cvss4_macrovector_table

GHashTable* cvss4_macrovector_table = NULL
static

Hashtable for quick lookup of CVSS macrovector scores.

Macrovector scores should be looked up with cvss4_macrovector_score which ensures the table is initialized and returns the scores as double values instead of pointers.

Definition at line 427 of file cvss.c.

Referenced by cvss4_init_macrovector_table(), and cvss4_macrovector_score().

◆ cvss4_metric_defs

cvss4_metric_def_t cvss4_metric_defs[]
static

String to enum mappings and allowed values for CVSS 4.0 metrics.

Notes:

  • The Provider Urgency metric can be longer than one character, so it needs special handling.
  • The orginal specification only lists the value S (Safety) for the modified metrics MSI and MSA, but the calculator reference implementation also uses it for the unmodified ones, SI and SA.

Definition at line 294 of file cvss.c.

294 {
295 // Base (11 metrics)
296 {"AV", CVSS4_AV, "NALP"},
297 {"AC", CVSS4_AC, "LH"},
298 {"AT", CVSS4_AT, "NP"},
299 {"PR", CVSS4_PR, "NLH"},
300 {"UI", CVSS4_UI, "NPA"},
301 {"VC", CVSS4_VC, "HLN"},
302 {"VI", CVSS4_VI, "HLN"},
303 {"VA", CVSS4_VA, "HLN"},
304 {"SC", CVSS4_SC, "HLN"},
305 {"SI", CVSS4_SI, "HLNS"},
306 {"SA", CVSS4_SA, "HLNS"},
307 // Threat (1 metric)
308 {"E", CVSS4_E, "XAPU"},
309 // Environmental (14 metrics)
310 {"CR", CVSS4_CR, "XHML"},
311 {"IR", CVSS4_IR, "XHML"},
312 {"AR", CVSS4_AR, "XHML"},
313 {"MAV", CVSS4_MAV, "XNALP"},
314 {"MAC", CVSS4_MAC, "XLH"},
315 {"MAT", CVSS4_MAT, "XNP"},
316 {"MPR", CVSS4_MPR, "XNLH"},
317 {"MUI", CVSS4_MUI, "XNPA"},
318 {"MVC", CVSS4_MVC, "XHLN"},
319 {"MVI", CVSS4_MVI, "XHLN"},
320 {"MVA", CVSS4_MVA, "XHLN"},
321 {"MSC", CVSS4_MSC, "XHLN"},
322 {"MSI", CVSS4_MSI, "XHLNS"},
323 {"MSA", CVSS4_MSA, "XHLNS"},
324 // Supplemental (6 metrics)
325 {"S", CVSS4_S, "XNP"},
326 {"AU", CVSS4_AU, "XNY"},
327 {"R", CVSS4_R, "XAUI"},
328 {"V", CVSS4_V, "XDC"},
329 {"RE", CVSS4_RE, "XLMH"},
330 {"U", CVSS4_U, "XCGAR"}, // Abbreviated to first letters
331 // Max number / array terminator
332 {NULL, CVSS4_METRICS_MAX, NULL}};

Referenced by cvss4_vector_expand(), and simplify_cvss4_vector().

◆ impact_map

const struct impact_item impact_map[][3]
static

Definition at line 174 of file cvss.c.

174 {
175 [A] =
176 {
177 {"N", A_NONE},
178 {"P", A_PARTIAL},
179 {"C", A_COMPLETE},
180 },
181 [I] =
182 {
183 {"N", I_NONE},
184 {"P", I_PARTIAL},
185 {"C", I_COMPLETE},
186 },
187 [C] =
188 {
189 {"N", C_NONE},
190 {"P", C_PARTIAL},
191 {"C", C_COMPLETE},
192 },
193 [Au] =
194 {
195 {"N", Au_NONE},
197 {"S", Au_SINGLE_INSTANCE},
198 },
199 [AV] =
200 {
201 {"N", AV_NETWORK},
202 {"A", AV_ADJACENT_NETWORK},
203 {"L", AV_LOCAL},
204 },
205 [AC] =
206 {
207 {"L", AC_LOW},
208 {"M", AC_MEDIUM},
209 {"H", AC_HIGH},
210 },
211};
#define C_COMPLETE
Definition cvss.c:122
#define AV_LOCAL
Definition cvss.c:101
#define Au_SINGLE_INSTANCE
Definition cvss.c:114
#define A_PARTIAL
Definition cvss.c:135
#define C_NONE
ConfidentialityImpact (C) Constants.
Definition cvss.c:120
#define I_PARTIAL
Definition cvss.c:128
#define AV_NETWORK
AccessVector (AV) Constants.
Definition cvss.c:99
#define C_PARTIAL
Definition cvss.c:121
#define A_COMPLETE
Definition cvss.c:136
#define Au_MULTIPLE_INSTANCES
Authentication (Au) Constants.
Definition cvss.c:113
#define AC_LOW
AccessComplexity (AC) Constants.
Definition cvss.c:106
#define I_NONE
IntegrityImpact (I) Constants.
Definition cvss.c:127
#define A_NONE
AvailabilityImpact (A) Constants.
Definition cvss.c:134
#define I_COMPLETE
Definition cvss.c:129
#define AC_MEDIUM
Definition cvss.c:107
#define AV_ADJACENT_NETWORK
Definition cvss.c:100
#define AC_HIGH
Definition cvss.c:108
#define Au_NONE
Definition cvss.c:115

Referenced by set_impact_from_str().