Update progress on JCA

This commit is contained in:
Kristen Newbury
2025-02-07 15:46:13 -05:00
parent 2e12bb5f5c
commit 60d931af9f
2 changed files with 136 additions and 58 deletions

View File

@@ -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();
}
}

View File

@@ -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()}
// }
}