• Aucun résultat trouvé

Un vérificateur de bytecode léger

Vérification de bytecode

5.3 Formalisation de vérificateurs de bytecode

5.3.5 Un vérificateur de bytecode léger

Nous pr´esentons ici un mod`ele abstrait de v´erificateur de code octet l´eger (voir section 5.1.4), `a la mani`ere du mod`ele pr´esent´e `a la section 5.3.1.

Ce mod`ele se base sur une notion de certificat, qui sera la preuve trans-mise avec le programme, de la sˆuret´e du typage.

D´efinition 24 Un v´erificateur de code octet sur un syst`eme de transition avec erreur est donn´e par un ensemble cert de certificats, un pr´edicat d´ e-cidable check_light sur les ´etats et les certificats qui rejette tous les ´etats mauvais.

De mani`ere formelle, le type de module LBCV des v´erificateurs de code octet l´egers ´etend le module TSE comme suit :

Module Type LBCV.

Declare Module tse: TSE.

Import tse.

Parameter cert : Set.

Parameter check_light : certstateProp.

Axiom check_light_ok : (a:state)(c:cert)(check_light c a)→ ¬(bad a).

Axiom check_light_dec : (c:cert)(dec_pred ? (check_light c)).

End LBCV.

Il est possible de construire un v´erificateur de code octet l´eger `a partir d’une structure de point fixe en prenant les ´etats eux-mˆemes comme certifi-cat. La v´erification l´eg`ere pour un ´etat aet certificat c est alors r´ealis´ee en v´erifiant que c:

– est plus petit que a;

– est un point fixe pourexec; – n’est pas un ´etat d’erreur.

Ces op´erations sont effectu´ees par le module WF_LBCV prenant en argument un module de typeFSE et satisfaisant le type LBCV.

La v´erification de code octet l´eg`ere est correcte et compl`ete vis-`a-vis de la v´erification de code octet.

Lemme 4 Sur une structure de point fixe avec erreurs, pour tout ´etat a et

c, les propri´et´es suivantes sont v´erifi´ees : Correction : (check_light a c) →(check a).

Compl´etude : (check a) →(check_light a (fixpt a)).

Notons finalement que cette notion de v´erification de code octet l´eg`ere peut ˆetre raffin´ee, plus particuli`erement en qui concerne la notion de certi-ficat. Il est possible et il apparaˆıt facile de ne transmettre dans le certificat, comme r´ealis´e dans [35, 78], que l’indication des types calcul´es au niveau des points de jonction du programme. Les types manquant peuvent alors ˆetre calcul´es en une seule passe sur le programme pendant la v´erification du

certificat. Cette approche est ´egalement prouv´ee correcte et compl`ete par Klein etNipkow[77, 79].

5.4 Conclusions

Nous avons con¸cu un cadre g´en´erique dans lequel nous avons ´etabli la correction d’un v´erificateur param´etris´e de code octet et justifi´e la technique compositionnelle de la v´erification (traitement m´ethode par m´ethode et ges-tion des excepges-tions). Ce cadre fournit une interface commode par laquelle construire un v´erificateur certifi´e de code octet pour les plates formes Java ou Java Card.

Un des aspects pratique et int´eressant de notre travail est de se repo-ser sur le syst`eme de modules de la version 7.4 de Coq. Notre exp´erience montre que les modules peuvent avantageusement ˆetre exploit´es pour four-nir des d´eveloppements structur´es. Cependant, nous avons trouv´e un certain nombre de situations o`u les modules de premi`ere classe auraient ´et´e utiles (les travaux de Augustsson[3] et de Coquand,Pollacket Takeyama [47] montrent qu’il est possible de consid´erer les modules comme des types d´ependants d’enregistrement). De mˆeme, les modules bien qu’apportant des fonctionnalit´es similaires aux objets des langages `a objets n’offrent pas la mˆeme facilit´e d’utilisation.

Travaux à venir Il est possible d’am´eliorer encore le travail pr´esent´e selon trois directions :

V´erificateurs de code octet optimis´es. Afin d’am´eliorer l’efficacit´e du v´ erifi-cateur de code octet extrait de notre mod`ele, il semble important de formaliser et de prouver correct un certain nombre d’optimisations, par exemple celles propos´ees dans [65];

V´erificateurs de code octet l´egers optimis´es. Afin de minimiser l’utilisation de l’espace m´emoire, les impl´ementations de v´erificateurs de code octet l´egers reposent uniquement sur les annotations aux points de jonction du programme. `A partir de ceux-ci, la structure d’historique (qui sert de certificat dans nos preuves) peut ˆetre reconstruite. Il semble int´ eres-sant d’´etendre notre travail dans cette direction. Nous nous attendons

`

a ce que notre formalisme alg´ebrique rendre cette tˆache relativement ais´ee.

V´erificateurs de code octet renforc´es. Comme soulign´e dans l’introduction, notre travail fournit une interface pouvant ˆetre utilis´ee pour d´eriver des v´erificateurs de code octet certifi´es assurant d’autres propri´et´es de s´ecurit´e comme la confidentialit´e ou la disponibilit´e. Des travaux

sont actuellement men´es dans l’´equipe pour d´evelopper une machine virtuelle d´efensive garantissant la non-interf´erence [16] (pas de fuite de valeurs sensibles vers des valeurs publiques d’un programme), et non pensons que ce travail sera utile pour d´eriver des v´erificateurs de code octet renforc´es assurant cette non-interf´erence. Il serait possible de mener un travail similaire pour le contrˆole des ressources afin d’assurer la disponibilit´e de l’unit´e de calcul et de la m´emoire.

Instanciation et outils d’aide à la preuve

Dans ce chapitre, nous allons d´etailler les preuves n´ecessaire `a l’instancia-tion du mod`ele de v´erificateur de code octet pr´esent´e au chapitre pr´ec´edent.

Avec les acquis de la r´ealisation de ces preuves, rendues fastidieuses par le nombre important et la complexit´e des instructions, nous allons ´etudier les moyens d’automatiser ces preuves et proposer des outils visant `a cette automatisation. Ces outils se centreront sur une tactique en Coqfacilitant le raisonnement sur les sp´ecifications fonctionnelles ; l’utilisation deJakarta pour la g´en´eration automatique de scripts de preuves `a l’aide des informa-tions n´ecessaires `a l’abstraction ; l’utilisation d’outils de r´e´ecriture tels que Spike.

6.1 Notations de C

OQ

Dans cette section, nous introduisons les notations de Coq en rapport avec la preuve de lemmes ou th´eor`emes.

Les lemmes sont ´enonc´es en Coq avec le mot-cl´e Lemma suivi du nom donn´e au lemme, du caract`ere : et du type du lemme. On passe ensuite dans le mode preuve de Coq, o`u l’on doit fournir une s´erie de tactiques suffisant `a d´emontrer le lemme. Dans ce mode de preuve, les hypoth`eses, donn´ees par leur nom et leur type, sont s´epar´ees du but `a prouver par :

============================

Parmi les tactiques les plus utilis´ees, citons :

Introsqui fait passer des quantificateurs ou produits du but dans les hypoth`eses ;

Unfold qui d´eplie (expanse) dans le but la d´efinition donn´ee en para-m`etre ;

Simplqui simplifie le but (par application de r`egles de r´eduction) ; – Case qui effectue un raisonnement par cas sur le terme donn´e en

pa-ram`etre ;

Apply qui fait correspondre le but au lemme donn´e en param`etre et laisse `a prouver les hypoth`eses du lemme ;

Inversion qui permet de raisonner par cas sur le pr´edicat inductif donn´e en param`etre ;

Reflexivityqui r´esout une ´egalit´e triviale ;

Il est ´egalement possible de composer des tactiques : avec la construc-tion tactic1 ; tactic2la tactique tactic2 sera appliqu´ee `a tous les sous-buts g´en´er´es par tactic1. Enfin, la construction Try tactic, utilis´ee avec la composition, permet de tester la tactique tactic sans faire ´echouer la composition dans sa globalit´e.