-
Florian Lugou authoredFlorian Lugou authored
AvatarPragma.java 20.87 KiB
/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
*
* ludovic.apvrille AT enst.fr
*
* This software is a computer program whose purpose is to allow the
* edition of TURTLE analysis, design and deployment diagrams, to
* allow the generation of RT-LOTOS or Java code from this diagram,
* and at last to allow the analysis of formal validation traces
* obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
* from INRIA Rhone-Alpes.
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*/
package avatartranslator;
import myutil.TraceManager;
import ui.TAttribute;
import ui.avatarbd.AvatarBDPragma;
import java.util.*;
/**
* Class AvatarPragma
* Creation: 20/05/2010
* @version 1.1 01/07/2014
* @author Ludovic APVRILLE, Raja GATGOUT
*/
public abstract class AvatarPragma extends AvatarElement implements Comparable<AvatarPragma> {
public static final String[] PRAGMAS = {"Confidentiality", "Secret", "SecrecyAssumption", "InitialSystemKnowledge", "InitialSessionKnowledge", "Authenticity", "PrivatePublicKeys", "Public", "PublicConstant", "PrivateConstant"};
public static final String[] PRAGMAS_TRANSLATION = {"Secret", "Secret", "SecrecyAssumption", "InitialSystemKnowledge", "InitialSessionKnowledge", "Authenticity", "PrivatePublicKeys", "Public", "PublicConstant", "PrivateConstant"};
private int proofStatus = 0;
public AvatarPragma(String _name, Object _referenceObject) {
super(_name, _referenceObject);
}
public int getProofStatus(){
return proofStatus;
}
public void setProofStatus(int status){
proofStatus = status;
}
public static List<AvatarPragma> createFromString(String str, Object obj, List<AvatarBlock> blocks, Map<String, List<TAttribute>> typeAttributesMap, Map<String, String> nameTypeMap, ErrorAccumulator errorAcc){
//createFromString takes in a pragma string (with # removed), the containing object, and the list of AvatarBlocks, and returns the corresponding AvatarPragma or null if an error occurred
//The attributes referenced must exist
List<AvatarPragma> pragmas = new LinkedList<AvatarPragma>();
AvatarBDPragma pragmaObj = (AvatarBDPragma) obj;
//Remove leading spaces
str = str.trim();
String[] split = str.split("\\s+");
if (split.length < 2) {
// One word is not enough
return pragmas;
}
String header = split[0];
String[] args = Arrays.copyOfRange(split, 1, split.length);
if (header.equals("Authenticity")){
if (args.length != 2){
TraceManager.addDev("Wrong number of attributes for Authenticity Pragma " + str);
errorAcc.addWarning("Wrong number of attributes for Authenticity Pragma " + str);
pragmaObj.syntaxErrors.add("#" +str);
return pragmas;
}
String[] split1 = args[0].split("\\.");
String[] split2 = args[1].split("\\.");
// Must be blockName.stateName.attributeName
if (split1.length != 3 || split2.length != 3){
TraceManager.addDev("Badly Formatted Pragma Attribute "+ str);
errorAcc.addWarning("Badly Formatted Pragma Attribute "+ str);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
String blockName1 = split1[0];
String blockName2 = split2[0];
String attrName1 = split1[2];
String attrName2 = split2[2];
if (!nameTypeMap.containsKey(blockName1+"."+attrName1) && !nameTypeMap.containsKey(blockName2+"."+attrName2)){
//Not composed types
LinkedList<AvatarAttributeState> attrStates = new LinkedList<AvatarAttributeState>();
for (String arg: args){
AvatarAttributeState res = parseAuthAttr(arg, blocks);
if (res ==null){
TraceManager.addDev("Can't find Pragma Attribute " + arg);
errorAcc.addWarning("Can't find Pragma Attribute " + arg);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
attrStates.add(res);
}
//Check if same type
if (attrStates.get(0).getAttribute().getType() != attrStates.get(1).getAttribute().getType()){
TraceManager.addDev("Incompatible types "+ str);
errorAcc.addWarning("Incompatible types "+ str);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
pragmas.add(new AvatarPragmaAuthenticity(str, obj, attrStates));
return pragmas;
} else if (!nameTypeMap.containsKey(blockName1+"."+attrName1) && nameTypeMap.containsKey(blockName2+"."+attrName2) || nameTypeMap.containsKey(blockName1+"."+attrName1) && !nameTypeMap.containsKey(blockName2+"."+attrName2)){
//1 composed type, 1 not
TraceManager.addDev("Incompatible types " + str);
errorAcc.addWarning("Incompatible types " + str);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
} else {
//Yay composed types
if (!nameTypeMap.get(blockName1+"."+attrName1).equals(nameTypeMap.get(blockName2+"."+attrName2))){
//Different types
TraceManager.addDev("Incompatible types " + str);
errorAcc.addWarning("Incompatible types " + str);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
//Generate a fun lot of pragmas...
//For each attribute, generate an authenticity pragma
List<TAttribute> typeAttrs = typeAttributesMap.get(nameTypeMap.get(blockName1+"."+attrName1));
for (TAttribute ta: typeAttrs) {
List<AvatarAttributeState> attrStates = new LinkedList<AvatarAttributeState>();
String suffix = ta.getId();
for (String arg: args){
AvatarAttributeState res = parseAuthAttr(arg+"__"+suffix, blocks);
if (res ==null){
TraceManager.addDev("Can't find Pragma Attribute " + arg+"__"+suffix);
errorAcc.addWarning("Can't find Pragma Attribute " + arg+"__"+suffix);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
attrStates.add(res);
}
pragmas.add(new AvatarPragmaAuthenticity(str, obj, attrStates));
}
return pragmas;
}
}
else if (header.equals("PrivateConstant")){
LinkedList<AvatarConstant> constants = new LinkedList<AvatarConstant>();
for (String arg: args){
if (!AvatarTerm.isValidName (arg)) {
errorAcc.addWarning ("Constant name '" + arg + "' is not valid");
continue;
}
constants.add(new AvatarConstant(arg, obj));
}
pragmas.add(new AvatarPragmaConstant(str, obj, constants, false));
}
else if (header.equals("PublicConstant")){
LinkedList<AvatarConstant> constants = new LinkedList<AvatarConstant>();
for (String arg: args){
if (!AvatarTerm.isValidName (arg)) {
errorAcc.addWarning ("Constant name '" + arg + "' is not valid");
continue;
}
constants.add(new AvatarConstant(arg, obj));
}
pragmas.add(new AvatarPragmaConstant(str, obj, constants, true));
}
else if (header.equals("PrivatePublicKeys")){
LinkedList<AvatarAttribute> attrs = new LinkedList<AvatarAttribute>();
if (args.length != 3){
TraceManager.addDev("Wrong number of attributes for PrivatePublicKeys Pragma " + str);
errorAcc.addWarning ("Wrong number of attributes for PrivatePublicKeys Pragma " + str);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
String blockName = args[0];
String attr1 = args[1];
String attr2 = args[2];
//Check if simple type or has only one field
if (nameTypeMap.containsKey(blockName+"."+attr1)){
//Find # of fields
String type = nameTypeMap.get(blockName+"."+attr1);
if (typeAttributesMap.get(type).size()!=1){
TraceManager.addDev("PrivatePublicKey cannot have more than 1 attribute "+ attr1);
errorAcc.addWarning("PrivatePublicKey cannot have more than 1 attribute "+ attr1);
return pragmas;
}
TAttribute ta = typeAttributesMap.get(type).get (0);
attr1 = attr1+"__"+ta.getId();
}
if (nameTypeMap.containsKey(blockName+"."+attr2)){
//Find # of fields
String type = nameTypeMap.get(blockName+"."+attr2);
if (typeAttributesMap.get(type).size()!=1){
TraceManager.addDev("PrivatePublicKey cannot have more than 1 attribute "+ attr2);
errorAcc.addWarning ("PrivatePublicKey cannot have more than 1 attribute "+ attr2);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
TAttribute ta = typeAttributesMap.get(type).get (0);
attr2 = attr2+"__"+ta.getId();
}
for (String attr: new String[]{attr1, attr2}){
AvatarAttribute res = parseAttr(blockName, attr, blocks);
if (res ==null){
TraceManager.addDev("Can't find Pragma Attribute "+ attr);
errorAcc.addWarning ("Can't find Pragma Attribute "+ attr);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
attrs.add(res);
}
pragmas.add(new AvatarPragmaPrivatePublicKey(str, obj, attrs));
}
else if (header.equals("InitialSystemKnowledge") || header.equals("InitialSessionKnowledge")){
//Check if all types are the same
TreeSet<String> types = new TreeSet<String>();
for (String arg: args){
String[] sp = arg.split("\\.");
// Must be blockName.attributeName
if (sp.length != 2){
TraceManager.addDev("Badly Formatted Pragma Attribute " + str);
errorAcc.addWarning ("Badly Formatted Pragma Attribute " + str);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
String blockName = sp[0];
String attrName = sp[1];
if (nameTypeMap.containsKey(blockName+"."+attrName)){
types.add(nameTypeMap.get(blockName+"."+attrName));
} else {
types.add("base");
}
}
if (types.size()!=1){
TraceManager.addDev("Initial Knowledge Pragma attributes must be same type "+ str);
errorAcc.addWarning ("Initial Knowledge Pragma attributes must be same type "+ str);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
if (types.first().equals("base")){
//Simple type
LinkedList<AvatarAttribute> attrs = new LinkedList<AvatarAttribute>();
for (String arg: args){
String[] sp = arg.split("\\.");
String blockName = sp[0];
String attrName = sp[1];
AvatarAttribute res = parseAttr(blockName, attrName, blocks);
if (res ==null){
TraceManager.addDev("Can't find Pragma Attribute "+ arg);
errorAcc.addWarning ("Can't find Pragma Attribute "+ arg);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
attrs.add(res);
}
//Check if same type
AvatarType type = attrs.get(0).getType();
for (int i =1; i< attrs.size(); i++){
if (type != attrs.get(i).getType()){
TraceManager.addDev("Incompatible types "+ str);
errorAcc.addWarning("Incompatible types "+ str);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
}
pragmas.add(new AvatarPragmaInitialKnowledge(str, obj, attrs, header.equals("InitialSystemKnowledge")));
} else {
List<TAttribute> typeAttrs = typeAttributesMap.get(types.first());
for (TAttribute ta: typeAttrs) {
List<AvatarAttribute> attrs = new LinkedList<AvatarAttribute>();
String suffix = ta.getId();
for (String arg: args){
String[] sp = arg.split("\\.");
String blockName = sp[0];
String attrName = sp[1];
AvatarAttribute res = parseAttr(blockName, attrName+"__"+suffix, blocks);
if (res ==null){
TraceManager.addDev("Can't find Pragma Attribute "+ attrName+"__"+suffix);
errorAcc.addWarning ("Can't find Pragma Attribute "+ attrName+"__"+suffix);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
attrs.add(res);
}
pragmas.add(new AvatarPragmaInitialKnowledge(str, obj, attrs, header.equals("InitialSystemKnowledge")));
}
}
}
else {
LinkedList<AvatarAttribute> attrs = new LinkedList<AvatarAttribute>();
for (String arg: args){
String[] sp = arg.split("\\.");
// Must be blockName.attributeName
if (sp.length != 2){
TraceManager.addDev("Badly Formatted Pragma Attribute "+str);
errorAcc.addWarning ("Badly Formatted Pragma Attribute in '"+str+"'");
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
String blockName = sp[0];
String attrName = sp[1];
if (nameTypeMap.containsKey(blockName+"."+attrName)){
//Composed type, YAY#$%^&*
List<TAttribute> typeAttrs = typeAttributesMap.get(nameTypeMap.get(blockName+"."+attrName));
for (TAttribute ta: typeAttrs) {
String suffix = ta.getId();
AvatarAttribute res = parseAttr(blockName, attrName+"__"+suffix, blocks);
if (res ==null){
TraceManager.addDev("Can't find Pragma Attribute "+ attrName+"__"+suffix);
errorAcc.addWarning ("Can't find Pragma Attribute "+ attrName+"__"+suffix);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
attrs.add(res);
}
} else {
AvatarAttribute res = parseAttr(blockName, attrName, blocks);
if (res ==null){
TraceManager.addDev("Can't find Pragma Attribute "+ arg);
errorAcc.addWarning ("Can't find Pragma Attribute "+ arg);
pragmaObj.syntaxErrors.add("#"+str);
return pragmas;
}
attrs.add(res);
}
}
switch(header){
case "Confidentiality":
for (AvatarAttribute attr: attrs)
pragmas.add(new AvatarPragmaSecret(str, obj, attr));
break;
case "Secret":
for (AvatarAttribute attr: attrs)
pragmas.add(new AvatarPragmaSecret(str, obj, attr));
break;
case "SecrecyAssumption":
pragmas.add(new AvatarPragmaSecrecyAssumption(str, obj, attrs));
break;
case "Public":
pragmas.add(new AvatarPragmaPublic(str, obj, attrs));
break;
default:
TraceManager.addDev("Invalid Pragma Name " + header);
errorAcc.addWarning ("Invalid Pragma Name " + header);
//Invalid pragma
return pragmas;
}
}
return pragmas;
}
public static AvatarAttribute parseAttr(String blockName, String attrName, List<AvatarBlock> blocks){
//Iterate through blocks
for (AvatarBlock block:blocks){
if (block.getName().equals(blockName)){
//If the state is found, find either 'attrName' or 'attrName__data'
return block.getAvatarAttributeWithName(attrName);
}
}
TraceManager.addDev("Pragma Attribute Block not found "+ blockName);
return null;
}
public static AvatarAttributeState parseAuthAttr(String arg, List<AvatarBlock> blocks){
//Iterate through the list of blocks
String[] split = arg.split("\\.");
String blockName = split[0];
String stateName = split[1];
String attrName = split[2];
for (AvatarBlock block:blocks){
if (block.getName().equals(blockName)){
//Check if the state exists
AvatarStateMachine asm = block.getStateMachine();
if (asm.getStateWithName(stateName) !=null){
//If the state is found, find either 'attrName' or 'attrName__data'
AvatarAttribute attr= block.getAvatarAttributeWithName(attrName);
if (attr ==null){
return null;
}
return new AvatarAttributeState(stateName+"."+attrName, attr, attr, asm.getStateWithName(stateName));
}
else {
TraceManager.addDev("Pragma Attribute State not found "+ stateName);
return null;
}
}
}
TraceManager.addDev("Pragma Attribute Block not found");
return null;
}
/**
* Returns a full clone of the pragma.
*
* @param avspec
* The AvatarSpecification that will contain the new pragma. Note that the specification should have already been populated with blocks and attributes.
*
* @return A full clone of the pragma.
*/
public abstract AvatarPragma advancedClone(AvatarSpecification avspec);
@Override
public int compareTo(AvatarPragma b)
{
return this.toString().compareTo(b.toString());
}
}