Aller au contenu principal

3. Éléments de procédure

Cette section décrit les procédures liées à la sécurité suivies par un moteur SNMP lors du traitement des messages SNMP selon le modèle de sécurité basé sur l'utilisateur.

3.1. Génération d'un message SNMP sortant

Cette section décrit la procédure suivie par un moteur SNMP chaque fois qu'il génère un message contenant une opération de gestion (comme une requête, une réponse, une notification ou un rapport) au nom d'un utilisateur, avec un securityLevel particulier.

  1. a) Si un securityStateReference est passé (message de réponse ou de rapport), alors les informations concernant l'utilisateur sont extraites des cachedSecurityData. Les cachedSecurityData peuvent maintenant être supprimées. Le securityEngineID est défini sur le snmpEngineID local. Le securityLevel est défini sur la valeur spécifiée par le module appelant.

    Sinon,

    b) en fonction du securityName, les informations concernant l'utilisateur au snmpEngineID de destination, spécifié par le securityEngineID, sont extraites du Local Configuration Datastore (LCD, usmUserTable). Si les informations sur l'utilisateur sont absentes du LCD, alors une indication d'erreur (unknownSecurityName) est renvoyée au module appelant.

  2. Si le securityLevel spécifie que le message doit être protégé contre la divulgation, mais que l'utilisateur ne prend pas en charge à la fois un protocole d'authentification et un protocole de confidentialité, alors le message ne peut pas être envoyé. Une indication d'erreur (unsupportedSecurityLevel) est renvoyée au module appelant.

  3. Si le securityLevel spécifie que le message doit être authentifié, mais que l'utilisateur ne prend pas en charge un protocole d'authentification, alors le message ne peut pas être envoyé. Une indication d'erreur (unsupportedSecurityLevel) est renvoyée au module appelant.

  4. a) Si le securityLevel spécifie que le message doit être protégé contre la divulgation, alors la séquence d'octets représentant le scopedPDU sérialisé est chiffrée selon le protocole de confidentialité de l'utilisateur. Pour ce faire, un appel est effectué au module de confidentialité qui implémente le protocole de confidentialité de l'utilisateur selon la primitive abstraite :

    statusInformation =       -- success or failure
    encryptData(
    IN encryptKey -- user's localized privKey
    IN dataToEncrypt -- serialized scopedPDU
    OUT encryptedData -- serialized encryptedPDU
    OUT privParameters -- serialized privacy parameters
    )
    • statusInformation indique si le processus de chiffrement a réussi ou non.

    • encryptKey la privKey localisée privée de l'utilisateur est la clé secrète qui peut être utilisée par l'algorithme de chiffrement.

    • dataToEncrypt le scopedPDU sérialisé sont les données à chiffrer.

    • encryptedData l'encryptedPDU représente le scopedPDU chiffré, encodé en OCTET STRING.

    • privParameters les paramètres de confidentialité, encodés en OCTET STRING.

    Si le module de confidentialité renvoie un échec, alors le message ne peut pas être envoyé et une indication d'erreur (encryptionError) est renvoyée au module appelant.

    Si le module de confidentialité renvoie un succès, alors les privParameters renvoyés sont placés dans le champ msgPrivacyParameters des securityParameters et l'encryptedPDU sert de charge utile du message en cours de préparation.

    Sinon,

    b) Si le securityLevel spécifie que le message ne doit pas être protégé contre la divulgation, alors un OCTET STRING de longueur nulle est encodé dans le champ msgPrivacyParameters des securityParameters et le scopedPDU en clair sert de charge utile du message en cours de préparation.

  5. Le securityEngineID est encodé en OCTET STRING dans le champ msgAuthoritativeEngineID des securityParameters. Notez qu'un securityEngineID vide (longueur nulle) est acceptable pour un message de requête, car cela amènera le moteur SNMP distant (autoritatif) à renvoyer un PDU de rapport avec le securityEngineID approprié inclus dans le msgAuthoritativeEngineID dans les securityParameters de ce PDU de rapport renvoyé.

  6. a) Si le securityLevel spécifie que le message doit être authentifié, alors les valeurs actuelles de snmpEngineBoots et snmpEngineTime correspondant au securityEngineID du LCD sont utilisées.

    Sinon,

    b) S'il s'agit d'un message de réponse ou de rapport, alors la valeur actuelle de snmpEngineBoots et snmpEngineTime correspondant au snmpEngineID local du LCD sont utilisées.

    Sinon,

    c) S'il s'agit d'un message de requête, alors une valeur nulle est utilisée pour snmpEngineBoots et snmpEngineTime. Cette valeur nulle est utilisée si snmpEngineID est vide.

    Les valeurs sont encodées respectivement en INTEGER dans les champs msgAuthoritativeEngineBoots et msgAuthoritativeEngineTime des securityParameters.

  7. Le userName est encodé en OCTET STRING dans le champ msgUserName des securityParameters.

  8. a) Si le securityLevel spécifie que le message doit être authentifié, le message est authentifié selon le protocole d'authentification de l'utilisateur. Pour ce faire, un appel est effectué au module d'authentification qui implémente le protocole d'authentification de l'utilisateur selon la primitive de service abstraite :

    statusInformation =
    authenticateOutgoingMsg(
    IN authKey -- the user's localized authKey
    IN wholeMsg -- unauthenticated message
    OUT authenticatedWholeMsg -- authenticated complete message
    )
    • statusInformation indique si l'authentification a réussi ou non.

    • authKey l'authKey localisée privée de l'utilisateur est la clé secrète qui peut être utilisée par l'algorithme d'authentification.

    • wholeMsg le message sérialisé complet à authentifier.

    • authenticatedWholeMsg identique à l'entrée donnée au service authenticateOutgoingMsg, mais avec msgAuthenticationParameters correctement rempli.

    Si le module d'authentification renvoie un échec, alors le message ne peut pas être envoyé et une indication d'erreur (authenticationFailure) est renvoyée au module appelant.

    Si le module d'authentification renvoie un succès, alors le champ msgAuthenticationParameters est placé dans les securityParameters et authenticatedWholeMsg représente la sérialisation du message authentifié en cours de préparation.

    Sinon,

    b) Si le securityLevel spécifie que le message ne doit pas être authentifié, alors un OCTET STRING de longueur nulle est encodé dans le champ msgAuthenticationParameters des securityParameters. Le wholeMsg est maintenant sérialisé et représente ensuite le message non authentifié en cours de préparation.

  9. Le message complet avec sa longueur est renvoyé au module appelant avec statusInformation défini sur succès.

3.2. Traitement d'un message SNMP entrant

Cette section décrit la procédure suivie par un moteur SNMP chaque fois qu'il reçoit un message contenant une opération de gestion au nom d'un utilisateur, avec un securityLevel particulier.

Pour simplifier les éléments de procédure, la libération des informations d'état n'est pas toujours explicitement spécifiée. En règle générale, si des informations d'état sont disponibles lorsqu'un message est supprimé, les informations d'état doivent également être libérées. De plus, une indication d'erreur peut renvoyer un OID et une valeur pour un compteur incrémenté et éventuellement une valeur pour securityLevel, et des valeurs pour contextEngineID ou contextName pour le compteur. En outre, les données securityStateReference sont renvoyées si de telles informations sont disponibles au point où l'erreur est détectée.

  1. Si les securityParameters reçus ne sont pas la sérialisation (selon les conventions de [RFC3417]) d'un OCTET STRING formaté selon les UsmSecurityParameters définis dans la section 2.4, alors le compteur snmpInASNParseErrs [RFC3418] est incrémenté et une indication d'erreur (parseError) est renvoyée au module appelant. Notez que nous revenons sans l'OID et la valeur du compteur incrémenté, car dans ce cas il n'y a pas assez d'informations pour générer un PDU de rapport.

  2. Les valeurs des champs de paramètres de sécurité sont extraites des securityParameters. Le securityEngineID à renvoyer à l'appelant est la valeur du champ msgAuthoritativeEngineID. Les cachedSecurityData sont préparées et un securityStateReference est préparé pour référencer ces données. Les valeurs à mettre en cache sont :

    msgUserName

  3. Si la valeur du champ msgAuthoritativeEngineID dans les securityParameters est inconnue alors :

    a) un moteur SNMP non autoritatif qui effectue la découverte peut éventuellement créer une nouvelle entrée dans son Local Configuration Datastore (LCD) et continuer le traitement ;

    ou

    b) le compteur usmStatsUnknownEngineIDs est incrémenté et une indication d'erreur (unknownEngineID) ainsi que l'OID et la valeur du compteur incrémenté sont renvoyés au module appelant.

    Notez que dans le cas où un msgAuthoritativeEngineID de longueur nulle ou d'une taille illégale est reçu, b) devrait être choisi pour faciliter la découverte d'engineID. Sinon, le choix entre a) et b) est une question d'implémentation.

  4. Les informations sur la valeur des champs msgUserName et msgAuthoritativeEngineID sont extraites du Local Configuration Datastore (LCD, usmUserTable). Si aucune information n'est disponible pour l'utilisateur, alors le compteur usmStatsUnknownUserNames est incrémenté et une indication d'erreur (unknownSecurityName) ainsi que l'OID et la valeur du compteur incrémenté sont renvoyés au module appelant.

  5. Si les informations sur l'utilisateur indiquent qu'il ne prend pas en charge le securityLevel demandé par l'appelant, alors le compteur usmStatsUnsupportedSecLevels est incrémenté et une indication d'erreur (unsupportedSecurityLevel) ainsi que l'OID et la valeur du compteur incrémenté sont renvoyés au module appelant.

  6. Si le securityLevel spécifie que le message doit être authentifié, alors le message est authentifié selon le protocole d'authentification de l'utilisateur. Pour ce faire, un appel est effectué au module d'authentification qui implémente le protocole d'authentification de l'utilisateur selon la primitive de service abstraite :

    statusInformation =          -- success or failure
    authenticateIncomingMsg(
    IN authKey -- the user's localized authKey
    IN authParameters -- as received on the wire
    IN wholeMsg -- as received on the wire
    OUT authenticatedWholeMsg -- checked for authentication
    )
    • statusInformation indique si l'authentification a réussi ou non.

    • authKey l'authKey localisée privée de l'utilisateur est la clé secrète qui peut être utilisée par l'algorithme d'authentification.

    • wholeMsg le message sérialisé complet à authentifier.

    • authenticatedWholeMsg identique à l'entrée donnée au service authenticateIncomingMsg, mais après vérification de l'authentification.

    Si le module d'authentification renvoie un échec, alors le message ne peut pas être approuvé, donc le compteur usmStatsWrongDigests est incrémenté et une indication d'erreur (authenticationFailure) ainsi que l'OID et la valeur du compteur incrémenté sont renvoyés au module appelant.

    Si le module d'authentification renvoie un succès, alors le message est authentique et peut être approuvé, donc le traitement continue.

  7. Si le securityLevel indique un message authentifié, alors les valeurs locales de snmpEngineBoots, snmpEngineTime et latestReceivedEngineTime correspondant à la valeur du champ msgAuthoritativeEngineID sont extraites du Local Configuration Datastore.

    a) Si la valeur extraite de msgAuthoritativeEngineID est la même que la valeur de snmpEngineID du moteur SNMP de traitement (ce qui signifie qu'il s'agit du moteur SNMP autoritatif), alors si l'une des conditions suivantes est vraie, le message est considéré comme étant en dehors de la fenêtre temporelle :

    - la valeur locale de snmpEngineBoots est 2147483647 ;

    - la valeur du champ msgAuthoritativeEngineBoots diffère de la valeur locale de snmpEngineBoots ; ou,

    - la valeur du champ msgAuthoritativeEngineTime diffère de la notion locale de snmpEngineTime de plus de +/- 150 secondes.

    Si le message est considéré comme étant en dehors de la fenêtre temporelle, alors le compteur usmStatsNotInTimeWindows est incrémenté et une indication d'erreur (notInTimeWindow) ainsi que l'OID, la valeur du compteur incrémenté et une indication que l'erreur doit être signalée avec un securityLevel de authNoPriv, sont renvoyés au module appelant

    b) Si la valeur extraite de msgAuthoritativeEngineID n'est pas la même que la valeur snmpEngineID du moteur SNMP de traitement (ce qui signifie qu'il ne s'agit pas du moteur SNMP autoritatif), alors :

    1) si au moins une des conditions suivantes est vraie :

    - la valeur extraite du champ msgAuthoritativeEngineBoots est supérieure à la notion locale de la valeur de snmpEngineBoots ; ou,

    - la valeur extraite du champ msgAuthoritativeEngineBoots est égale à la notion locale de la valeur de snmpEngineBoots, et la valeur extraite du champ msgAuthoritativeEngineTime est supérieure à la valeur de latestReceivedEngineTime,

    alors l'entrée LCD correspondant à la valeur extraite du champ msgAuthoritativeEngineID est mise à jour, en définissant :

    - la notion locale de la valeur de snmpEngineBoots sur la valeur du champ msgAuthoritativeEngineBoots,

    - la notion locale de la valeur de snmpEngineTime sur la valeur du champ msgAuthoritativeEngineTime, et

    - le latestReceivedEngineTime sur la valeur de la valeur du champ msgAuthoritativeEngineTime.

    2) si l'une des conditions suivantes est vraie, alors le message est considéré comme étant en dehors de la fenêtre temporelle :

    - la notion locale de la valeur de snmpEngineBoots est 2147483647 ;

    - la valeur du champ msgAuthoritativeEngineBoots est inférieure à la notion locale de la valeur de snmpEngineBoots ; ou,

    - la valeur du champ msgAuthoritativeEngineBoots est égale à la notion locale de la valeur de snmpEngineBoots et la valeur du champ msgAuthoritativeEngineTime est inférieure de plus de 150 secondes à la notion locale de la valeur de snmpEngineTime.

    Si le message est considéré comme étant en dehors de la fenêtre temporelle, alors une indication d'erreur (notInTimeWindow) est renvoyée au module appelant.

    Notez que cela signifie qu'un message trop ancien (éventuellement rejoué) a été détecté et est considéré comme non authentique.

    Notez que cette procédure permet à la valeur de msgAuthoritativeEngineBoots dans le message d'être supérieure à la notion locale de la valeur de snmpEngineBoots pour permettre aux messages reçus d'être acceptés comme authentiques lorsqu'ils sont reçus d'un moteur SNMP autoritatif qui a redémarré depuis que le moteur SNMP récepteur s'est (re-)synchronisé pour la dernière fois.
  8. a) Si le securityLevel indique que le message a été protégé contre la divulgation, alors l'OCTET STRING représentant l'encryptedPDU est déchiffré selon le protocole de confidentialité de l'utilisateur pour obtenir une valeur scopedPDU sérialisée non chiffrée. Pour ce faire, un appel est effectué au module de confidentialité qui implémente le protocole de confidentialité de l'utilisateur selon la primitive abstraite :

    statusInformation =       -- success or failure
    decryptData(
    IN decryptKey -- the user's localized privKey
    IN privParameters -- as received on the wire
    IN encryptedData -- encryptedPDU as received
    OUT decryptedData -- serialized decrypted scopedPDU
    )
    • statusInformation indique si le processus de déchiffrement a réussi ou non.

    • decryptKey la privKey localisée privée de l'utilisateur est la clé secrète qui peut être utilisée par l'algorithme de déchiffrement.

    • privParameters les msgPrivacyParameters, encodés en OCTET STRING.

    • encryptedData l'encryptedPDU représente le scopedPDU chiffré, encodé en OCTET STRING.

    • decryptedData le scopedPDU sérialisé si le déchiffrement réussit.

    Si le module de confidentialité renvoie un échec, alors le message ne peut pas être traité, donc le compteur usmStatsDecryptionErrors est incrémenté et une indication d'erreur (decryptionError) ainsi que l'OID et la valeur du compteur incrémenté sont renvoyés au module appelant.

    Si le module de confidentialité renvoie un succès, alors le scopedPDU déchiffré est la charge utile du message à renvoyer au module appelant.

    Sinon,

    b) Le composant scopedPDU est supposé être en texte clair et est la charge utile du message à renvoyer au module appelant.

  9. Le maxSizeResponseScopedPDU est calculé. C'est la taille maximale autorisée pour un scopedPDU pour un éventuel message de réponse. Une provision est faite pour un en-tête de message qui permet le même securityLevel que la requête reçue.

  10. Le securityName pour l'utilisateur est récupéré de la usmUserTable.

  11. Les données de sécurité sont mises en cache en tant que cachedSecurityData, de sorte qu'une éventuelle réponse à ce message puisse et utilisera les mêmes secrets d'authentification et de confidentialité. Les informations à sauvegarder/mettre en cache sont les suivantes :

    msgUserName, usmUserAuthProtocol, usmUserAuthKey usmUserPrivProtocol, usmUserPrivKey

  12. Le statusInformation est défini sur succès et un retour est effectué vers le module appelant en renvoyant les paramètres OUT comme spécifié dans la primitive processIncomingMsg.