Reeder key localization for AES192/256 encryption implemented
parent
9efc0872d7
commit
6eed8eff24
|
@ -9,6 +9,12 @@ Github `repo <https://github.com/etingof/pysnmp>`_
|
|||
MIB objects. A side effect of this change is that additional
|
||||
var-binds can only be added prior to .resolveMibObjects() is
|
||||
run.
|
||||
- Non-standard (but apparently used by many vendors) Reeder AES192/256
|
||||
key localization algorithm implemented and set as default for
|
||||
usmAesCfb192Protocol and usmAesCfb256Protocol identifiers.
|
||||
Original and more standard implementation can still be used
|
||||
with the usmAesBlumenthalCfb192Protocol and
|
||||
usmAesBlumenthalCfb192Protocol IDs respectively.
|
||||
- Fix to NotificationType to make additional var-binds overriding
|
||||
MIB objects implicitly included through NOTIFICATION-TYPE OBJECTS.
|
||||
- Fix to SNMP engine boots counter persistence on Python 3.
|
||||
|
|
|
@ -29,8 +29,10 @@ usmNoAuthProtocol = noauth.NoAuth.serviceID
|
|||
usmDESPrivProtocol = des.Des.serviceID
|
||||
usm3DESEDEPrivProtocol = des3.Des3.serviceID
|
||||
usmAesCfb128Protocol = aes.Aes.serviceID
|
||||
usmAesCfb192Protocol = aes192.Aes192.serviceID
|
||||
usmAesCfb256Protocol = aes256.Aes256.serviceID
|
||||
usmAesBlumenthalCfb192Protocol = aes192.Aes192.serviceID # semi-standard but not widely used
|
||||
usmAesBlumenthalCfb256Protocol = aes256.Aes256.serviceID # semi-standard but not widely used
|
||||
usmAesCfb192Protocol = aes192.AesReeder192.serviceID # non-standard but used by many vendors
|
||||
usmAesCfb256Protocol = aes256.AesReeder256.serviceID # non-standard but used by many vendors
|
||||
usmNoPrivProtocol = nopriv.NoPriv.serviceID
|
||||
|
||||
# Auth services
|
||||
|
@ -44,6 +46,8 @@ privServices = {des.Des.serviceID: des.Des(),
|
|||
aes.Aes.serviceID: aes.Aes(),
|
||||
aes192.Aes192.serviceID: aes192.Aes192(),
|
||||
aes256.Aes256.serviceID: aes256.Aes256(),
|
||||
aes192.AesReeder192.serviceID: aes192.AesReeder192(), # non-standard
|
||||
aes256.AesReeder256.serviceID: aes256.AesReeder256(), # non-standard
|
||||
nopriv.NoPriv.serviceID: nopriv.NoPriv()}
|
||||
|
||||
|
||||
|
|
|
@ -8,9 +8,26 @@ from pysnmp.proto.secmod.eso.priv import aesbase
|
|||
|
||||
|
||||
class Aes192(aesbase.AbstractAes):
|
||||
"""AES 192/256 bit encryption (Internet draft)
|
||||
"""AES 192 bit encryption (Internet draft)
|
||||
|
||||
Reeder AES encryption:
|
||||
|
||||
http://tools.ietf.org/html/draft-blumenthal-aes-usm-04
|
||||
"""
|
||||
serviceID = (1, 3, 6, 1, 4, 1, 9, 12, 6, 1, 1) # cusmAESCfb192PrivProtocol
|
||||
keySize = 24
|
||||
|
||||
|
||||
class AesReeder192(aesbase.AbstractAesReeder):
|
||||
"""AES 192 bit encryption (Internet draft)
|
||||
|
||||
Reeder AES encryption with non-standard key localization algorithm
|
||||
borrowed from Reeder 3DES draft:
|
||||
|
||||
http://tools.ietf.org/html/draft-blumenthal-aes-usm-04
|
||||
https://tools.ietf.org/html/draft-reeder-snmpv3-usm-3desede-00
|
||||
|
||||
Known to be used by many vendors including Cisco and others.
|
||||
"""
|
||||
serviceID = (1, 3, 6, 1, 4, 1, 9, 12, 6, 1, 101) # cusmAESCfb192PrivProtocol (non-standard)
|
||||
keySize = 24
|
||||
|
|
|
@ -8,9 +8,24 @@ from pysnmp.proto.secmod.eso.priv import aesbase
|
|||
|
||||
|
||||
class Aes256(aesbase.AbstractAes):
|
||||
"""AES 192/256 bit encryption (Internet draft)
|
||||
"""AES 256 bit encryption (Internet draft)
|
||||
|
||||
http://tools.ietf.org/html/draft-blumenthal-aes-usm-04
|
||||
"""
|
||||
serviceID = (1, 3, 6, 1, 4, 1, 9, 12, 6, 1, 2) # cusmAESCfb256PrivProtocol
|
||||
keySize = 32
|
||||
|
||||
|
||||
class AesReeder256(aesbase.AbstractAesReeder):
|
||||
"""AES 256 bit encryption (Internet draft)
|
||||
|
||||
Reeder AES encryption with non-standard key localization algorithm
|
||||
borrowed from Reeder 3DES draft:
|
||||
|
||||
http://tools.ietf.org/html/draft-blumenthal-aes-usm-04
|
||||
https://tools.ietf.org/html/draft-reeder-snmpv3-usm-3desede-00
|
||||
|
||||
Known to be used by many vendors including Cisco and others.
|
||||
"""
|
||||
serviceID = (1, 3, 6, 1, 4, 1, 9, 12, 6, 1, 102) # cusmAESCfb256PrivProtocol (non-standard)
|
||||
keySize = 32
|
||||
|
|
|
@ -41,3 +41,39 @@ class AbstractAes(aes.Aes):
|
|||
'Unknown auth protocol %s' % (authProtocol,)
|
||||
)
|
||||
return localPrivKey[:self.keySize]
|
||||
|
||||
|
||||
class AbstractAesReeder(AbstractAes):
|
||||
"""AES encryption with non-standard key localization.
|
||||
|
||||
Cisco devices do not use:
|
||||
|
||||
https://tools.itef.org/pdf/draft_bluementhal-aes-usm-04.txt
|
||||
|
||||
for key localization instead, they use the procedure for 3DES key localization
|
||||
specified in:
|
||||
|
||||
https://tools.itef.org/pdf/draft_reeder_snmpv3-usm-3desede-00.pdf
|
||||
|
||||
The difference between the two is that the Reeder draft does key extension by repeating
|
||||
the steps in the password to key algorithm (hash phrase, then localize with SNMPEngine ID).
|
||||
"""
|
||||
|
||||
# 2.1 of https://tools.itef.org/pdf/draft_bluementhal-aes-usm-04.txt
|
||||
def localizeKey(self, authProtocol, privKey, snmpEngineID):
|
||||
if authProtocol == hmacmd5.HmacMd5.serviceID:
|
||||
localPrivKey = localkey.localizeKeyMD5(privKey, snmpEngineID)
|
||||
# now extend this key if too short by repeating steps that includes the hashPassphrase step
|
||||
while len(localPrivKey) < self.keySize:
|
||||
newKey = hashPassphraseMD5(localPrivKey) # this is the difference between reeder and bluementhal
|
||||
localPrivKey += localizeKeyMD5(newKey, snmpEngineID)
|
||||
elif authProtocol == hmacsha.HmacSha.serviceID:
|
||||
localPrivKey = localkey.localizeKeySHA(privKey, snmpEngineID)
|
||||
while len(localPrivKey < self.keySize):
|
||||
newKey = hashPassphraseSHA(localPrivKey)
|
||||
localPrivKey += localizeKeySHA(newKey, snmpEngineID)
|
||||
else:
|
||||
raise error.ProtocolError(
|
||||
'Unknown auth protocol %s' % (authProtocol,)
|
||||
)
|
||||
return localPrivKey[:self.keySize]
|
||||
|
|
|
@ -46,6 +46,8 @@ class SnmpUSMSecurityModel(AbstractSecurityModel):
|
|||
aes.Aes.serviceID: aes.Aes(),
|
||||
aes192.Aes192.serviceID: aes192.Aes192(),
|
||||
aes256.Aes256.serviceID: aes256.Aes256(),
|
||||
aes192.AesReeder192.serviceID: aes192.AesReeder192(), # non-standard
|
||||
aes256.AesReeder256.serviceID: aes256.AesReeder256(), # non-standard
|
||||
nopriv.NoPriv.serviceID: nopriv.NoPriv()}
|
||||
|
||||
def __init__(self):
|
||||
|
|
Loading…
Reference in New Issue