1 /*
2 * ModSecurity, http://www.modsecurity.org/
3 * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
4 *
5 * You may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * If any of the files related to licensing are missing or if you have any
11 * other questions related to licensing please contact Trustwave Holdings, Inc.
12 * directly using the email address security@modsecurity.org.
13 *
14 */
15
16 #include "src/operators/verify_cpf.h"
17
18 #include <string>
19 #include <list>
20
21 #include "src/operators/operator.h"
22
23 namespace modsecurity {
24 namespace operators {
25
convert_to_int(const char c)26 int VerifyCPF::convert_to_int(const char c) {
27 int n;
28 if ((c >= '0') && (c <= '9')) {
29 n = c - '0';
30 } else if ((c >= 'A') && (c <= 'F')) {
31 n = c - 'A' + 10;
32 } else if ((c >= 'a') && (c <= 'f')) {
33 n = c - 'a' + 10;
34 } else {
35 n = 0;
36 }
37 return n;
38 }
39
40
verify(const char * cpfnumber,int len)41 bool VerifyCPF::verify(const char *cpfnumber, int len) {
42 int factor, part_1, part_2, var_len = len;
43 unsigned int sum = 0, i = 0, cpf_len = 11, c;
44 int cpf[11];
45 char s_cpf[11];
46
47 while ((*cpfnumber != '\0') && (var_len > 0)) {
48 // Always true.
49 //if (*cpfnumber != '-' || *cpfnumber != '.') {
50 if (i < cpf_len && isdigit(*cpfnumber)) {
51 s_cpf[i] = *cpfnumber;
52 cpf[i] = convert_to_int(*cpfnumber);
53 i++;
54 }
55 //}
56 cpfnumber++;
57 var_len--;
58 }
59
60
61 if (i != cpf_len) {
62 return 0;
63 } else {
64 for (i = 0; i< cpf_len; i++) {
65 if (strncmp(s_cpf, bad_cpf[i], cpf_len) == 0) {
66 return 0;
67 }
68 }
69 }
70
71 part_1 = convert_to_int(s_cpf[cpf_len-2]);
72 part_2 = convert_to_int(s_cpf[cpf_len-1]);
73
74 c = cpf_len;
75
76 for (i = 0; i < 9; i++) {
77 sum += (cpf[i] * --c);
78 }
79
80 factor = (sum % cpf_len);
81
82 if (factor < 2) {
83 cpf[9] = 0;
84 } else {
85 cpf[9] = cpf_len-factor;
86 }
87
88 sum = 0;
89 c = cpf_len;
90
91 for (i = 0; i < 10; i++) {
92 sum += (cpf[i] * c--);
93 }
94
95 factor = (sum % cpf_len);
96
97 if (factor < 2) {
98 cpf[10] = 0;
99 } else {
100 cpf[10] = cpf_len-factor;
101 }
102
103 if (part_1 == cpf[9] && part_2 == cpf[10]) {
104 return true;
105 }
106
107 return false;
108 }
109
110
evaluate(Transaction * t,RuleWithActions * rule,const std::string & input,std::shared_ptr<RuleMessage> ruleMessage)111 bool VerifyCPF::evaluate(Transaction *t, RuleWithActions *rule,
112 const std::string& input, std::shared_ptr<RuleMessage> ruleMessage) {
113 std::list<SMatch> matches;
114 bool is_cpf = false;
115 int i;
116
117 if (m_param.empty()) {
118 return false;
119 }
120
121 for (i = 0; i < input.size() - 1 && is_cpf == false; i++) {
122 matches = m_re->searchAll(input.substr(i, input.size()));
123 for (const auto & m : matches) {
124 is_cpf = verify(m.str().c_str(), m.str().size());
125 if (is_cpf) {
126 logOffset(ruleMessage, m.offset(), m.str().size());
127 if (rule && t && rule->hasCaptureAction()) {
128 t->m_collections.m_tx_collection->storeOrUpdateFirst(
129 "0", m.str());
130 ms_dbg_a(t, 7, "Added VerifyCPF match TX.0: " + \
131 m.str());
132 }
133
134 goto out;
135 }
136 }
137 }
138
139 out:
140 return is_cpf;
141 }
142
143
144 } // namespace operators
145 } // namespace modsecurity
146