calypsonet / calypsonet-terminal-calypso-java-api

Deprecated repository containing the old Java code of CNA Terminal Calypso Card API → replaced by https://github.com/eclipse-keypop/keypop-calypso-card-java-api/
https://keypop.org/
Eclipse Public License 2.0
6 stars 3 forks source link

Amélioration de la gestion des KIF KVC par défaut et KVC autorisés #50

Closed kfereira closed 1 year ago

kfereira commented 1 year ago

Actuellement lors de la création d'un objet CardSecuritySetting il est possible d'assigner des kif/kvc à utiliser par défaut ainsi qu'une liste de KVC autorisés.

Dans le cas où aucun KIF n'est remonté lors du OPEN SESSION le KIF par défaut est utilisé. La façon de créer CardSecuritySetting actuellement ne permet de fournir un KIF par défaut en fonction du KVC récupéré de la carte.

Aussi concernant la liste de KVC autorisés, la détermination d'une telle liste n'est pas toujours statique et peut nécessiter de connaitre le KIF lu de la carte.

Le but de ce ticket est de permettre de fournir les KIF / KVC à utiliser par défaut ainsi que la liste des KVC autorisés via des interfaces (SPI) que nous implémenterons selon nos spécificités.

Ca se traduirait en la création de deux SPI:

public interface DefaultKifKvcProviderSpi {
    byte[] computeKifKvc(Byte cardKif, Byte cardKvc);
}

public interface KifKvcAuthorizationServiceSpi {
    boolean isAuthorizedKey(Byte kif, Byte kvc);
}

Ces SPI serait affectée au CardSecuritySetting via les méthodes:


  CardSecuritySetting assignDefaultKifKvcProvider(WriteAccessLevel writeAccessLevel, DefaultKifKvcProviderSpi kifKvcProvider);

  CardSecuritySetting setKifKvcAuthorizationService(KifKvcAuthorizationServiceSpi kifKvcAuthorizationServiceSpi);

Les impactes sur la lib keyple-card-calypso-java-lib

Dans la classe CardSecuritySettingAdapter :

    boolean isSessionKeyAuthorized(Byte kif, Byte kvc) {
        if (kif == null || kvc == null) {
            return false;
        }
        //👉 On utilise la nouvelle SPI si elle est valorisée 
        if(kifKvcAuthorizationServiceSpi != null) {
            return kifKvcAuthorizationServiceSpi.isAuthorizedKey(kif, kvc);
        }
        if (authorizedSessionKeys.isEmpty()) {
            return true;
        }
        return authorizedSessionKeys.contains(((kif << 8) & 0xff00) | (kvc & 0x00ff));
    }

Dans la méthode processAtomicOpenning de la classe CardTransactionManagerAdapter:

    byte[] kifKvc = controlSamTransactionManager.computeKifKvc(writeAccessLevel, cardKif, cardKvc);
    Byte kif = kifKvc[0];
    Byte kvc = kifKvc[1];

Dans la classe CardControlSamTransactionManagerAdapter:

byte[] computeKifKvc(WriteAccessLevel writeAccessLevel, Byte cardKif, Byte cardKvc) {
        DefaultKifKvcProviderSpi defaultKifKvcProviderSpi = cardSecuritySetting.getDefaultKifKvcProviderSpi();

        if (defaultKifKvcProviderSpi != null) {
           //👉 On utilise la nouvelle SPI si elle est valorisée 
            return defaultKifKvcProviderSpi.computeKifKvc(cardKif, cardKvc);
        } else {
            Byte kvc = computeKvc(writeAccessLevel, cardKvc);
            Byte kif = computeKif(writeAccessLevel, cardKif, kvc);
            return new byte[]{kif, kvc};
        }
    }
andrei-cristea commented 1 year ago

Bonjour Kevin,

Est-ce que la méthode CardSecuritySetting.assignKif (WriteAccessLevel writeAccessLevel, byte kvc, byte kif) ne répondrait pas à ton besoin ?

En effet, cette méthode permet d'associer pour un kvc et un niveau d'accès le kif à utiliser quand la carte ne le fournit pas.

A l'exécution, lorsque la carte ne fournit pas le kvc, alors c'est le kvc par défaut associé au niveau d'accès qui sera utilisé et/ou si le kif n'est pas fournit, se sera le kif associé au kvc et niveau d'accès, ou le kvc par défaut associé au niveau d'accès si non trouvé.

Cordialement

kfereira commented 1 year ago

Dans notre contexte, dans le cas ou le KIF n'est pas fourni par la carte, nous avons un algorithme pour savoir quel KIF utilisé en fonction du KVC et d'autres paramètres internes. Aussi dans le cas ou ni le kif ni le kvc sont présents sur la carte, de même un algo spécifique est prévu.

D'où la proposition d'utiliser des SPI pour plus de flexibilité.

jeanpierrefortune commented 1 year ago

Bonjour Kévin, Si je comprends bien c'est plus pour une raison de commodité que de fonctionnalités. N'est-il pas possible de pré-calculer l'ensemble des valeurs pour les différents couples (kvc, kif) supportés et de les injecter au moment de l'initialisation ? Il ne devrait pas y avoir beaucoup de valeurs dans cette liste, non ? Il faut dans ce cas avoir déterminé avant l'ouverture de session quels paramètres on envoie dans les security settings. Cela éviterait de complexifier l'API et garantirait un temps de traitement optimal au moment où la carte est présente.

kfereira commented 1 year ago

Bonjour Jean-Pierre,

Oui en effet c'est plus pour une raison de commodité.

Nous migrons une base de code importante vers l'utilisation de Keyple. Et nous essayons de ne pas trop s'éloigner de notre architecture d'origine afin de ne pas avoir à réécrire trop de tests. Du coups pour éviter de trop changer ces algo de détermination de kif/kvc nous avions opté pour l'utilisation d'interface SPI. Après effectivement c'est du temps de traitement ajouté au traitement carte.

Nous allons refaire une passe sur le code pour voir dans quelle mesure on pourrait se passer de ces SPI. Je reviens vers vous asap.

kfereira commented 1 year ago

Après investigation plus poussée, on arrive à s'en sortir sans. Je clos du coups cette issue.