Skip to content

Commit 57f4c9d

Browse files
committed
Refactored algorithm instances
This commit also adds associated elliptic curves to the key generation and key nodes.
1 parent b3edef2 commit 57f4c9d

File tree

5 files changed

+204
-161
lines changed

5 files changed

+204
-161
lines changed

java/ql/lib/experimental/quantum/BouncyCastle.qll

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,24 @@ module Signers {
2424
}
2525

2626
MethodCall getAMethodCall(string name) {
27-
result.getCallee().hasQualifiedName("org.bouncycastle.crypto.signers", this.getName(), name)
27+
result.getCallee().hasQualifiedName(this.getPackage().getName(), this.getName(), name)
2828
}
2929
}
3030

3131
/**
3232
* BouncyCastle algorithms are instantiated by calling the constructor of the
33-
* corresponding class.
33+
* corresponding class, which also represents the algorithm instance.
3434
*/
35-
private class NewCall = SignatureAlgorithmInstance;
35+
private class SignerNewCall = SignatureAlgorithmInstance;
3636

3737
/**
3838
* The type is instantiated by a constructor call and initialized by a call to
3939
* `init()` which takes two arguments. The first argument is a flag indicating
4040
* whether the operation is signing data or verifying a signature, and the
4141
* second is the key to use.
4242
*/
43-
private class InitCall extends MethodCall {
44-
InitCall() { this = any(Signer signer).getAnInitCall() }
43+
private class SignerInitCall extends MethodCall {
44+
SignerInitCall() { this = any(Signer signer).getAnInitCall() }
4545

4646
Expr getForSigningArg() { result = this.getArgument(0) }
4747

@@ -67,8 +67,8 @@ module Signers {
6767
* `generateSignature()` or `verifySignature()` methods are used to produce or
6868
* verify the signature, respectively.
6969
*/
70-
private class UseCall extends MethodCall {
71-
UseCall() { this = any(Signer signer).getAUseCall() }
70+
private class SignerUseCall extends MethodCall {
71+
SignerUseCall() { this = any(Signer signer).getAUseCall() }
7272

7373
predicate isIntermediate() { this.getCallee().getName() = "update" }
7474

@@ -80,13 +80,14 @@ module Signers {
8080
/**
8181
* Instantiate the flow analysis module for the `Signer` class.
8282
*/
83-
private module FlowAnalysis = NewToInitToUseFlowAnalysis<NewCall, InitCall, UseCall>;
83+
private module FlowAnalysis =
84+
NewToInitToUseFlowAnalysis<SignerNewCall, SignerInitCall, SignerUseCall>;
8485

8586
/**
8687
* A signing operation instance is a call to either `update()`, `generateSignature()`,
8788
* or `verifySignature()` on a `Signer` instance.
8889
*/
89-
class SignatureOperationInstance extends Crypto::KeyOperationInstance instanceof UseCall {
90+
class SignatureOperationInstance extends Crypto::KeyOperationInstance instanceof SignerUseCall {
9091
SignatureOperationInstance() { not this.isIntermediate() }
9192

9293
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
@@ -114,9 +115,9 @@ module Signers {
114115
result.asExpr() = super.getOutput()
115116
}
116117

117-
InitCall getInitCall() { result = FlowAnalysis::getInitFromUse(this, _, _) }
118+
SignerInitCall getInitCall() { result = FlowAnalysis::getInitFromUse(this, _, _) }
118119

119-
UseCall getAnUpdateCall() {
120+
SignerUseCall getAnUpdateCall() {
120121
result = FlowAnalysis::getAnIntermediateUseFromFinalUse(this, _, _)
121122
}
122123
}
@@ -150,20 +151,10 @@ module Generators {
150151
MethodCall getAUseCall() { result = this.getAMethodCall(["generateKey", "generateKeyPair"]) }
151152

152153
MethodCall getAMethodCall(string name) {
153-
result
154-
.getCallee()
155-
.hasQualifiedName("org.bouncycastle.crypto.generators", this.getName(), name)
154+
result.getCallee().hasQualifiedName(this.getPackage().getName(), this.getName(), name)
156155
}
157156

158157
Crypto::KeyArtifactType getKeyType() { result = type }
159-
160-
string getRawAlgorithmName() {
161-
this.getKeyType() = Crypto::TSymmetricKeyType() and
162-
result = this.getName().splitAt("KeyGenerator", 0)
163-
or
164-
this.getKeyType() = Crypto::TAsymmetricKeyType() and
165-
result = this.getName().splitAt("KeyPairGenerator", 0)
166-
}
167158
}
168159

169160
/**
@@ -187,7 +178,7 @@ module Generators {
187178

188179
/**
189180
* BouncyCastle algorithms are instantiated by calling the constructor of the
190-
* corresponding class.
181+
* corresponding class, which also represents the algorithm instance.
191182
*/
192183
private class KeyGeneratorNewCall = KeyGenerationAlgorithmInstance;
193184

@@ -250,10 +241,15 @@ module Generators {
250241
result = KeyGeneratorFlow::getInitFromUse(this, _, _).getKeySizeConsumer()
251242
}
252243
}
244+
}
253245

246+
/**
247+
* Models for cryptographic parameters defined by the `org.bouncycastle.crypto.params` package.
248+
*/
249+
module Parameters {
254250
class KeyGenerationParameters extends RefType {
255251
KeyGenerationParameters() {
256-
this.getPackage().getName() = "org.bouncycastle.crypto.generators" and
252+
this.getPackage().getName() = "org.bouncycastle.crypto.params" and
257253
this.getName().matches("%KeyGenerationParameters")
258254
}
259255
}
Lines changed: 158 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,160 @@
11
import java
22
import experimental.quantum.Language
3-
import AlgorithmInstances.SignatureAlgorithmInstances
4-
import AlgorithmInstances.KeyGenerationAlgorithmInstance
3+
import AlgorithmValueConsumers
4+
5+
abstract private class EllipticCurveAlgorithmInstance extends Crypto::EllipticCurveInstance,
6+
EllipticCurveAlgorithmValueConsumer
7+
{
8+
override Crypto::TEllipticCurveType getEllipticCurveType() {
9+
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getRawEllipticCurveName(), _, result)
10+
}
11+
12+
override string getKeySize() {
13+
exists(int keySize |
14+
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getRawEllipticCurveName(), keySize, _) and
15+
result = keySize.toString()
16+
)
17+
}
18+
}
19+
20+
/**
21+
* Signature algorithms.
22+
*/
23+
abstract class SignatureAlgorithmInstance extends Crypto::KeyOperationAlgorithmInstance,
24+
SignatureAlgorithmValueConsumer instanceof ClassInstanceExpr
25+
{
26+
// TODO: Could potentially be used to model signature modes like Ed25519ph and Ed25519ctx.
27+
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() }
28+
29+
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
30+
31+
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { none() }
32+
33+
override Crypto::KeyOpAlg::Algorithm getAlgorithmType() {
34+
signatureNameToKeySizeAndAlgorithmMapping(this.getRawAlgorithmName(), _, result)
35+
}
36+
37+
override string getKeySizeFixed() {
38+
signatureNameToKeySizeAndAlgorithmMapping(this.getRawAlgorithmName(), result, _)
39+
}
40+
41+
override string getRawAlgorithmName() {
42+
typeNameToRawAlgorithmName(super.getConstructedType().getName(), result)
43+
}
44+
}
45+
46+
abstract private class EllipticCurveSignatureAlgorithmInstance extends SignatureAlgorithmInstance,
47+
EllipticCurveAlgorithmInstance
48+
{ }
49+
50+
class Ed25519SignatureAlgorithmInstance extends EllipticCurveSignatureAlgorithmInstance instanceof ClassInstanceExpr
51+
{
52+
Ed25519SignatureAlgorithmInstance() {
53+
super.getConstructedType() instanceof Signers::Signer and
54+
super.getConstructedType().getName().matches("Ed25519%")
55+
}
56+
57+
override string getRawEllipticCurveName() { result = "CURVE25519" }
58+
}
59+
60+
class Ed448SignatureAlgorithmInstance extends EllipticCurveSignatureAlgorithmInstance instanceof ClassInstanceExpr
61+
{
62+
Ed448SignatureAlgorithmInstance() {
63+
super.getConstructedType() instanceof Signers::Signer and
64+
super.getConstructedType().getName().matches("Ed448%")
65+
}
66+
67+
override string getRawAlgorithmName() {
68+
typeNameToRawAlgorithmName(super.getConstructedType().getName(), result)
69+
}
70+
71+
override string getRawEllipticCurveName() { result = "CURVE448" }
72+
}
73+
74+
/**
75+
* Key generation algorithms.
76+
*/
77+
abstract class KeyGenerationAlgorithmInstance extends Crypto::KeyOperationAlgorithmInstance,
78+
KeyGenerationAlgorithmValueConsumer instanceof ClassInstanceExpr
79+
{
80+
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() }
81+
82+
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
83+
84+
// TODO: Model flow from the parameter specification to the key generator.
85+
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { none() }
86+
87+
override Crypto::KeyOpAlg::Algorithm getAlgorithmType() {
88+
generatorNameToKeySizeAndAlgorithmMapping(this.getRawAlgorithmName(), _, result)
89+
}
90+
91+
override string getKeySizeFixed() {
92+
generatorNameToKeySizeAndAlgorithmMapping(this.getRawAlgorithmName(), result, _)
93+
}
94+
95+
override string getRawAlgorithmName() {
96+
typeNameToRawAlgorithmName(super.getConstructedType().getName(), result)
97+
}
98+
}
99+
100+
abstract private class EllipticCurveKeyGenerationAlgorithmInstance extends KeyGenerationAlgorithmInstance,
101+
EllipticCurveAlgorithmInstance
102+
{ }
103+
104+
class Ed25519KeyGenerationAlgorithmInstance extends EllipticCurveKeyGenerationAlgorithmInstance instanceof ClassInstanceExpr
105+
{
106+
Ed25519KeyGenerationAlgorithmInstance() {
107+
super.getConstructedType() instanceof Generators::KeyGenerator and
108+
super.getConstructedType().getName().matches("Ed25519%")
109+
}
110+
111+
override string getRawEllipticCurveName() { result = "CURVE25519" }
112+
}
113+
114+
class Ed448KeyGenerationAlgorithmInstance extends EllipticCurveKeyGenerationAlgorithmInstance instanceof ClassInstanceExpr
115+
{
116+
Ed448KeyGenerationAlgorithmInstance() {
117+
super.getConstructedType() instanceof Generators::KeyGenerator and
118+
super.getConstructedType().getName().matches("Ed448%")
119+
}
120+
121+
override string getRawEllipticCurveName() { result = "CURVE25519" }
122+
}
123+
124+
/**
125+
* Private predicates mapping type names to raw names, key sizes and algorithms.
126+
*/
127+
bindingset[typeName]
128+
private predicate typeNameToRawAlgorithmName(string typeName, string algorithmName) {
129+
// Ed25519, Ed25519ph, and Ed25519ctx key generators and signers
130+
typeName.matches("Ed25519%") and
131+
algorithmName = "ED25519"
132+
or
133+
// Ed448 and Ed448ph key generators and signers
134+
typeName.matches("Ed448%") and
135+
algorithmName = "ED448"
136+
}
137+
138+
private predicate signatureNameToKeySizeAndAlgorithmMapping(
139+
string name, string keySize, Crypto::KeyOpAlg::Algorithm algorithm
140+
) {
141+
name = "ED25519" and
142+
keySize = "256" and
143+
algorithm = Crypto::KeyOpAlg::TSignature(Crypto::KeyOpAlg::Ed25519())
144+
or
145+
name = "ED448" and
146+
keySize = "448" and
147+
algorithm = Crypto::KeyOpAlg::TSignature(Crypto::KeyOpAlg::Ed448())
148+
}
149+
150+
private predicate generatorNameToKeySizeAndAlgorithmMapping(
151+
string name, string keySize, Crypto::KeyOpAlg::Algorithm algorithm
152+
) {
153+
name = "ED25519" and
154+
keySize = "256" and
155+
algorithm = Crypto::KeyOpAlg::TSignature(Crypto::KeyOpAlg::Ed25519())
156+
or
157+
name = "ED448" and
158+
keySize = "448" and
159+
algorithm = Crypto::KeyOpAlg::TSignature(Crypto::KeyOpAlg::Ed448())
160+
}

java/ql/lib/experimental/quantum/BouncyCastle/AlgorithmInstances/KeyGenerationAlgorithmInstance.qll

Lines changed: 0 additions & 85 deletions
This file was deleted.

0 commit comments

Comments
 (0)