diff options
Diffstat (limited to 'macros/latex/contrib/cvss/cvss.ins')
-rw-r--r-- | macros/latex/contrib/cvss/cvss.ins | 403 |
1 files changed, 403 insertions, 0 deletions
diff --git a/macros/latex/contrib/cvss/cvss.ins b/macros/latex/contrib/cvss/cvss.ins new file mode 100644 index 0000000000..a11eb8b58d --- /dev/null +++ b/macros/latex/contrib/cvss/cvss.ins @@ -0,0 +1,403 @@ +%% +%% This is file `cvss.ins', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% cvss.dtx (with options: `install') +%% ---------------------------------------------------------------- +%% cvss --- A package to compute and display CVSS base scores +%% E-mail: pierre@vivegnis.be +%% Released under the LaTeX Project Public License v1.3c or later +%% See http://www.latex-project.org/lppl.txt +%% ---------------------------------------------------------------- +%% +\input docstrip.tex +\keepsilent +\askforoverwritefalse +\preamble +---------------------------------------------------------------- +cvss --- A package to compute and display CVSS base scores +E-mail: pierre@vivegnis.be +Released under the LaTeX Project Public License v1.3c or later +See http://www.latex-project.org/lppl.txt +---------------------------------------------------------------- + +\endpreamble +\postamble + +Copyright (C) 2022 by Pierre VIVEGNIS <pierre@vivegnis.be> + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License (LPPL), either +version 1.3c of this license or (at your option) any later +version. The latest version of this license is in the file: + +http://www.latex-project.org/lppl.txt + +This work is "maintained" (as per LPPL maintenance status) by +Pierre VIVEGNIS. + +This work consists of the file cvss.dtx +and the derived files cvss.ins, + cvss.pdf and + cvss.sty. + +\endpostamble +\usedir{tex/latex/cvss} +\generate{ + \file{\jobname.sty}{\from{\jobname.dtx}{package}} +} +\endbatchfile + % \begin{syntax} + % \cs{cvssScore} \Arg{CVSS string} + % \end{syntax} + % \begin{syntax} + % \cs{cvssScorepretty} \Arg{CVSS string} + % \end{syntax} + % This macro will print a \textbf{colored} base CVSS 3.1 score of an \marg{input vector} (without \texttt{CVSS3.1/}). The output of this macro is a floating point CVSS score. + % \end{function} + % \begin{syntax} + % \cs{cvssLevel} \Arg{CVSS string} + % \end{syntax} + % \begin{syntax} + % \cs{cvssLevelpretty} \Arg{CVSS string} + % \end{syntax} + % \begin{syntax} + % \cs{cvssTag} \Arg{CVSS string} + % \end{syntax} + % \begin{syntax} + % \cs{cvssPrint} \Arg{CVSS string} + % \end{syntax} + % This macro will print all details of a CVSS string: colored level, score, and hyperlink to FIRST calculator, from an \marg{input vector} (without \texttt{CVSS3.1/}). + % \end{function} + % \begin{syntax} + % \cs{category} \Arg{CVSS score} + % \end{syntax} + % \begin{syntax} + % \cs{cvssFrame} \Arg{CVSS score} + % \end{syntax} + % This macro will output a CVSS tag based on a CVSS \textbf{level} passed as argument. The mandatory argument must be one of the defined CVSS levels (None, Info, Low, Medium, High or Critical), for example \texttt{Info}. + % \end{function} + + + % \begin{verbatim} + % \end{verbatim} + %\end{minipage}% + %\end{minipage} + + % \begin{verbatim} + % \end{verbatim} + %\end{minipage}% + %\end{minipage} + + % \begin{verbatim} + % \end{verbatim} + %\end{minipage}% + %\end{minipage} + + % \begin{verbatim} + % \end{verbatim} + %\end{minipage}% + %\end{minipage} + + + % \begin{verbatim} + %\cvssFrame{Low} + % \end{verbatim} + %\end{minipage}% + %\cvssFrame{Low} + + %\category{9.9} + %\category{9.9} +\RequirePackage{expl3} +\RequirePackage[skins]{tcolorbox} +\tcbuselibrary{xparse} +\RequirePackage{xstring} +\RequirePackage{hyperref} +\def\scoreLow{0.1} +\def\scoreMed{4.0} +\def\scoreHigh{7.0} +\def\scoreCrit{9.0} +\definecolor{color@cvss@None}{RGB}{83, 170, 51} +\definecolor{color@cvss@Low}{RGB}{255, 203, 13} +\definecolor{color@cvss@Medium}{RGB}{249, 160, 9} +\definecolor{color@cvss@High}{RGB}{223, 61, 3} +\definecolor{color@cvss@Critical}{RGB}{204, 5, 0} +\ExplSyntaxOn +\cs_new:Npn \__CVSS_roundup:n #1 { + \fp_eval:n { ceil(#1,1) } + \fp_compare:nT { ceil(#1,1)=ceil(#1,0) } {.0} +} +\msg_new:nnn { CVSS } { invalid-option }{ Value~'#2'~invalid~for~#1~#3.} +\msg_new:nnn { CVSS } { invalid-structure } { CVSS~metric~#1~is~not~correct~(#2)~#3.} +\msg_new:nnn { CVSS } { invalid-length } { CVSS~vector~"#1"~is~badly~formatted~#2.} +\cs_new:Npn \__CVSS_parseAV:n #1 +{ + \str_case_e:nnF {#1} + { + { N } { 0.85 } % Network + { A } { 0.62 } % Adjacent + { L } { 0.55 } % Local + { P } { 0.2 } % Physical + } + { \msg_error:nnxxx { CVSS } { invalid-option } { parseAV } {#1} {\msg_line_context:} } +} +\cs_new:Npn \__CVSS_parseAC:n #1 +{ + \str_case_e:nnF {#1} + { + { H } { 0.44 } % High + { L } { 0.77 } % Low + + } + { \msg_error:nnxxx { CVSS } { invalid-option } { parseAC } {#1} {\msg_line_context:} } +} +\cs_new:Npn \__CVSS_parsePRScopeUnchanged:n #1 +{ + \str_case_e:nnF {#1} + { + { N } { 0.85 } % None + { L } { 0.62 } % Low + { H } { 0.27 } % High + } + { \msg_error:nnxxx { CVSS } { invalid-option } { parsePRScopeUnchanged } {#1} {\msg_line_context:} } +} +\cs_new:Npn \__CVSS_parsePRScopeChanged:n #1 +{ + \str_case_e:nnF {#1} + { + { N } { 0.85 } % None + { L } { 0.68 } % Low + { H } { 0.50 } % High + } + { \msg_error:nnxxx { CVSS } { invalid-option } { parsePRScopeChanged } {#1} {\msg_line_context:} } +} +\cs_new:Npn \__CVSS_parsePR:nn #1#2 +{ + % #1 Privilege Required + % #2 Scope + \str_case_e:nnF {#2} + { + { U } { \exp_args:Ne \__CVSS_parsePRScopeUnchanged:n {#1} } + { C } { \exp_args:Ne \__CVSS_parsePRScopeChanged:n {#1} } + } + { \msg_error:nnxxx { CVSS } { invalid-option } { parsePR } {#1} {\msg_line_context:} } +} +\cs_new:Npn \__CVSS_parseUI:n #1 +{ + \str_case_e:nnF {#1} + { + { N } { 0.85 } % None + { R } { 0.62 } % Required + } + { \msg_error:nnxxx { CVSS } { invalid-option } { parseUI } {#1} {\msg_line_context:} } +} + + +\cs_new:Npn \__CVSS_parseCIA:n #1 +{ + \str_case_e:nnF {#1} + { + { H } { 0.56 } + { L } { 0.22 } + { N } { 0.00 } + } + { \msg_error:nnxxx { CVSS } { invalid-option } { parseCIA } {#1} {\msg_line_context:} } +} +\cs_new:Npn \__CVSS_calcISS:nnn #1#2#3 +{ + % #1 Confidentiality Impact %High H, Low L, None N + % #2 Integrity Impact %High H, Low L, None N + % #3 Availability Impact %High H, Low L, None N + 1 - ( (1 - (\__CVSS_parseCIA:n {#1})) * (1 - (\__CVSS_parseCIA:n {#2})) * (1 - (\__CVSS_parseCIA:n {#3})) ) +} +\cs_new:Npn \__CVSS_calcImpact:nn #1#2 +{ + % #1 = Scope + % #2 = ISS + % Scope Unchanged 6.42 × ISS + % Scope Changed 7.52 × [ISS-0.029] - 3.25 × [ISS-0.02]15 + \str_case_e:nnF {#1} + { + { U } { \fp_eval:n { 6.42 * (#2) } } % Scope UNCHANGED + { C } { \fp_eval:n { 7.52 * ( (#2) - 0.029 ) - 3.25 * ( (#2) - 0.02 )^15 } } % Scope CHANGED + } + { \msg_error:nnxxx { CVSS } { invalid-option } { calcISC } {#1} {\msg_line_context:} } +}% +\cs_new:Npn \__CVSS_calcExploitability:nnnnn #1#2#3#4#5 +{ + % #1 Attack Vector + % #2 Attack Complexity + % #3 Privileges Required + % #4 User Interaction + % #5 Scope + % 8.22 × AttackVector × AttackComplexity × PrivilegeRequired × UserInteraction + 8.22 * (\__CVSS_parseAV:n {#1}) * (\__CVSS_parseAC:n {#2}) * (\__CVSS_parsePR:nn {#3}{#5}) * (\__CVSS_parseUI:n {#4})% +} +\cs_new:Npn \__CVSS_cvssBaseScore:nnnnnnnn #1#2#3#4#5#6#7#8 { + % #1 Attack Vector %Network N, Adjacent A, Local L, Physical P + % #2 Attack Complexity %Low L, High H + % #3 Privileges Required %None N, Low L, High H + % #4 User Interaction %None N, Required R + % #5 Scope %Unchanged U, Changed C + % #6 Confidentiality Impact %High H, Low L, None N + % #7 Integrity Impact %High H, Low L, None N + % #8 Availability Impact %High H, Low L, None N + % + \fp_compare:nTF { \exp_args:Ne \__CVSS_calcImpact:nn {#5}{\exp_args:Ne \__CVSS_calcISS:nnn {#6}{#7}{#8}} <= 0 } + % IF ISC <=0 + { + % ISC <=0 + 0.0 + }{ + % ISC > 0 + \str_case_e:nnF {#5} + { + { U } { % SCOPE UNCHANGED + \fp_eval:n { \__CVSS_roundup:n { min( ((\__CVSS_calcImpact:nn {#5}{\__CVSS_calcISS:nnn {#6}{#7}{#8}}) + (\__CVSS_calcExploitability:nnnnn {#1}{#2}{#3}{#4}{#5})), 10) } }% + } + { C } { % SCOPE CHANGED + \fp_eval:n { \__CVSS_roundup:n { min( (1.08 * ((\__CVSS_calcImpact:nn {#5}{\__CVSS_calcISS:nnn {#6}{#7}{#8}}) + (\__CVSS_calcExploitability:nnnnn {#1}{#2}{#3}{#4}{#5}))), 10) } }% + } + } + { \msg_error:nnxxx { CVSS } { invalid-option } { parseScope } {#1} {\msg_line_context:} } + }% +} +\NewExpandableDocumentCommand \cvssScore { m }{% + + % Check that there are 35 chars + \int_compare:nNnTF { \str_count_ignore_spaces:n {#1} } = {35}{}{ + \msg_error:nnxx{CVSS}{invalid-length}{#1}{\msg_line_context:} + } + % Check AV value + \str_if_eq:eeTF {\str_range:nnn {#1} {1} {3}} {AV:} + {} { + \msg_error:nnxxx{CVSS}{invalid-structure}{AV}{\str_range:nnn {#1} {1} {3}}{\msg_line_context:} + } + + % Check AC value + \str_if_eq:eeTF {\str_range:nnn {#1} {5} {8}} {/AC:} + {} { + \msg_error:nnxxx{CVSS}{invalid-structure}{AC}{\str_range:nnn {#1} {5} {8}}{\msg_line_context:} + } + + % Check PR value + \str_if_eq:eeTF {\str_range:nnn {#1} {10} {13}} {/PR:} + {} { + \msg_error:nnxxx{CVSS}{invalid-structure}{PR}{\str_range:nnn {#1} {10} {13}}{\msg_line_context:} + } + + % Check UI value + \str_if_eq:eeTF {\str_range:nnn {#1} {15} {18}} {/UI:} + {} { + \msg_error:nnxxx{CVSS}{invalid-structure}{UI}{\str_range:nnn {#1} {15} {18}}{\msg_line_context:} + } + + % Check S value + \str_if_eq:eeTF {\str_range:nnn {#1} {20} {22}} {/S:} + {} { + \msg_error:nnxxx{CVSS}{invalid-structure}{S}{\str_range:nnn {#1} {20} {22}}{\msg_line_context:} + } + + % Check I value + \str_if_eq:eeTF {\str_range:nnn {#1} {24} {26}} {/C:} + {} { + \msg_error:nnxxx{CVSS}{invalid-structure}{C}{\str_range:nnn {#1} {24} {26}}{\msg_line_context:} + } + + % Check I value + \str_if_eq:eeTF {\str_range:nnn {#1} {28} {30}} {/I:} + {} { + \msg_error:nnxxx{CVSS}{invalid-structure}{I}{\str_range:nnn {#1} {28} {30}}{\msg_line_context:} + } + + % Check A value + \str_if_eq:eeTF {\str_range:nnn {#1} {32} {34}} {/A:} + {} { + \msg_error:nnxxx{CVSS}{invalid-structure}{A}{\str_range:nnn {#1} {32} {34}}{\msg_line_context:} + } + + \exp_args:Ne \__CVSS_cvssBaseScore:nnnnnnnn + { \str_use:N \str_item_ignore_spaces:nn { #1 }{ 4 } } + { \str_use:N \str_item_ignore_spaces:nn { #1 }{ 9 } } + { \str_use:N \str_item_ignore_spaces:nn { #1 }{ 14 } } + { \str_use:N \str_item_ignore_spaces:nn { #1 }{ 19 } } + { \str_use:N \str_item_ignore_spaces:nn { #1 }{ 23 } } + { \str_use:N \str_item_ignore_spaces:nn { #1 }{ 27 } } + { \str_use:N \str_item_ignore_spaces:nn { #1 }{ 31 } } + { \str_use:N \str_item_ignore_spaces:nn { #1 }{ 35 } } + +}% +\ExplSyntaxOff +\ExplSyntaxOn +\NewExpandableDocumentCommand \category { m }{% + \fp_compare:nNnTF {#1}<{\scoreLow}{None} + { + \fp_compare:nNnTF{#1}<{\scoreMed}{Low} + { + \fp_compare:nNnTF{#1}<{\scoreHigh}{Medium} + { + \fp_compare:nNnTF{#1}<{\scoreCrit}{High} + {Critical} + }% + }% + }% +}% +\ExplSyntaxOff +\newcommand{\cvssScorepretty}[1]{% + \def\CVSScategory{\category{\cvssScore{#1}}}% + \textcolor{color@cvss@\CVSScategory}{\cvssScore{#1}}% +}% +\newcommand{\cvssLevel}[1]{% + \def\CVSSscore{\cvssScore{#1}}% + \category{\CVSSscore}% +}% +\newcommand{\cvssLevelpretty}[1]{% + \def\CVSScategory{\category{\cvssScore{#1}}}% + \textcolor{color@cvss@\CVSScategory}{\CVSScategory}% +}% +\DeclareTotalTCBox{\cvssFrame}{m}{ + enhanced,nobeforeafter, + tcbox raise base, + boxrule=0.4pt, + top=0mm,bottom=0mm,right=1mm,left=1mm, + arc=1pt, + boxsep=2pt, + colframe=color@cvss@#1, + colback=tcbcolframe, + coltext=black, +}{#1}% + +\MakeRobust\cvssFrame +\newcommand{\cvssTag}[1]{% + \def\CVSSscore{\cvssScore{#1}}% + \cvssFrame{\category{\CVSSscore}}% +}% +\newcommand{\cvssPrint}[1]{% + \def\CVSSscore{\cvssScore{#1}} + \cvssFrame{\category{\CVSSscore}} \quad \CVSSscore \quad% + \href{https://www.first.org/cvss/calculator/3.1\#CVSS:3.1/#1}{CVSS:3.1/#1} +}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Copyright (C) 2022 by Pierre VIVEGNIS <pierre@vivegnis.be> +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License (LPPL), either +%% version 1.3c of this license or (at your option) any later +%% version. The latest version of this license is in the file: +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This work is "maintained" (as per LPPL maintenance status) by +%% Pierre VIVEGNIS. +%% +%% This work consists of the file cvss.dtx +%% and the derived files cvss.ins, +%% cvss.pdf and +%% cvss.sty. +%% +%% +%% End of file `cvss.ins'. |