OpenVAS Libraries  9.0.3
cvss.c
Go to the documentation of this file.
1 /* openvas-libraries/base
2  * $Id$
3  * Description: CVSS utility functions
4  *
5  * Authors:
6  * Preeti Subramanian
7  *
8  * Copyright:
9  * Copyright (C) 2012 Greenbone Networks GmbH
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
66 #include <string.h>
67 #include <stdio.h>
68 
69 #include <glib.h>
70 
71 
72 /* AccessVector (AV) Constants */
73 #define AV_NETWORK 1.0
74 #define AV_ADJACENT_NETWORK 0.646
75 #define AV_LOCAL 0.395
76 
77 /* AccessComplexity (AC) Constants */
78 #define AC_LOW 0.71
79 #define AC_MEDIUM 0.61
80 #define AC_HIGH 0.35
81 
82 /* Authentication (Au) Constants */
83 #define Au_MULTIPLE_INSTANCES 0.45
84 #define Au_SINGLE_INSTANCE 0.56
85 #define Au_NONE 0.704
86 
87 /* ConfidentialityImpact (C) Constants */
88 #define C_NONE 0.0
89 #define C_PARTIAL 0.275
90 #define C_COMPLETE 0.660
91 
92 /* IntegrityImpact (I) Constants */
93 #define I_NONE 0.0
94 #define I_PARTIAL 0.275
95 #define I_COMPLETE 0.660
96 
97 /* AvailabilityImpact (A) Constants */
98 #define A_NONE 0.0
99 #define A_PARTIAL 0.275
100 #define A_COMPLETE 0.660
101 
102 
103 enum base_metrics { A, I, C, Au, AC, AV };
104 
109 {
110  const char *name;
111  double nvalue;
112 };
113 
117 struct cvss
118 {
119  double conf_impact;
120  double integ_impact;
121  double avail_impact;
122  double access_vector;
124  double authentication;
125 };
126 
127 
128 static const struct impact_item impact_map[][3] = {
129  [A] = {
130  {"N", A_NONE},
131  {"P", A_PARTIAL},
132  {"C", A_COMPLETE},
133  },
134  [I] = {
135  {"N", I_NONE},
136  {"P", I_PARTIAL},
137  {"C", I_COMPLETE},
138  },
139  [C] = {
140  {"N", C_NONE},
141  {"P", C_PARTIAL},
142  {"C", C_COMPLETE},
143  },
144  [Au] = {
145  {"N", Au_NONE},
146  {"M", Au_MULTIPLE_INSTANCES},
147  {"S", Au_SINGLE_INSTANCE},
148  },
149  [AV] = {
150  {"N", AV_NETWORK},
151  {"A", AV_ADJACENT_NETWORK},
152  {"L", AV_LOCAL},
153  },
154  [AC] = {
155  {"L", AC_LOW},
156  {"M", AC_MEDIUM},
157  {"H", AC_HIGH},
158  },
159 };
160 
169 static int
170 toenum (const char * str, enum base_metrics *res)
171 {
172  int rc = 0; /* let's be optimistic */
173 
174  if (g_strcmp0 (str, "A") == 0)
175  *res = A;
176  else if (g_strcmp0 (str, "I") == 0)
177  *res = I;
178  else if (g_strcmp0 (str, "C") == 0)
179  *res = C;
180  else if (g_strcmp0 (str, "Au") == 0)
181  *res = Au;
182  else if (g_strcmp0 (str, "AU") == 0)
183  *res = Au;
184  else if (g_strcmp0 (str, "AV") == 0)
185  *res = AV;
186  else if (g_strcmp0 (str, "AC") == 0)
187  *res = AC;
188  else
189  rc = -1;
190 
191  return rc;
192 }
193 
202 static double
203 get_impact_subscore (const struct cvss *cvss)
204 {
205  return (10.41 * (1 -
206  (1 - cvss->conf_impact) *
207  (1 - cvss->integ_impact) *
208  (1 - cvss->avail_impact)));
209 }
210 
219 static double
220 get_exploitability_subscore (const struct cvss *cvss)
221 {
222  return (20 * cvss->access_vector *
224 }
225 
235 static inline int
236 set_impact_from_str (const char *value, enum base_metrics metric,
237  struct cvss *cvss)
238 {
239  int i;
240 
241  for (i = 0; i < 3; i++)
242  {
243  const struct impact_item *impact;
244 
245  impact = &impact_map[metric][i];
246 
247  if (g_strcmp0 (impact->name, value) == 0)
248  {
249  switch (metric)
250  {
251  case A:
252  cvss->avail_impact = impact->nvalue;
253  break;
254 
255  case I:
256  cvss->integ_impact = impact->nvalue;
257  break;
258 
259  case C:
260  cvss->conf_impact = impact->nvalue;
261  break;
262 
263  case Au:
264  cvss->authentication = impact->nvalue;
265  break;
266 
267  case AV:
268  cvss->access_vector = impact->nvalue;
269  break;
270 
271  case AC:
272  cvss->access_complexity = impact->nvalue;
273  break;
274 
275  default:
276  return -1;
277  }
278  return 0;
279  }
280  }
281  return -1;
282 }
283 
292 static double
293 __get_cvss_score (struct cvss *cvss)
294 {
295  double impact = 1.176;
296  double impact_sub;
297  double exploitability_sub;
298 
299  impact_sub = get_impact_subscore (cvss);
300  exploitability_sub = get_exploitability_subscore (cvss);
301 
302  if (impact_sub < 0.1)
303  impact = 0.0;
304 
305  return (((0.6 * impact_sub) + (0.4 * exploitability_sub) - 1.5) * impact)
306  + 0.0;
307 }
308 
316 double
317 get_cvss_score_from_base_metrics (const char *cvss_str)
318 {
319  struct cvss cvss;
320  char *token, *base_str, *base_metrics;
321 
322  memset(&cvss, 0x00, sizeof(struct cvss));
323 
324  if (cvss_str == NULL)
325  return -1.0;
326 
327  base_str = base_metrics = g_strdup_printf ("%s/", cvss_str);
328 
329  while ((token = strchr (base_metrics, '/')) != NULL)
330  {
331  char *token2 = strtok (base_metrics, ":");
332  char *metric_name = token2;
333  char *metric_value;
334  enum base_metrics mval;
335  int rc;
336 
337  *token++ = '\0';
338 
339  if (metric_name == NULL)
340  goto ret_err;
341 
342  metric_value = strtok (NULL, ":");
343 
344  if (metric_value == NULL)
345  goto ret_err;
346 
347  rc = toenum (metric_name, &mval);
348  if (rc)
349  goto ret_err;
350 
351  if (set_impact_from_str (metric_value, mval, &cvss))
352  goto ret_err;
353 
354  base_metrics = token;
355  }
356 
357  g_free (base_str);
358  return __get_cvss_score (&cvss);
359 
360 ret_err:
361  g_free (base_str);
362  return (double)-1;
363 }
Definition: cvss.c:103
#define Au_SINGLE_INSTANCE
Definition: cvss.c:84
#define C_NONE
Definition: cvss.c:88
#define AV_ADJACENT_NETWORK
Definition: cvss.c:74
Describe a CVSS metrics.
Definition: cvss.c:117
#define Au_NONE
Definition: cvss.c:85
double avail_impact
Definition: cvss.c:121
double nvalue
Definition: cvss.c:111
#define AC_LOW
Definition: cvss.c:78
Definition: cvss.c:103
#define AV_LOCAL
Definition: cvss.c:75
#define C_COMPLETE
Definition: cvss.c:90
#define A_COMPLETE
Definition: cvss.c:100
double get_cvss_score_from_base_metrics(const char *cvss_str)
Calculate CVSS Score.
Definition: cvss.c:317
double authentication
Definition: cvss.c:124
#define A_PARTIAL
Definition: cvss.c:99
const char * name
Definition: cvss.c:110
#define Au_MULTIPLE_INSTANCES
Definition: cvss.c:83
Definition: cvss.c:103
Definition: cvss.c:103
#define AC_HIGH
Definition: cvss.c:80
Definition: cvss.c:103
#define I_COMPLETE
Definition: cvss.c:95
#define C_PARTIAL
Definition: cvss.c:89
#define A_NONE
Definition: cvss.c:98
double conf_impact
Definition: cvss.c:119
#define AV_NETWORK
Definition: cvss.c:73
#define AC_MEDIUM
Definition: cvss.c:79
double integ_impact
Definition: cvss.c:120
Definition: cvss.c:103
double access_complexity
Definition: cvss.c:123
Describe a CVSS impact element.
Definition: cvss.c:108
double access_vector
Definition: cvss.c:122
#define I_PARTIAL
Definition: cvss.c:94
base_metrics
Definition: cvss.c:103
#define I_NONE
Definition: cvss.c:93