Rati Gelashvili reported a rare but annoying bug in the hash function handling.
The fix requires a significant reworking of the function handling. This is a first attempt. Conflicts: src/knowledge.c src/knowledge.h Regression test suggests that the Hashfunction fix works.
This commit is contained in:
parent
4a1898db92
commit
7658644295
@ -787,7 +787,7 @@ createDecryptionChain (const Binding b, const int run, const int index,
|
||||
indentDepth++;
|
||||
|
||||
tdecr = keylist->term;
|
||||
tkey = inverseKey (sys->know->inverses, TermKey (tdecr));
|
||||
tkey = inverseKey (sys->know, TermKey (tdecr));
|
||||
smallrun = create_decryptor (tdecr, tkey);
|
||||
{
|
||||
Roledef rddecrypt;
|
||||
|
@ -1101,7 +1101,7 @@ hashfunctions (Tac tcstart)
|
||||
error
|
||||
("Bug in hashfunction generation code. Please contact the authors.\n");
|
||||
}
|
||||
knowledgeAddInverse (sys->know, hfuncs->term, hinvs->term);
|
||||
knowledgeAddInverseKeys (sys->know, hfuncs->term, hinvs->term);
|
||||
hfuncs->term->stype = termlistAdd (NULL, TERM_Function);
|
||||
hinvs->term->stype = termlistAdd (NULL, TERM_Function);
|
||||
hfuncs = hfuncs->next;
|
||||
@ -1157,8 +1157,12 @@ normalDeclaration (Tac tc)
|
||||
knowledgeAddTermlist (sys->know, tacTermlist (tc->t1.tac));
|
||||
break;
|
||||
case TAC_INVERSEKEYS:
|
||||
knowledgeAddInverse (sys->know, tacTerm (tc->t1.tac),
|
||||
tacTerm (tc->t2.tac));
|
||||
knowledgeAddInverseKeys (sys->know, tacTerm (tc->t1.tac),
|
||||
tacTerm (tc->t2.tac));
|
||||
break;
|
||||
case TAC_INVERSEKEYFUNCTIONS:
|
||||
knowledgeAddInverseKeyFunctions (sys->know, tacTerm (tc->t1.tac),
|
||||
tacTerm (tc->t2.tac));
|
||||
break;
|
||||
case TAC_HASHFUNCTION:
|
||||
hashfunctions (tc);
|
||||
@ -1568,8 +1572,14 @@ tacProcess (Tac tc)
|
||||
Term
|
||||
tacTerm (Tac tc)
|
||||
{
|
||||
Term t;
|
||||
|
||||
switch (tc->op)
|
||||
{
|
||||
case TAC_FCALL:
|
||||
t = makeTermEncrypt (tacTerm (tc->t1.tac), tacTerm (tc->t2.tac));
|
||||
t->helper.fcall = true;
|
||||
return t;
|
||||
case TAC_ENCRYPT:
|
||||
return makeTermEncrypt (tacTerm (tc->t1.tac), tacTerm (tc->t2.tac));
|
||||
case TAC_TUPLE:
|
||||
|
@ -96,7 +96,7 @@ isIntruderChoice (const Term t)
|
||||
{
|
||||
// Chosen by intruder
|
||||
// However, if it is a rolename, this is not really what we mean
|
||||
if (!(t->roleVar || isAgentType (t->stype)))
|
||||
if (!(t->helper.roleVar || isAgentType (t->stype)))
|
||||
{
|
||||
// Not a role variable, and chosen by the intruder: that's it
|
||||
return true;
|
||||
@ -187,12 +187,12 @@ explainVariable (Term t)
|
||||
if (realTermVariable (t))
|
||||
{
|
||||
eprintf ("any ");
|
||||
if (t->roleVar)
|
||||
if (t->helper.roleVar)
|
||||
{
|
||||
eprintf ("agent ");
|
||||
}
|
||||
termPrintRemap (t);
|
||||
if (!t->roleVar)
|
||||
if (!t->helper.roleVar)
|
||||
{
|
||||
if (switches.match == 0 && t->stype != NULL)
|
||||
{
|
||||
|
192
src/knowledge.c
192
src/knowledge.c
@ -30,19 +30,10 @@
|
||||
#include "system.h"
|
||||
#include "debug.h"
|
||||
#include "error.h"
|
||||
#include "specialterm.h"
|
||||
|
||||
/*
|
||||
* Knowledge stuff
|
||||
*
|
||||
* Note that a really weird thing is going on involving unpropagated substitutions.
|
||||
* Idea:
|
||||
*
|
||||
* 1. Substitute terms by filling in ->subst.
|
||||
* Now, either:
|
||||
* 2a. Undo this by knowledgeUndo.
|
||||
* 2b. Propagate it, modifying the knowledge beyond repair by knowledgeSubstDo. Now inKnowledge works again.
|
||||
* 2c. inKnowledge/knowledgeSet if something is in the knowledge: this does not consider the substitutions!, and
|
||||
* they now have some overhead.
|
||||
*/
|
||||
|
||||
//! Open knowledge code.
|
||||
@ -81,7 +72,8 @@ emptyKnowledge ()
|
||||
know = makeKnowledge ();
|
||||
know->basic = NULL;
|
||||
know->encrypt = NULL;
|
||||
know->inverses = NULL;
|
||||
know->inversekeys = NULL;
|
||||
know->inversekeyfunctions = NULL;
|
||||
know->vars = NULL;
|
||||
know->publicfunctions = NULL;
|
||||
return know;
|
||||
@ -110,7 +102,8 @@ knowledgeDuplicate (Knowledge know)
|
||||
newknow->basic = termlistShallow (know->basic);
|
||||
newknow->encrypt = termlistShallow (know->encrypt);
|
||||
newknow->vars = termlistShallow (know->vars);
|
||||
newknow->inverses = know->inverses;
|
||||
newknow->inversekeys = know->inversekeys;
|
||||
newknow->inversekeyfunctions = know->inversekeyfunctions;
|
||||
newknow->publicfunctions = termlistShallow (know->publicfunctions);
|
||||
return newknow;
|
||||
}
|
||||
@ -147,7 +140,8 @@ knowledgeDestroy (Knowledge know)
|
||||
termlistDestroy (know->basic);
|
||||
termlistDestroy (know->encrypt);
|
||||
termlistDestroy (know->vars);
|
||||
// termlistDestroy(know->inverses);
|
||||
// termlistDestroy(know->inversekeys);
|
||||
// termlistDestroy(know->inversekeyfunctions);
|
||||
termlistDestroy (know->publicfunctions);
|
||||
free (know);
|
||||
}
|
||||
@ -195,7 +189,7 @@ knowledgeAddTerm (Knowledge know, Term term)
|
||||
}
|
||||
if (term->type == ENCRYPT)
|
||||
{
|
||||
Term invkey = inverseKey (know->inverses, TermKey (term));
|
||||
Term invkey = inverseKey (know, TermKey (term));
|
||||
if (inKnowledge (know, invkey))
|
||||
{
|
||||
/* we can decrypt it */
|
||||
@ -227,7 +221,7 @@ knowledgeSimplify (Knowledge know, Term key)
|
||||
{
|
||||
Termlist tldecrypts = NULL;
|
||||
Termlist scan = know->encrypt;
|
||||
Term invkey = inverseKey (know->inverses, key);
|
||||
Term invkey = inverseKey (know, key);
|
||||
|
||||
while (scan != NULL)
|
||||
{
|
||||
@ -257,6 +251,7 @@ knowledgeAddTermlist (Knowledge know, Termlist tl)
|
||||
|
||||
while (tl != NULL)
|
||||
{
|
||||
// Evil old fashioned code relies on lazy left-to-right parsing. Get rid of it.
|
||||
flag = knowledgeAddTerm (know, tl->term) || flag;
|
||||
tl = tl->next;
|
||||
}
|
||||
@ -265,21 +260,18 @@ knowledgeAddTermlist (Knowledge know, Termlist tl)
|
||||
|
||||
//! Add an inverse pair to the knowledge
|
||||
void
|
||||
knowledgeAddInverse (Knowledge know, Term t1, Term t2)
|
||||
knowledgeAddInverseKeys (Knowledge know, Term t1, Term t2)
|
||||
{
|
||||
know->inverses = termlistAdd (know->inverses, t1);
|
||||
know->inverses = termlistAdd (know->inverses, t2);
|
||||
return;
|
||||
know->inversekeys = termlistAdd (know->inversekeys, t1);
|
||||
know->inversekeys = termlistAdd (know->inversekeys, t2);
|
||||
}
|
||||
|
||||
//! Set an inverse pair list for the knowledge.
|
||||
/**
|
||||
* List pointer is simply copied, so don't delete it later!
|
||||
*/
|
||||
//! Add an inverse pair to the knowledge
|
||||
void
|
||||
knowledgeSetInverses (Knowledge know, Termlist tl)
|
||||
knowledgeAddInverseKeyFunctions (Knowledge know, Term t1, Term t2)
|
||||
{
|
||||
know->inverses = tl;
|
||||
know->inversekeyfunctions = termlistAdd (know->inversekeyfunctions, t1);
|
||||
know->inversekeyfunctions = termlistAdd (know->inversekeyfunctions, t2);
|
||||
}
|
||||
|
||||
//! Is a term a part of the knowledge?
|
||||
@ -341,6 +333,15 @@ knowledgePrint (Knowledge know)
|
||||
eprintf (" [Vars]: ");
|
||||
termlistPrint (know->vars);
|
||||
eprintf ("\n");
|
||||
eprintf (" [Inversekeys]: ");
|
||||
termlistPrint (know->inversekeys);
|
||||
eprintf ("\n");
|
||||
eprintf (" [Inversekeyfunctions]: ");
|
||||
termlistPrint (know->inversekeyfunctions);
|
||||
eprintf ("\n");
|
||||
eprintf (" [Publicfunctions]: ");
|
||||
termlistPrint (know->publicfunctions);
|
||||
eprintf ("\n");
|
||||
}
|
||||
|
||||
//! Print a knowledge set, short version (no newline)
|
||||
@ -368,43 +369,6 @@ knowledgePrintShort (const Knowledge know)
|
||||
}
|
||||
}
|
||||
|
||||
//! Print the inverses list of a knowledge set.
|
||||
void
|
||||
knowledgeInversesPrint (Knowledge know)
|
||||
{
|
||||
Termlist tl;
|
||||
int after = 0;
|
||||
|
||||
if (know == NULL)
|
||||
{
|
||||
eprintf ("Empty knowledge.");
|
||||
return;
|
||||
}
|
||||
|
||||
tl = knowledgeGetInverses (know);
|
||||
if (tl == NULL)
|
||||
{
|
||||
eprintf ("None.");
|
||||
}
|
||||
else
|
||||
{
|
||||
while (tl != NULL && tl->next != NULL)
|
||||
{
|
||||
if (after)
|
||||
{
|
||||
eprintf (",");
|
||||
}
|
||||
eprintf ("(");
|
||||
termPrint (tl->term);
|
||||
eprintf (",");
|
||||
termPrint (tl->next->term);
|
||||
eprintf (")");
|
||||
after = 1;
|
||||
tl = tl->next->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Yield the set of representatives for the knowledge.
|
||||
/**
|
||||
* Note: this is a shallow copy, and needs to be termlistDelete'd.
|
||||
@ -420,17 +384,11 @@ knowledgeSet (const Knowledge know)
|
||||
return termlistConcat (tl1, tl2);
|
||||
}
|
||||
|
||||
//! Get the inverses pointer of the knowledge.
|
||||
/**
|
||||
* Essentially the inverse function of knowledgeSetInverses()
|
||||
*/
|
||||
Termlist
|
||||
knowledgeGetInverses (const Knowledge know)
|
||||
//! Check for elements in the knowledge set
|
||||
int
|
||||
inKnowledgeSet (const Knowledge know, Term t)
|
||||
{
|
||||
if (know == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return know->inverses;
|
||||
return (inTermlist (know->basic, t) || inTermlist (know->encrypt, t));
|
||||
}
|
||||
|
||||
//! check whether any substitutions where made in a knowledge set.
|
||||
@ -457,37 +415,6 @@ knowledgeSubstNeeded (const Knowledge know)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//! Reconstruct a knowledge set.
|
||||
/**
|
||||
* This is useful after e.g. substitutions.
|
||||
* Just rebuilds the knowledge in a new (shallow) copy.
|
||||
*@return The pointer to the new knowledge.
|
||||
*\sa knowledgeSubstNeeded()
|
||||
*/
|
||||
Knowledge
|
||||
knowledgeReconstruction (const Knowledge know)
|
||||
{
|
||||
Knowledge newknow = emptyKnowledge ();
|
||||
|
||||
newknow->inverses = know->inverses;
|
||||
knowledgeAddTermlist (newknow, know->basic);
|
||||
knowledgeAddTermlist (newknow, know->encrypt);
|
||||
return newknow;
|
||||
}
|
||||
|
||||
//! Propagate any substitutions just made.
|
||||
/**
|
||||
* This usually involves reconstruction of the complete knowledge, which is
|
||||
* 'cheaper' than a thorough analysis, so we always make a copy.
|
||||
*\sa knowledgeReconstruction()
|
||||
*/
|
||||
Knowledge
|
||||
knowledgeSubstDo (const Knowledge know)
|
||||
{
|
||||
/* otherwise a copy (for deletion) is returned. */
|
||||
return knowledgeReconstruction (know);
|
||||
}
|
||||
|
||||
//! Add public function
|
||||
void
|
||||
knowledgeAddPublicFunction (const Knowledge know, const Term f)
|
||||
@ -502,3 +429,62 @@ isKnowledgePublicFunction (const Knowledge know, const Term f)
|
||||
{
|
||||
return inTermlist (know->publicfunctions, f);
|
||||
}
|
||||
|
||||
//! Give the inverse key term of a term.
|
||||
/**
|
||||
* Gives a duplicate of the inverse Key of some term (which is used to encrypt something), as is defined
|
||||
* by the termlist, which is a list of key1,key1inv, key2, key2inv, etc...
|
||||
*@param inverses The list of inverses, typically from the knowledge.
|
||||
*@param key Any term of which the inverse will be determined.
|
||||
*@return A pointer to a duplicate of the inverse key term. Use termDelete to remove it.
|
||||
*\sa termDuplicate(), knowledge::inverses
|
||||
*/
|
||||
Term
|
||||
inverseKey (Knowledge know, Term key)
|
||||
{
|
||||
Term f;
|
||||
|
||||
key = deVar (key);
|
||||
|
||||
/* inverse key function? */
|
||||
f = getTermFunction (key);
|
||||
if (f != NULL)
|
||||
{
|
||||
Termlist tl;
|
||||
|
||||
Term funKey (Term orig, Term f)
|
||||
{
|
||||
/* in: f'{op}, f
|
||||
* out: f{op'} */
|
||||
return makeTermFcall (termDuplicate (TermOp (orig)),
|
||||
termDuplicate (f));
|
||||
}
|
||||
|
||||
tl = know->inversekeyfunctions;
|
||||
while (tl != NULL && tl->next != NULL)
|
||||
{
|
||||
if (isTermEqual (TermKey (key), tl->term))
|
||||
return funKey (key, tl->next->term);
|
||||
if (isTermEqual (TermKey (key), tl->next->term))
|
||||
return funKey (key, tl->term);
|
||||
tl = tl->next->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* scanning for a direct inverse */
|
||||
Termlist tl;
|
||||
|
||||
/* scan the list */
|
||||
tl = know->inversekeys;
|
||||
while (tl != NULL && tl->next != NULL)
|
||||
{
|
||||
if (isTermEqual (key, tl->term))
|
||||
return termDuplicate (tl->next->term);
|
||||
if (isTermEqual (key, tl->next->term))
|
||||
return termDuplicate (tl->term);
|
||||
tl = tl->next->next;
|
||||
}
|
||||
}
|
||||
return termDuplicate (key); /* defaults to symmetrical */
|
||||
}
|
||||
|
@ -33,8 +33,10 @@ struct knowledge
|
||||
Termlist basic;
|
||||
//! A list of terms encrypted, such that the inverse is not in the knowledge set.
|
||||
Termlist encrypt;
|
||||
//! List of inverse pairs (thus length of list is even)
|
||||
Termlist inverses;
|
||||
//! List of inverse pairs (thus length of list is even) (add,sub)
|
||||
Termlist inversekeys;
|
||||
//! List of inverse pairs (thus length of list is even) (pk,sk)
|
||||
Termlist inversekeyfunctions;
|
||||
//! List of open variables in the knowledge set.
|
||||
/**
|
||||
* This list is used to determine whether the knowledge needs to be rewritten.
|
||||
@ -42,7 +44,7 @@ struct knowledge
|
||||
* and we need to reconstruct the knowledge set.
|
||||
*/
|
||||
Termlist vars; // special: denotes unsubstituted variables
|
||||
//! A list of public functions
|
||||
//! A list of hash functions
|
||||
Termlist publicfunctions;
|
||||
};
|
||||
|
||||
@ -58,19 +60,19 @@ void knowledgeDelete (Knowledge know);
|
||||
void knowledgeDestroy (Knowledge know);
|
||||
int knowledgeAddTerm (Knowledge know, Term term);
|
||||
int knowledgeAddTermlist (Knowledge know, Termlist tl);
|
||||
void knowledgeAddInverse (Knowledge know, Term t1, Term t2);
|
||||
void knowledgeSetInverses (Knowledge know, Termlist tl);
|
||||
void knowledgeAddInverseKeys (Knowledge know, Term t1, Term t2);
|
||||
void knowledgeAddInverseKeyFunctions (Knowledge know, Term t1, Term t2);
|
||||
int inKnowledgeSet (const Knowledge know, Term t);
|
||||
void knowledgeSimplify (Knowledge know, Term decryptkey);
|
||||
int inKnowledge (const Knowledge know, Term term);
|
||||
void knowledgePrint (Knowledge know);
|
||||
void knowledgePrintShort (const Knowledge know);
|
||||
void knowledgeInversesPrint (Knowledge know);
|
||||
Termlist knowledgeSet (const Knowledge know);
|
||||
Termlist knowledgeGetInverses (const Knowledge know);
|
||||
int knowledgeSubstNeeded (const Knowledge know);
|
||||
Knowledge knowledgeSubstDo (const Knowledge know);
|
||||
void knowledgeAddPublicFunction (const Knowledge know, const Term f);
|
||||
int isKnowledgePublicFunction (const Knowledge know, const Term f);
|
||||
Term inverseKey (Knowledge know, Term key);
|
||||
|
||||
//! Harnass macro for recursive procedures.
|
||||
#define mindwipe(k,recurse) \
|
||||
|
@ -149,9 +149,6 @@ main (int argc, char **argv)
|
||||
termlistPrint (sys->untrusted);
|
||||
printf ("\n");
|
||||
knowledgePrint (sys->know);
|
||||
printf ("inverses: ");
|
||||
knowledgeInversesPrint (sys->know);
|
||||
printf ("\n");
|
||||
locVarPrint (sys->locals);
|
||||
protocolsPrint (sys->protocols);
|
||||
|
||||
|
@ -82,6 +82,7 @@ List findMacroDefinition(Symbol s)
|
||||
%token SECRET
|
||||
%token COMPROMISED
|
||||
%token INVERSEKEYS
|
||||
%token INVERSEKEYFUNCTIONS
|
||||
%token UNTRUSTED
|
||||
%token USERTYPE
|
||||
%token SINGULAR
|
||||
@ -356,6 +357,12 @@ declaration : secretpref CONST basictermlist typeinfo1 ';'
|
||||
t->t2.tac = $5;
|
||||
$$ = t;
|
||||
}
|
||||
| INVERSEKEYFUNCTIONS '(' term ',' term ')' ';'
|
||||
{ Tac t = tacCreate(TAC_INVERSEKEYFUNCTIONS);
|
||||
t->t1.tac = $3;
|
||||
t->t2.tac = $5;
|
||||
$$ = t;
|
||||
}
|
||||
| COMPROMISED termlist ';'
|
||||
{ Tac t = tacCreate(TAC_COMPROMISED);
|
||||
t->t1.tac= $2;
|
||||
@ -456,7 +463,7 @@ term : ID '(' termlist ')'
|
||||
{
|
||||
Tac t = tacCreate(TAC_STRING);
|
||||
t->t1.sym = $1;
|
||||
$$ = tacJoin(TAC_ENCRYPT,tacTuple($3),t,NULL);
|
||||
$$ = tacJoin(TAC_FCALL,tacTuple($3),t,NULL);
|
||||
}
|
||||
| '{' termlist '}' key
|
||||
{
|
||||
|
@ -1,2 +0,0 @@
|
||||
Passed wall time in seconds:
|
||||
0
|
@ -1,2 +1,2 @@
|
||||
Passed wall time in seconds:
|
||||
14
|
||||
15
|
||||
|
@ -1,2 +1,2 @@
|
||||
Passed wall time in seconds:
|
||||
23
|
||||
24
|
||||
|
@ -1,2 +1,2 @@
|
||||
Passed wall time in seconds:
|
||||
28
|
||||
29
|
||||
|
@ -1,6 +1,6 @@
|
||||
claim spliceAS-HC,I Secret_7 N2 Ok [no attack within bounds] time=60
|
||||
claim spliceAS-HC,I Niagree_9 - Ok [does not occur] time=60
|
||||
claim spliceAS-HC,I Nisynch_10 - Ok [does not occur] time=60
|
||||
claim spliceAS-HC,R Secret_8 N2 Ok [no attack within bounds] time=60
|
||||
claim spliceAS-HC,R Niagree_11 - Ok [does not occur] time=60
|
||||
claim spliceAS-HC,R Nisynch_12 - Ok [does not occur] time=60
|
||||
claim spliceAS-HC,I Secret_7 N2 Fail [at least 7 attacks]
|
||||
claim spliceAS-HC,I Niagree_9 - Fail [at least 1 attack]
|
||||
claim spliceAS-HC,I Nisynch_10 - Fail [at least 1 attack]
|
||||
claim spliceAS-HC,R Secret_8 N2 Fail [at least 7 attacks]
|
||||
claim spliceAS-HC,R Niagree_11 - Fail [at least 1 attack]
|
||||
claim spliceAS-HC,R Nisynch_12 - Fail [at least 1 attack]
|
||||
|
@ -1,2 +1,2 @@
|
||||
Passed wall time in seconds:
|
||||
60
|
||||
6
|
||||
|
@ -1,6 +1,6 @@
|
||||
claim spliceAS,I Secret_7 N2 Ok [no attack within bounds] time=60
|
||||
claim spliceAS,I Niagree_9 - Ok [does not occur] time=60
|
||||
claim spliceAS,I Nisynch_10 - Ok [does not occur] time=60
|
||||
claim spliceAS,R Secret_8 N2 Ok [no attack within bounds] time=60
|
||||
claim spliceAS,R Niagree_11 - Ok [does not occur] time=60
|
||||
claim spliceAS,R Nisynch_12 - Ok [does not occur] time=60
|
||||
claim spliceAS,I Secret_7 N2 Fail [at least 7 attacks]
|
||||
claim spliceAS,I Niagree_9 - Fail [at least 1 attack]
|
||||
claim spliceAS,I Nisynch_10 - Fail [at least 1 attack]
|
||||
claim spliceAS,R Secret_8 N2 Fail [at least 7 attacks]
|
||||
claim spliceAS,R Niagree_11 - Fail [at least 1 attack]
|
||||
claim spliceAS,R Nisynch_12 - Fail [at least 1 attack]
|
||||
|
@ -1,2 +1,2 @@
|
||||
Passed wall time in seconds:
|
||||
60
|
||||
6
|
||||
|
@ -1,2 +1,2 @@
|
||||
Passed wall time in seconds:
|
||||
36
|
||||
37
|
||||
|
@ -1,2 +0,0 @@
|
||||
Passed wall time in seconds:
|
||||
0
|
@ -415,7 +415,7 @@ Readable (Knowledge know, Term t)
|
||||
return true;
|
||||
}
|
||||
// Right disjunct
|
||||
inv = inverseKey (know->inverses, TermKey (t));
|
||||
inv = inverseKey (know, TermKey (t));
|
||||
either = false;
|
||||
if (inKnowledge (know, inv))
|
||||
{
|
||||
|
@ -171,6 +171,7 @@ claim { return CLAIMT; }
|
||||
run { return RUN; }
|
||||
secret { return SECRET; }
|
||||
inversekeys { return INVERSEKEYS; }
|
||||
inversekeyfunctions { return INVERSEKEYFUNCTIONS; }
|
||||
untrusted { return UNTRUSTED; }
|
||||
compromised { return COMPROMISED; }
|
||||
usertype { return USERTYPE; }
|
||||
|
@ -119,7 +119,7 @@ specialTermInit (const System sys)
|
||||
langcons (TERM_PK, "pk", TERM_Function);
|
||||
langcons (TERM_SK, "sk", TERM_Function);
|
||||
langcons (TERM_K, "k", TERM_Function);
|
||||
knowledgeAddInverse (sys->know, TERM_PK, TERM_SK);
|
||||
knowledgeAddInverseKeyFunctions (sys->know, TERM_PK, TERM_SK);
|
||||
knowledgeAddTerm (sys->know, TERM_PK);
|
||||
|
||||
/* Define a prefix for labels for the match function */
|
||||
|
@ -504,7 +504,7 @@ roleInstanceArachne (const System sys, const Protocol protocol,
|
||||
newt = makeTermType (GLOBAL, TermSymb (oldt), rid);
|
||||
}
|
||||
newt->stype = oldt->stype; // copy list of types
|
||||
newt->roleVar = isrole; // set role status
|
||||
newt->helper.roleVar = isrole; // set role status
|
||||
|
||||
// Add to copy list
|
||||
TERMLISTADD (fromlist, oldt);
|
||||
|
@ -32,6 +32,7 @@ enum tactypes
|
||||
TAC_SYM,
|
||||
TAC_TUPLE,
|
||||
TAC_ENCRYPT,
|
||||
TAC_FCALL,
|
||||
TAC_VAR,
|
||||
TAC_CONST,
|
||||
TAC_FRESH,
|
||||
@ -48,6 +49,7 @@ enum tactypes
|
||||
TAC_ROLEREF,
|
||||
TAC_SECRET,
|
||||
TAC_INVERSEKEYS,
|
||||
TAC_INVERSEKEYFUNCTIONS,
|
||||
TAC_HASHFUNCTION,
|
||||
TAC_UNTRUSTED,
|
||||
TAC_COMPROMISED,
|
||||
|
68
src/term.c
68
src/term.c
@ -84,6 +84,9 @@ makeTerm ()
|
||||
|
||||
//! Create a fresh encrypted term from two existing terms.
|
||||
/**
|
||||
* The first argument is the message,
|
||||
* the second argument is the key.
|
||||
*
|
||||
*@return A pointer to the new term.
|
||||
*/
|
||||
Term
|
||||
@ -92,11 +95,32 @@ makeTermEncrypt (Term t1, Term t2)
|
||||
Term term = makeTerm ();
|
||||
term->type = ENCRYPT;
|
||||
term->stype = NULL;
|
||||
term->helper.fcall = false;
|
||||
term->subst = NULL;
|
||||
TermOp (term) = t1;
|
||||
TermKey (term) = t2;
|
||||
return term;
|
||||
}
|
||||
|
||||
Term
|
||||
makeTermFcall (Term t1, Term t2)
|
||||
//! Create a fresh function application term from two existing terms.
|
||||
/**
|
||||
* The first argument is the function argument,
|
||||
* the second argument is the function (name).
|
||||
*
|
||||
* These behave like encryptions in most cases.
|
||||
*
|
||||
*@return A pointer to the new term.
|
||||
*/
|
||||
{
|
||||
Term t;
|
||||
|
||||
t = makeTermEncrypt (t1, t2);
|
||||
t->helper.fcall = true;
|
||||
return t;
|
||||
}
|
||||
|
||||
//! Create a fresh term tuple from two existing terms.
|
||||
/**
|
||||
*@return A pointer to the new term.
|
||||
@ -128,7 +152,8 @@ makeTermTuple (Term t1, Term t2)
|
||||
tt = makeTerm ();
|
||||
tt->type = TUPLE;
|
||||
tt->stype = NULL;
|
||||
tt->roleVar = 0;
|
||||
tt->helper.roleVar = 0;
|
||||
tt->subst = NULL;
|
||||
TermOp1 (tt) = t1;
|
||||
TermOp2 (tt) = t2;
|
||||
return tt;
|
||||
@ -145,7 +170,16 @@ makeTermType (const int type, const Symbol symb, const int runid)
|
||||
Term term = makeTerm ();
|
||||
term->type = type;
|
||||
term->stype = NULL;
|
||||
term->roleVar = 0;
|
||||
if ((type == ENCRYPT) || (type == TUPLE))
|
||||
{
|
||||
// Non-leaf
|
||||
term->helper.fcall = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Leaf
|
||||
term->helper.roleVar = 0;
|
||||
}
|
||||
term->subst = NULL;
|
||||
TermSymb (term) = symb;
|
||||
TermRunid (term) = runid;
|
||||
@ -381,8 +415,7 @@ termPrintCustom (Term term, char *leftvar, char *rightvar, char *lefttup,
|
||||
}
|
||||
if (realTermEncrypt (term))
|
||||
{
|
||||
if (isTermLeaf (TermKey (term))
|
||||
&& inTermlist (TermKey (term)->stype, TERM_Function))
|
||||
if (term->helper.fcall)
|
||||
{
|
||||
/* function application */
|
||||
termPrintCustom (TermKey (term), leftvar, rightvar, lefttup,
|
||||
@ -695,8 +728,12 @@ termRunid (Term term, int runid)
|
||||
/* anything else, recurse */
|
||||
if (realTermEncrypt (term))
|
||||
{
|
||||
return makeTermEncrypt (termRunid (TermOp (term), runid),
|
||||
termRunid (TermKey (term), runid));
|
||||
Term t;
|
||||
|
||||
t = makeTermEncrypt (termRunid (TermOp (term), runid),
|
||||
termRunid (TermKey (term), runid));
|
||||
t->helper.fcall = term->helper.fcall;
|
||||
return t;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1159,22 +1196,23 @@ term_encryption_level (const Term term)
|
||||
}
|
||||
else
|
||||
{
|
||||
int l, r;
|
||||
|
||||
if (realTermTuple (t))
|
||||
{
|
||||
int l, r;
|
||||
|
||||
l = iter_maxencrypt (TermOp1 (t));
|
||||
r = iter_maxencrypt (TermOp2 (t));
|
||||
if (l > r)
|
||||
return l;
|
||||
else
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
// encrypt
|
||||
return 1 + iter_maxencrypt (TermOp (t));
|
||||
l = 1 + iter_maxencrypt (TermOp (t));
|
||||
r = iter_maxencrypt (TermKey (t));
|
||||
}
|
||||
if (l > r)
|
||||
return l;
|
||||
else
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1418,9 +1456,9 @@ Term
|
||||
getTermFunction (Term t)
|
||||
{
|
||||
t = deVar (t);
|
||||
if (t != NULL)
|
||||
if (realTermEncrypt (t))
|
||||
{
|
||||
if (realTermEncrypt (t) && isTermFunctionName (TermKey (t)))
|
||||
if (t->helper.fcall)
|
||||
{
|
||||
return TermKey (t);
|
||||
}
|
||||
|
@ -47,7 +47,11 @@ struct term
|
||||
//! Data Type termlist (e.g. agent or nonce)
|
||||
/** Only for leaves. */
|
||||
void *stype; // list of types
|
||||
int roleVar; //!< only for leaf, arachne engine: role variable flag
|
||||
union
|
||||
{
|
||||
int roleVar; //!< only for leaf, arachne engine: role variable flag
|
||||
int fcall; //!< only for 'encryption' to mark actual function call f(t)
|
||||
} helper;
|
||||
|
||||
//! Substitution term.
|
||||
/**
|
||||
@ -96,6 +100,7 @@ typedef struct term *Term;
|
||||
void termsInit (void);
|
||||
void termsDone (void);
|
||||
Term makeTermEncrypt (Term t1, Term t2);
|
||||
Term makeTermFcall (Term t1, Term t2);
|
||||
Term makeTermTuple (Term t1, Term t2);
|
||||
Term makeTermType (const int type, const Symbol symb, const int runid);
|
||||
__inline__ Term deVarScan (Term t);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "debug.h"
|
||||
#include "error.h"
|
||||
#include "switches.h"
|
||||
#include "knowledge.h"
|
||||
|
||||
/*
|
||||
* Shared stuff
|
||||
@ -618,68 +619,6 @@ termlistLength (Termlist tl)
|
||||
return i;
|
||||
}
|
||||
|
||||
//! Give the inverse key term of a term.
|
||||
/**
|
||||
* Gives a duplicate of the inverse Key of some term (which is used to encrypt something), as is defined
|
||||
* by the termlist, which is a list of key1,key1inv, key2, key2inv, etc...
|
||||
*@param inverses The list of inverses, typically from the knowledge.
|
||||
*@param key Any term of which the inverse will be determined.
|
||||
*@return A pointer to a duplicate of the inverse key term. Use termDelete to remove it.
|
||||
*\sa termDuplicate(), knowledge::inverses
|
||||
*/
|
||||
|
||||
Term
|
||||
inverseKey (Termlist inverses, Term key)
|
||||
{
|
||||
key = deVar (key);
|
||||
|
||||
/* is this a function application? i.e. hash? */
|
||||
if (isTermLeaf (key) && inTermlist (key->stype, TERM_Function))
|
||||
{
|
||||
/* functions cannot be inverted by default */
|
||||
return termDuplicate (TERM_Hidden);
|
||||
}
|
||||
/* check for the special case first: when it is effectively a function application */
|
||||
if (isTermEncrypt (key) && isTermLeaf (TermKey (key))
|
||||
&& inTermlist (deVar (TermKey (key))->stype, TERM_Function))
|
||||
{
|
||||
/* we are scanning for functions */
|
||||
/* scan the list */
|
||||
/* key is function application kk(op), or {op}kk */
|
||||
Term funKey (Term orig, Term newk)
|
||||
{
|
||||
/* in: {op}kk, nk
|
||||
* out: {op'}nk */
|
||||
return makeTermEncrypt (termDuplicate (TermOp (orig)),
|
||||
termDuplicate (newk));
|
||||
}
|
||||
while (inverses != NULL && inverses->next != NULL)
|
||||
{
|
||||
|
||||
if (isTermEqual (TermKey (key), inverses->term))
|
||||
return funKey (key, inverses->next->term);
|
||||
if (isTermEqual (TermKey (key), inverses->next->term))
|
||||
return funKey (key, inverses->term);
|
||||
inverses = inverses->next->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* scanning for a direct inverse */
|
||||
|
||||
/* scan the list */
|
||||
while (inverses != NULL && inverses->next != NULL)
|
||||
{
|
||||
if (isTermEqual (key, inverses->term))
|
||||
return termDuplicate (inverses->next->term);
|
||||
if (isTermEqual (key, inverses->next->term))
|
||||
return termDuplicate (inverses->term);
|
||||
inverses = inverses->next->next;
|
||||
}
|
||||
}
|
||||
return termDuplicate (key); /* defaults to symmetrical */
|
||||
}
|
||||
|
||||
//! Create a term local to a run.
|
||||
/*
|
||||
* We assume that at this point, no variables have been instantiated yet that occur in this term.
|
||||
|
@ -66,7 +66,6 @@ Termlist termlistAddBasic (Termlist tl, Term t);
|
||||
Termlist termlistAddBasics (Termlist tl, Termlist scan);
|
||||
Termlist termlistMinusTerm (Termlist tl, Term t);
|
||||
int termlistLength (Termlist tl);
|
||||
Term inverseKey (Termlist inverses, Term key);
|
||||
Term termLocal (const Term t, Termlist fromlist, Termlist tolist);
|
||||
Termlist termlistLocal (Termlist tl, const Termlist fromlist,
|
||||
const Termlist tolist);
|
||||
|
19
src/xmlout.c
19
src/xmlout.c
@ -438,7 +438,7 @@ xmlInverses (const System sys)
|
||||
|
||||
xmlPrint ("<inversekeys>");
|
||||
xmlindent++;
|
||||
invlist = sys->know->inverses;
|
||||
invlist = sys->know->inversekeys;
|
||||
while (invlist != NULL && invlist->next != NULL)
|
||||
{
|
||||
xmlPrint ("<keypair>");
|
||||
@ -452,6 +452,23 @@ xmlInverses (const System sys)
|
||||
}
|
||||
xmlindent--;
|
||||
xmlPrint ("</inversekeys>");
|
||||
|
||||
xmlPrint ("<inversekeyfunctions>");
|
||||
xmlindent++;
|
||||
invlist = sys->know->inversekeyfunctions;
|
||||
while (invlist != NULL && invlist->next != NULL)
|
||||
{
|
||||
xmlPrint ("<keypair>");
|
||||
xmlindent++;
|
||||
xmlOutTerm (NULL, invlist->term);
|
||||
xmlOutTerm (NULL, invlist->next->term);
|
||||
xmlindent--;
|
||||
xmlPrint ("</keypair>");
|
||||
|
||||
invlist = invlist->next->next;
|
||||
}
|
||||
xmlindent--;
|
||||
xmlPrint ("</inversekeyfunctions>");
|
||||
}
|
||||
|
||||
//! Show initial knowledge
|
||||
|
Loading…
Reference in New Issue
Block a user