mirror of
https://github.com/github/codeql.git
synced 2026-04-26 01:05:15 +02:00
Update progress on JCA
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
}
|
||||
|
||||
class UnknownLocation instanceof Location;
|
||||
|
||||
|
||||
}
|
||||
|
||||
module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
@@ -91,6 +93,11 @@
|
||||
* Gets the name of this algorithm, e.g., "AES" or "SHA".
|
||||
*/
|
||||
abstract string getAlgorithmName();
|
||||
|
||||
/**
|
||||
* Gets the raw name of this algorithm from source (no parsing or formatting)
|
||||
*/
|
||||
abstract string getRawAlgorithmName();
|
||||
|
||||
final override string toString() { result = this.getAlgorithmName() }
|
||||
}
|
||||
@@ -148,7 +155,7 @@
|
||||
/**
|
||||
* Gets the raw name of this hash algorithm from source.
|
||||
*/
|
||||
abstract string getRawAlgorithmName();
|
||||
override abstract string getRawAlgorithmName();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,5 +238,90 @@
|
||||
|
||||
override string getOperationName() { result = "ENCRYPTION" }
|
||||
}
|
||||
|
||||
// newtype TBlockCipherFamilyType =
|
||||
// // We're saying by this that all of these have an identical interface / properties / edges
|
||||
// CBC() or ECB()
|
||||
|
||||
|
||||
// abstract class BlockCiper extends Algorithm {
|
||||
|
||||
// abstract string getKeySize(Location location);
|
||||
|
||||
// abstract TBlockCipherFamilyType getBlockCipherFamilyType();
|
||||
|
||||
// override predicate properties(string key, string value, Location location) {
|
||||
// super.properties(key, value, location)
|
||||
// or
|
||||
// key = "key_size" and
|
||||
// if exists(this.getKeySize(location))
|
||||
// then value = this.getKeySize(location)
|
||||
// else (
|
||||
// value instanceof UnknownPropertyValue and location instanceof UnknownLocation
|
||||
// )
|
||||
// // other properties, like field type are possible, but not modeled until considered necessary
|
||||
// }
|
||||
|
||||
// override string getAlgorithmName() { result = this.getRawAlgorithmName().toUpperCase()}
|
||||
|
||||
// override abstract string getRawAlgorithmName();
|
||||
// }
|
||||
|
||||
newtype TModeOperation =
|
||||
ECB() or OtherMode()
|
||||
|
||||
abstract class ModeOfOperation extends Algorithm {
|
||||
string getValue() {result = ""}
|
||||
|
||||
final private predicate modeToNameMapping(TModeOperation type, string name) {
|
||||
type instanceof ECB and name = "ECB"
|
||||
or
|
||||
type instanceof OtherMode and name = this.getRawAlgorithmName()
|
||||
}
|
||||
|
||||
abstract TModeOperation getModeType();
|
||||
|
||||
override string getAlgorithmName() { this.modeToNameMapping(this.getModeType(), result) }
|
||||
|
||||
}
|
||||
|
||||
newtype TCipherStructure =
|
||||
Block() or Stream()
|
||||
|
||||
newtype TSymmetricCipherFamilyType =
|
||||
// We're saying by this that all of these have an identical interface / properties / edges
|
||||
AES()
|
||||
|
||||
/**
|
||||
* Symmetric algorithms
|
||||
*/
|
||||
abstract class SymmetricAlgorithm extends Algorithm {
|
||||
|
||||
|
||||
abstract TSymmetricCipherFamilyType getSymmetricCipherFamilyType();
|
||||
|
||||
abstract string getKeySize(Location location);
|
||||
|
||||
abstract TCipherStructure getCipherType();
|
||||
|
||||
|
||||
//mode, padding scheme, keysize, block/stream, auth'd
|
||||
//nodes = mode, padding scheme
|
||||
//properties = keysize, block/stream, auth'd
|
||||
//leave authd to lang specific
|
||||
override predicate properties(string key, string value, Location location) {
|
||||
super.properties(key, value, location)
|
||||
or
|
||||
key = "key_size" and
|
||||
if exists(this.getKeySize(location))
|
||||
then value = this.getKeySize(location)
|
||||
else (
|
||||
value instanceof UnknownPropertyValue and location instanceof UnknownLocation
|
||||
)
|
||||
//add more keys to index props
|
||||
}
|
||||
|
||||
abstract ModeOfOperation getModeOfOperation();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,41 +14,6 @@ predicate cipher_modes(string mode) {mode = ["NONE", "CBC", "CCM", "CFB", "CFBx"
|
||||
predicate cipher_padding(string padding) {padding = ["NoPadding", "ISO10126Padding", "OAEPPadding", "OAEPWith", "PKCS1Padding", "PKCS5Padding", "SSL3Padding"]}
|
||||
|
||||
|
||||
abstract class BlockCiper extends Crypto::Algorithm {
|
||||
CipherAlgorithmStringLiteral alg;
|
||||
CipherAlgorithmMode mode;
|
||||
CipherAlgorithmPadding padding;
|
||||
|
||||
|
||||
CipherAlgorithmStringLiteral getAlg() {result = alg }
|
||||
CipherAlgorithmMode getMode() {result = mode }
|
||||
|
||||
CipherAlgorithmPadding getPadding() {result =padding}
|
||||
}
|
||||
/**
|
||||
* Symmetric algorithms
|
||||
*/
|
||||
abstract class SymmetricAlgorithm extends Crypto::Algorithm {
|
||||
|
||||
|
||||
//TODO figure out how to get this from the Cipher interface, is it explicit?
|
||||
//abstract string getKeySize(Location location);
|
||||
|
||||
// override predicate properties(string key, string value, Location location) {
|
||||
// super.properties(key, value, location)
|
||||
// or
|
||||
// key = "key_size" and
|
||||
// if exists(this.getKeySize(location))
|
||||
// then value = this.getKeySize(location)
|
||||
// else (
|
||||
// value instanceof Crypto::UnknownPropertyValue and location instanceof UnknownLocation
|
||||
// )
|
||||
// // other properties, like field type are possible, but not modeled until considered necessary
|
||||
// }
|
||||
|
||||
abstract override string getAlgorithmName();
|
||||
}
|
||||
|
||||
////cipher specifics ----------------------------------------
|
||||
|
||||
class CipherInstance extends Call {
|
||||
@@ -60,24 +25,26 @@ class CipherInstance extends Call {
|
||||
/**
|
||||
* this may be specified either in the ALG/MODE/PADDING or just ALG format
|
||||
*/
|
||||
class CipherAlgorithmStringLiteral extends Crypto::NodeBase instanceof StringLiteral {
|
||||
class CipherAlgorithmStringLiteral extends StringLiteral {
|
||||
CipherAlgorithmStringLiteral() { cipher_names(this.getValue().splitAt("/"))}
|
||||
|
||||
override string toString() { result = this.(StringLiteral).toString() }
|
||||
|
||||
string getValue() { result = this.(StringLiteral).getValue() }
|
||||
}
|
||||
|
||||
abstract class CipherAlgorithmMode extends Crypto::NodeBase {
|
||||
string getValue() {result = ""}
|
||||
}
|
||||
|
||||
class CipherAlgorithmModeStringLiteral extends CipherAlgorithmMode instanceof StringLiteral {
|
||||
CipherAlgorithmModeStringLiteral() { cipher_modes(this.(StringLiteral).getValue().splitAt("/"))}
|
||||
class ModeOfOperationStringLiteral extends Crypto::ModeOfOperation instanceof StringLiteral {
|
||||
ModeOfOperationStringLiteral() { cipher_modes(this.(StringLiteral).getValue().splitAt("/"))}
|
||||
|
||||
override string toString() { result = this.(StringLiteral).toString() }
|
||||
override string getRawAlgorithmName() { result = this.(StringLiteral).getValue().regexpCapture(".*/(.*)/.*",1) }
|
||||
|
||||
override string getValue() { result = this.(StringLiteral).getValue().regexpCapture(".*/(.*)/.*",1) }
|
||||
|
||||
|
||||
predicate modeToNameMapping(Crypto::TModeOperation type, string name) {
|
||||
name = "ECB" and type instanceof Crypto::ECB
|
||||
}
|
||||
|
||||
override Crypto::TModeOperation getModeType(){
|
||||
modeToNameMapping(result, this.getRawAlgorithmName())
|
||||
}
|
||||
}
|
||||
|
||||
abstract class CipherAlgorithmPadding extends Crypto::NodeBase {
|
||||
@@ -102,32 +69,51 @@ abstract class CipherAlgorithmMode extends Crypto::NodeBase {
|
||||
|
||||
module AlgorithmStringToFetchFlow = DataFlow::Global<AlgorithmStringToFetchConfig>;
|
||||
|
||||
predicate algorithmStringToCipherInstanceArgFlow(string name, CipherAlgorithmStringLiteral origin, CipherAlgorithmModeStringLiteral mode, CipherAlgorithmPaddingStringLiteral padding, Expr arg) {
|
||||
predicate algorithmStringToCipherInstanceArgFlow(string name, CipherAlgorithmStringLiteral origin, Expr arg) {
|
||||
exists(CipherInstance sinkCall |
|
||||
origin.getValue().splitAt("/") = name and
|
||||
origin = mode and
|
||||
origin = padding and
|
||||
arg = sinkCall.getAlgorithmArg() and
|
||||
AlgorithmStringToFetchFlow::flow(DataFlow::exprNode(origin), DataFlow::exprNode(arg))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
predicate modeStringToCipherInstanceArgFlow(string name, ModeOfOperationStringLiteral mode, Expr arg) {
|
||||
exists(CipherInstance sinkCall |
|
||||
mode.getRawAlgorithmName() = name and
|
||||
arg = sinkCall.getAlgorithmArg() and
|
||||
AlgorithmStringToFetchFlow::flow(DataFlow::exprNode(mode), DataFlow::exprNode(arg))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A class to represent when AES is used AND it has literal mode and padding provided
|
||||
* this does not capture the use without
|
||||
*/
|
||||
class AESLiteral extends SymmetricAlgorithm, BlockCiper instanceof Expr {
|
||||
// class AESLiteral extends Crypto::SymmetricAlgorithm instanceof Expr {
|
||||
// CipherAlgorithmStringLiteral alg;
|
||||
// AESLiteral() { algorithmStringToCipherInstanceArgFlow("AES", alg, this)
|
||||
// }
|
||||
|
||||
// override Crypto::ModeOfOperation getModeOfOperation(){ modeStringToCipherInstanceArgFlow(result.getAlgorithmName(), result, this)}
|
||||
|
||||
AESLiteral() { algorithmStringToCipherInstanceArgFlow("AES", alg, mode, padding, this)
|
||||
}
|
||||
// override Crypto::LocatableElement getOrigin(string name) {
|
||||
// result = alg and name = alg.toString()
|
||||
// }
|
||||
|
||||
override Crypto::LocatableElement getOrigin(string name) {
|
||||
result = alg and name = alg.toString()
|
||||
}
|
||||
// override string getAlgorithmName(){ result = "AES" }
|
||||
|
||||
override string getAlgorithmName(){ result = alg.getValue()}
|
||||
}
|
||||
// override string getRawAlgorithmName(){ result = alg.getValue()}
|
||||
|
||||
// override Crypto::TSymmetricCipherFamilyType getSymmetricCipherFamilyType() { result instanceof Crypto::AES}
|
||||
|
||||
// //temp hacks for testing
|
||||
// override string getKeySize(Location location){
|
||||
// result = ""
|
||||
// }
|
||||
|
||||
// override Crypto::TCipherStructure getCipherType(){ none()}
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user