-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathRsa.qll
More file actions
173 lines (140 loc) · 5.61 KB
/
Rsa.qll
File metadata and controls
173 lines (140 loc) · 5.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/**
* Provides classes modeling security-relevant aspects of the `rsa` PyPI package.
* See https://stuvel.eu/python-rsa-doc/.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.dataflow.new.TaintTracking
private import semmle.python.Concepts
private import semmle.python.ApiGraphs
/**
* Provides models for the `rsa` PyPI package.
* See https://stuvel.eu/python-rsa-doc/.
*/
private module Rsa {
/**
* A call to `rsa.newkeys`
*
* See https://stuvel.eu/python-rsa-doc/reference.html#rsa.newkeys
*/
class RsaNewkeysCall extends Cryptography::PublicKey::KeyGeneration::RsaRange,
DataFlow::CallCfgNode
{
RsaNewkeysCall() { this = API::moduleImport("rsa").getMember("newkeys").getACall() }
override DataFlow::Node getKeySizeArg() {
result in [this.getArg(0), this.getArgByName("nbits")]
}
}
/**
* A call to `rsa.encrypt`
*
* See https://stuvel.eu/python-rsa-doc/reference.html#rsa.encrypt
*/
class RsaEncryptCall extends Cryptography::CryptographicOperation::Range instanceof DataFlow::CallCfgNode
{
RsaEncryptCall() { this = API::moduleImport("rsa").getMember("encrypt").getACall() }
override DataFlow::Node getInitialization() { result = this }
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.getName() = "RSA" }
override DataFlow::Node getAnInput() {
result in [super.getArg(0), super.getArgByName("message")]
}
override Cryptography::BlockMode getBlockMode() { none() }
}
/**
* A call to `rsa.decrypt`
*
* See https://stuvel.eu/python-rsa-doc/reference.html#rsa.decrypt
*/
class RsaDecryptCall extends Cryptography::CryptographicOperation::Range instanceof DataFlow::CallCfgNode
{
RsaDecryptCall() { this = API::moduleImport("rsa").getMember("decrypt").getACall() }
override DataFlow::Node getInitialization() { result = this }
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.getName() = "RSA" }
override DataFlow::Node getAnInput() {
result in [super.getArg(0), super.getArgByName("crypto")]
}
override Cryptography::BlockMode getBlockMode() { none() }
}
/**
* A call to `rsa.sign`, which both hashes and signs in the input message.
*
* See https://stuvel.eu/python-rsa-doc/reference.html#rsa.sign
*/
class RsaSignCall extends Cryptography::CryptographicOperation::Range instanceof DataFlow::CallCfgNode
{
RsaSignCall() { this = API::moduleImport("rsa").getMember("sign").getACall() }
override DataFlow::Node getInitialization() { result = this }
override Cryptography::CryptographicAlgorithm getAlgorithm() {
// signature part
result.getName() = "RSA"
or
// hashing part
exists(StringLiteral str, DataFlow::Node hashNameArg |
hashNameArg in [super.getArg(2), super.getArgByName("hash_method")] and
DataFlow::exprNode(str) = hashNameArg.getALocalSource() and
result.matchesName(str.getText())
)
}
override DataFlow::Node getAnInput() {
result in [super.getArg(0), super.getArgByName("message")]
}
override Cryptography::BlockMode getBlockMode() { none() }
}
/**
* A call to `rsa.verify`
*
* See https://stuvel.eu/python-rsa-doc/reference.html#rsa.verify
*/
class RsaVerifyCall extends Cryptography::CryptographicOperation::Range instanceof DataFlow::CallCfgNode
{
RsaVerifyCall() { this = API::moduleImport("rsa").getMember("verify").getACall() }
override DataFlow::Node getInitialization() { result = this }
override Cryptography::CryptographicAlgorithm getAlgorithm() {
// note that technically there is also a hashing operation going on but we don't
// know what algorithm is used up front, since it is encoded in the signature
result.getName() = "RSA"
}
override DataFlow::Node getAnInput() {
result in [super.getArg(0), super.getArgByName("message")]
or
result in [super.getArg(1), super.getArgByName("signature")]
}
override Cryptography::BlockMode getBlockMode() { none() }
}
/**
* A call to `rsa.compute_hash`
*
* See https://stuvel.eu/python-rsa-doc/reference.html#rsa.compute_hash
*/
class RsaComputeHashCall extends Cryptography::CryptographicOperation::Range instanceof DataFlow::CallCfgNode
{
RsaComputeHashCall() { this = API::moduleImport("rsa").getMember("compute_hash").getACall() }
override DataFlow::Node getInitialization() { result = this }
override Cryptography::CryptographicAlgorithm getAlgorithm() {
exists(StringLiteral str, DataFlow::Node hashNameArg |
hashNameArg in [super.getArg(1), super.getArgByName("method_name")] and
DataFlow::exprNode(str) = hashNameArg.getALocalSource() and
result.matchesName(str.getText())
)
}
override DataFlow::Node getAnInput() {
result in [super.getArg(0), super.getArgByName("message")]
}
override Cryptography::BlockMode getBlockMode() { none() }
}
/**
* A call to `rsa.sign_hash`
*
* See https://stuvel.eu/python-rsa-doc/reference.html#rsa.sign_hash
*/
class RsaSignHashCall extends Cryptography::CryptographicOperation::Range instanceof DataFlow::CallCfgNode
{
RsaSignHashCall() { this = API::moduleImport("rsa").getMember("sign_hash").getACall() }
override DataFlow::Node getInitialization() { result = this }
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.getName() = "RSA" }
override DataFlow::Node getAnInput() {
result in [super.getArg(0), super.getArgByName("hash_value")]
}
override Cryptography::BlockMode getBlockMode() { none() }
}
}