formal specification of gemplus’ electronic purse case study néstor cataño & marieke huisman...

40
Formal specification of Gemplus’ electronic purse case study Néstor Cataño & Marieke Huisman INRIA Sophia-Antipolis {ncatano, mhuisman}@sophia.inria.fr

Upload: jade-harrison

Post on 02-Jan-2016

213 views

Category:

Documents


0 download

TRANSCRIPT

Formal specification of Gemplus’ electronic purse

case study

Néstor Cataño & Marieke HuismanINRIA Sophia-Antipolis

{ncatano, mhuisman}@sophia.inria.fr

The electronic purse

• Developed by trainee at Gemplus

• Goal: develop more complex application, using object-oriented features

• Revision by members research lab and new trainee

• Result: not completely finished , not fully representative

Software documentation

• Management & history of the development

• Clear, concise and unambiguous

• Correspondance with implementation

Some Fragments from LoyaltiesTable

// huge modifications on 31/07/2000

// now, we handle AID objects instead of byte arrays that represents them.

// that way, we gain some space, and code is clearer.

/* the purse stores in this object the loyalties that are allowed to communicate with it*/

class LoyaltiesTable {

//////////////// ATTRIBUTES ////////////////

// temporarily modified by RM on 26/07/2000 for memory reason

// private final static byte NB_MAX = (byte)20;

private final static byte NB_MAX = (byte)3;…/* suppress all the entries of the loyalty specified by aid */void delLoyalty(AID aid) {…}

…/* suppress the notification of the loyalty specified by aid*/void removeNotification(AID aid) {…}

Software documentation

• Management & history of the development

• Clear, concise and unambiguous

• Correspondance with implementation• Formal specification• And verification

Difficult and labour-intensive

This talk

• Different approaches to formal specification and verification

• Static checking (lightweight formal methods)

• The electronic purse case study

• Static checking of the electronic purse: class invariants

Specification language

• Close to programming language

• Expressions from programming language

Eiffel, JML, ESC/Java, Jass

with specification-specific constructs (forall, exists, implication etc.)

Checking techniques

• Run-time checking

• Full verification

(syntactic or

semantic)

(Eiffel, JML, Jass)

(Jive)

(LOOP)

• Static checking (ESC/Java)

Static checking with ESC/Java

• Compaq Research (Leino et al.)

• Focus on finding common program errors (nullpointers, array index out of bounds)

• Proof obligations to dedicated theorem prover (assume - assert pairs)

• Issues warnings

Static checking with ESC/Java

ESC/Java =

Compromise

between

soundness,

completeness,

and

efficiency

ESC/Java pragmas

• Preconditions (requires)• Postconditions (ensures)• Exceptional postconditions (exsures)• Modifies clause• Class invariants• Implication, quantification• Value expression in pre-state (\old(E))• Result value of method (\result)

The electronic purse

• Supports debit, credit and currency change operations

• Interaction with loyalty, card issuer and terminal

• Packages: utils, pacapinterfaces and purse

The purse package

• PurseApplet: installation, (de)selection, communication with terminal

• Purse:

– implements basic functionalities

– keeps track of balance, transactions, currency changes, loyalties

The purse package

• AccessControl: restricted set of users for certain operations

• Currencies

• Cryptographic concepts

Writing the specification

• For each method: requires, ensures, exsures, modifies

• First basic classes (utils), then more application-specific

• Appropriate class invariants, e.g. restricting domain of instance variables

Writing the specification

• Discrepancies between documentation and implementation

Writing the specification

• Discrepancies between documentation and implementation

Writing the specification

• Discrepancies between documentation and implementation

• Usage of existing API specification

Writing the specification

• Discrepancies between documentation and implementation

• Usage of existing API specification

• .spec files for e.g. visa and crypto classes

Writing the specification

• Discrepancies between documentation and implementation

• Usage of existing API specification

• .spec files for e.g. visa and crypto classes

• Avoid warnings as much as possible, but still full specification

Class invariants

Restrict state space of a class– reference never null pointer

//@ invariant purse != null;

– variable within a certain range/*@ invariant decPart >= 0 && decPart < PRECISION; invariant intPart >= 0 &&

intPart < MAX_DECIMAL_NUMBER; */

Easy to write, easy to check

Enumeration types/* the transaction status*/

public static final byte INDETERMINE = (byte)0;

. . .

/* the transaction status*/

public static final byte TYPE_CREDIT = (byte)50;

/* the transaction status*/

public static final byte TYPE_DEBIT = (byte)51;

. . .

/* the transaction type: debit or credit*/

private byte type;

. . .

/* set all this transaction attributes to 0*/ void reset() {

isValid = false;

number = (short)0;

type = INDETERMINE;

typeProduit = (short)0;

. . .

}

/* the transaction type: debit or credit*/

private byte type;

. . .

/* set all this transaction attributes to 0*/

void reset() {

isValid = false;

number = (short)0;

type = INDETERMINE;

typeProduit = (short)0;

. . .

}

public AccessCondition() {super();// commented by Rodolphe Muller on 16/06/2000// strange to set the condition here to 0 and to// FREE above setCondition((byte)0); }

Enumeration types

/*@ invariant condition == FREE || condition == LOCKED || condition == SECRET_CODE || condition == SECURE_MESSAGING ||

condition == (SECRET_CODE | SECURE_MESSAGING)

*/public AccessCondition() {super();// commented by Rodolphe Muller on 16/06/2000// strange to set the condition here to 0 and to// FREE above setCondition((byte)0); }

public AccessCondition() {super();// commented by Rodolphe Muller on 16/06/2000// strange to set the condition here to 0 and to// FREE above setCondition((byte)0); } NB. FREE == (byte)1;

switch(condition) {

case FREE: ...

case SECRET_CODE: ...

case SECURE_MESSAGING: ...

case SECRET_CODE | SECURE_MESSAGING: ...

case LOCKED: ...

default:

//@ assert false;

t = AccessConditionException.C_C_INVALIDE; AccessConditionException.throwIt(t);

}

Avoiding dead code

switch(condition) {

case FREE: ...

case SECRET_CODE: ...

case SECURE_MESSAGING: ...

case SECRET_CODE | SECURE_MESSAGING: ...

case LOCKED: ...

default:

t = AccessConditionException.C_C_INVALIDE; AccessConditionException.throwIt(t);

}

Other problems

• Incorrect coding• Forgetting variable modifiers (final)

• Underspecified documentation Is MAX_DECIMAL_NUMBER.999 legal?And how do you round it?

• Superfluous methods (isNegatif())

• Complex and undocumented datastructures (with incorrect corrections)

Complete specification

Available from

http://www-sop.inria.fr/lemme/verificard/electronic_purse

Conclusions

• Using lightweight formal methods, applications can be improved

• Class invariants make implicit assumptions explicit and check them

• Case study convinced Gemplus to look at JML and ESC/Java

• ESC/Java useful, but possibilities for improvement

Complete specification

Available from

http://www-sop.inria.fr/lemme/verificard/electronic_purse

Writing the specification

/*@ modifies M;

requires true;

ensures Q;

exsures (E) !P;

*/

void m () {

. . .

}

Writing the specification

Offensive

/*@ modifies M;

requires P;

ensures Q;

exsures (E) false;

*/

void m () {

. . .

}

Defensive

/*@ modifies M;

requires true;

ensures Q;

exsures (E) !P;

*/

void m () {

. . .

}

Experiences with ESC/Java

• Pleasant tool, easy to work with

• Specifications written by non-experienced user

• Two/three months work all together

Suggestions for ESC/Javaspecification language

• Richer specification languagemodifies \nothing, modifies \field_of(E)

• Extra quantifiers

• Run-time exceptions without explicit throws clause

• Use of pure methods in specifications

modifies sessionNumber, date.jour, date.mois, date.annee, heure.heure, heure.minute; modifies ancienneDevise, nouvelleDevise, isValid, status;modifies id[*], terminalTC[*], terminalSN[*] ; requires es != null ; requires es.id != terminalTC & es.id != terminalSN & es.terminalTC != terminalSN; ensures sessionNumber == es.sessionNumber ;ensures ancienneDevise == es.ancienneDevise ; ensures nouvelleDevise == es.nouvelleDevise ; ensures isValid == es.isValid ; ensures status == es.status ; ensures (\forall int i;0 <= i & i < ID_LENGTH ==> es.id[i] == id[i]); ensures (\forall int i;0 <= i & i < TTC_LENGTH ==>

es.terminalTC[i] == terminalTC[i]);ensures (\forall int i;0 <= i & i < TSN_LENGTH ==>

es.terminalSN[i] == terminalSN[i]);exsures (TransactionException e)

e._reason == TransactionException.BUFFER_FULL && JCSystem._transactionDepth == 1; exsures (NullPointerException) false; exsures (ArrayIndexOutOfBoundsException) false;

modifies sessionNumber, date.jour, date.mois, date.annee, heure.heure, heure.minute; modifies ancienneDevise, nouvelleDevise, isValid, status;modifies id[*], terminalTC[*], terminalSN[*] ; requires es != null ; requires es.id != terminalTC & es.id != terminalSN & es.terminalTC != terminalSN; ensures sessionNumber == es.sessionNumber ;ensures ancienneDevise == es.ancienneDevise ; ensures nouvelleDevise == es.nouvelleDevise ; ensures isValid == es.isValid ; ensures status == es.status ; ensures (\forall int i;0 <= i & i < ID_LENGTH ==> es.id[i] == id[i]); ensures (\forall int i;0 <= i & i < TTC_LENGTH ==>

es.terminalTC[i] == terminalTC[i]);ensures (\forall int i;0 <= i & i < TSN_LENGTH ==>

es.terminalSN[i] == terminalSN[i]);exsures (TransactionException e) e._reason == TransactionException.BUFFER_FULL && JCSystem._transactionDepth == 1; exsures (NullPointerException) false; exsures (ArrayIndexOutOfBoundsException) false;

Example specification

And as we would like it to be...

modifies sessionNumber, date.jour, date.mois, date.annee, heure.heure, heure.minute; modifies ancienneDevise, nouvelleDevise, isValid,

status;modifies id[*], terminalTC[*], terminalSN[*] ; requires es != null ; requires es.id != terminalTC & es.id != terminalSN &

es.terminalTC != terminalSN; ensures this.equal(es);exsures (TransactionException e)

e._reason == TransactionException.BUFFER_FULL && JCSystem._transactionDepth == 1;

exsures (NullPointerException) false;

exsures (ArrayIndexOutOfBoundsException) false;

Verification of modifies clauses

/*@ modifies x; ensures x == 3; */ void m() { x = 3; n (); }

void n() { x = 4; }

Missing modifies clause

Specification accepted

NO

Modifies clauses

• Implementation of modifiable checker• Extension of JML• Static checking technique, based on

syntax• Neither sound, nor complete• Fully described in separate paper

(ask Néstor or me)

Future work

• Develop application with annotations from scratch

• Extension to multi-threading• Automated verification technique for

termination of loops• Cryptographic aspects of the

specification