Skip to content

Commit d49efef

Browse files
committed
Crypto: Fix for non-monotonic recursion in JCA
1 parent 92dac03 commit d49efef

File tree

1 file changed

+57
-21
lines changed
  • java/ql/lib/experimental/quantum

1 file changed

+57
-21
lines changed

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

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -119,15 +119,15 @@ module JCAModel {
119119

120120
bindingset[name]
121121
Crypto::HashType hash_name_to_type_known(string name, int digestLength) {
122-
name = "SHA-1" and result instanceof Crypto::SHA1 and digestLength = 160
122+
name in ["SHA-1", "SHA1"] and result instanceof Crypto::SHA1 and digestLength = 160
123123
or
124-
name = ["SHA-256", "SHA-384", "SHA-512"] and
124+
name in ["SHA-256", "SHA-384", "SHA-512", "SHA256", "SHA384", "SHA512"] and
125125
result instanceof Crypto::SHA2 and
126-
digestLength = name.splitAt("-", 1).toInt()
126+
digestLength = name.replaceAll("-", "").splitAt("SHA", 1).toInt()
127127
or
128-
name = ["SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512"] and
128+
name in ["SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512", "SHA3256", "SHA3384", "SHA3512"] and
129129
result instanceof Crypto::SHA3 and
130-
digestLength = name.splitAt("-", 1).toInt()
130+
digestLength = name.replaceAll("-", "").splitAt("SHA3", 1).toInt()
131131
or
132132
(
133133
name.matches("BLAKE2b%") and
@@ -1222,37 +1222,73 @@ module JCAModel {
12221222
SecretKeyFactoryKDFAlgorithmValueConsumer getConsumer() { result = consumer }
12231223
}
12241224

1225-
class Pbkdf2AlgorithmStringLiteral extends KdfAlgorithmStringLiteral,
1226-
Crypto::Pbkdf2AlgorithmInstance, Crypto::HmacAlgorithmInstance, Crypto::HashAlgorithmInstance,
1227-
Crypto::AlgorithmValueConsumer
1225+
class PBKDF2WithHmac_KeyOperationAlgorithmStringLiteral extends Crypto::KeyOperationAlgorithmInstance instanceof KdfAlgorithmStringLiteral
12281226
{
1229-
Pbkdf2AlgorithmStringLiteral() { super.getKdfType() instanceof Crypto::PBKDF2 }
1230-
1231-
override Crypto::ConsumerInputDataFlowNode getInputNode() { none() }
1227+
PBKDF2WithHmac_KeyOperationAlgorithmStringLiteral() {
1228+
this.(StringLiteral).getValue().toUpperCase().matches(["PBKDF2WithHmac%"].toUpperCase())
1229+
}
12321230

1233-
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() { result = this }
1231+
override Crypto::KeyOpAlg::AlgorithmType getAlgorithmType() {
1232+
result = KeyOpAlg::TMac(KeyOpAlg::HMAC())
1233+
}
12341234

1235-
override Crypto::THashType getHashFamily() {
1236-
result = hash_name_to_type_known(this.getRawHashAlgorithmName(), _)
1235+
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() {
1236+
// TODO: trace to any key size initializer?
1237+
none()
12371238
}
12381239

1239-
override int getFixedDigestLength() {
1240-
exists(hash_name_to_type_known(this.getRawHashAlgorithmName(), result))
1240+
override int getKeySizeFixed() {
1241+
// TODO: are there known fixed key sizes to consider?
1242+
none()
12411243
}
12421244

1243-
override string getRawMacAlgorithmName() {
1244-
result = super.getRawKdfAlgorithmName().splitAt("PBKDF2With", 1)
1245+
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() }
1246+
1247+
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
1248+
1249+
override string getRawAlgorithmName() {
1250+
// Note: hardcoding "hmac" since that should be the only option
1251+
result = "Hmac"
12451252
}
1253+
}
12461254

1247-
override string getRawHashAlgorithmName() {
1248-
result = super.getRawKdfAlgorithmName().splitAt("WithHmac", 1)
1255+
class PBKDF2WithHmac_HashAlgorithmStringLiteral extends Crypto::HashAlgorithmInstance instanceof PBKDF2WithHmac_KeyOperationAlgorithmStringLiteral
1256+
{
1257+
string hashName;
1258+
1259+
PBKDF2WithHmac_HashAlgorithmStringLiteral() {
1260+
hashName = this.(StringLiteral).getValue().splitAt("WithHmac", 1)
12491261
}
12501262

1251-
override Crypto::MacType getMacType() { result = Crypto::HMAC() }
1263+
override string getRawHashAlgorithmName() { result = this.(StringLiteral).getValue() }
1264+
1265+
override Crypto::THashType getHashFamily() { result = hash_name_to_type_known(hashName, _) }
1266+
1267+
override int getFixedDigestLength() { exists(hash_name_to_type_known(hashName, result)) }
1268+
}
1269+
1270+
//TODO: handle PBE
1271+
class Pbkdf2AlgorithmStringLiteral extends KdfAlgorithmStringLiteral,
1272+
Crypto::Pbkdf2AlgorithmInstance, Crypto::HmacAlgorithmInstance
1273+
{
1274+
Pbkdf2AlgorithmStringLiteral() { super.getKdfType() instanceof Crypto::PBKDF2 }
12521275

12531276
override Crypto::AlgorithmValueConsumer getHmacAlgorithmValueConsumer() { result = this }
12541277

12551278
override Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() { result = this }
1279+
1280+
override int getKeySizeFixed() { none() }
1281+
1282+
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() { none() }
1283+
1284+
override string getRawAlgorithmName() {
1285+
// Note: hard coding "hmac" since that should be the only option
1286+
result = "Hmac"
1287+
}
1288+
1289+
override Crypto::KeyOpAlg::AlgorithmType getAlgorithmType() {
1290+
result = KeyOpAlg::TMac(KeyOpAlg::HMAC())
1291+
}
12561292
}
12571293

12581294
class SecretKeyFactoryKDFAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer instanceof Expr

0 commit comments

Comments
 (0)