summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelie <elie>2007-07-09 13:39:47 +0000
committerelie <elie>2007-07-09 13:39:47 +0000
commit1e519091d197e17acf5c6363d7c25b5ffd98ad08 (patch)
tree82a986ebc97f321911c64f7ec9cfd12d27e648c4
parent3517969eaf8fce91f9f43b19fa280e8d376f7dfb (diff)
downloadpysnmp-1e519091d197e17acf5c6363d7c25b5ffd98ad08.tar.gz
added support for AES cipher (rfc3826)
-rw-r--r--CHANGES5
-rw-r--r--README2
-rw-r--r--docs/pysnmp-tutorial.html3
-rw-r--r--examples/v3arch/agent/cmdrsp.py1
-rw-r--r--examples/v3arch/manager/getgen.py1
-rw-r--r--pysnmp/entity/config.py5
-rw-r--r--pysnmp/entity/rfc3413/oneliner/cmdgen.py1
-rw-r--r--pysnmp/entity/rfc3413/oneliner/ntforg.py1
-rw-r--r--pysnmp/proto/secmod/rfc3414/priv/des.py30
-rw-r--r--pysnmp/proto/secmod/rfc3414/service.py100
-rw-r--r--pysnmp/proto/secmod/rfc3826/__init__.py0
-rw-r--r--pysnmp/proto/secmod/rfc3826/priv/__init__.py0
-rw-r--r--pysnmp/proto/secmod/rfc3826/priv/aes.py115
-rw-r--r--pysnmp/smi/mibs/SNMP-USM-AES-MIB.py28
14 files changed, 228 insertions, 64 deletions
diff --git a/CHANGES b/CHANGES
index 4484237..061b8b8 100644
--- a/CHANGES
+++ b/CHANGES
@@ -33,6 +33,7 @@ Revision 4.1.8a
respectively.
- Multi-target oneliner API-based example script added.
- Ignore more socket errors in datagram-type async socket code.
+- AES cipher now supported (rfc3826).
Revision 4.1.7a
---------------
@@ -82,14 +83,14 @@ Revision 4.1.7a
- Memory leak fixed in indices.OidOrderedDict implementation.
- Fix to VACM shortcuts to let notifications and requests to co-exist
for the same user otherwise.
-- Fix to ...oneliner.cmdgen.UsmUserData to support non-default cyphers.
+- Fix to ...oneliner.cmdgen.UsmUserData to support non-default ciphers.
- USM now uses local notion of snmpEngineBoots/Time when authoritative
and cached estimate otherwise. Also, a security fix applied to to USM
time-window verification (SF bug #1649032).
- Fix to notification objects resolution code at
NotificationOriginator.sendNotification()
- Do not raise securityLevel for USM error reports that lacks user
- information, as these reports could never be cyphered (SF bug #1624720).
+ information, as these reports could never be ciphered (SF bug #1624720).
- Non-default BULK PDU params now actually applied.
- SnmpEngineID default value generation algorithmic function changed
to allow multiple SNMP engines running on the same host.
diff --git a/README b/README
index b3de22c..13fd291 100644
--- a/README
+++ b/README
@@ -21,7 +21,7 @@ FEATURES
Features, specific to SNMPv3 model include:
-* USM authentication (MD5/SHA) and privacy (DES) protocols (RFC3414)
+* USM authentication (MD5/SHA) and privacy (DES/AES) protocols (RFC3414)
* View-based access control to use with any SNMP model (RFC3415)
* Built-in SNMP proxy PDU converter for building multi-lingual
SNMP entities (RFC2576)
diff --git a/docs/pysnmp-tutorial.html b/docs/pysnmp-tutorial.html
index ea29a04..9e5e363 100644
--- a/docs/pysnmp-tutorial.html
+++ b/docs/pysnmp-tutorial.html
@@ -1463,7 +1463,8 @@ non-default hash function algorithm. Possible values include
<P>
Optional <STRONG>privProtocol</STRONG> parameter may be used to specify
non-default ciphering algorithm. Possible values include
-<STRONG>usmDESPrivProtocol</STRONG> and
+<STRONG>usmDESPrivProtocol</STRONG>,
+<STRONG>usmAesCfb128Protocol</STRONG>, and
<STRONG>usmNoPrivProtocol</STRONG>.
</P>
</DD>
diff --git a/examples/v3arch/agent/cmdrsp.py b/examples/v3arch/agent/cmdrsp.py
index 1748ba5..3d147f0 100644
--- a/examples/v3arch/agent/cmdrsp.py
+++ b/examples/v3arch/agent/cmdrsp.py
@@ -34,6 +34,7 @@ config.addV3User(
snmpEngine, 'test-user',
config.usmHMACMD5AuthProtocol, 'authkey1',
config.usmDESPrivProtocol, 'privkey1'
+# config.usmAesCfb128Protocol, 'privkey1'
)
# Install default Agent configuration
diff --git a/examples/v3arch/manager/getgen.py b/examples/v3arch/manager/getgen.py
index 115d008..ed8b7f4 100644
--- a/examples/v3arch/manager/getgen.py
+++ b/examples/v3arch/manager/getgen.py
@@ -13,6 +13,7 @@ config.addV3User(
snmpEngine, 'test-user',
config.usmHMACMD5AuthProtocol, 'authkey1',
config.usmDESPrivProtocol, 'privkey1'
+# config.usmAesCfb128Protocol, 'privkey1'
)
# Transport params
diff --git a/pysnmp/entity/config.py b/pysnmp/entity/config.py
index eb4485a..a9ee81b 100644
--- a/pysnmp/entity/config.py
+++ b/pysnmp/entity/config.py
@@ -13,6 +13,7 @@ from pysnmp.proto.secmod.rfc3414 import localkey
from pysnmp.entity import engine
from pysnmp.proto.secmod.rfc3414.auth import hmacmd5, hmacsha, noauth
from pysnmp.proto.secmod.rfc3414.priv import des, nopriv
+from pysnmp.proto.secmod.rfc3826.priv import aes
from pysnmp.smi.error import NotWritableError
from pysnmp import error
@@ -28,6 +29,7 @@ usmNoAuthProtocol = noauth.NoAuth.serviceID
# Privacy protocol
usmDESPrivProtocol = des.Des.serviceID
+usmAesCfb128Protocol = aes.Aes.serviceID
usmNoPrivProtocol = nopriv.NoPriv.serviceID
def __cookV1SystemInfo(snmpEngine, securityName):
@@ -136,7 +138,8 @@ def addV3User(snmpEngine, securityName,
else:
raise error.PySnmpError('Unknown auth protocol %s' % (authProtocol,))
- if privProtocol == usmDESPrivProtocol:
+ if privProtocol == usmDESPrivProtocol or \
+ privProtocol == usmAesCfb128Protocol:
if authProtocol == usmHMACMD5AuthProtocol:
hashedPrivPassphrase = localkey.hashPassphraseMD5(
privKey and privKey or ''
diff --git a/pysnmp/entity/rfc3413/oneliner/cmdgen.py b/pysnmp/entity/rfc3413/oneliner/cmdgen.py
index 2377bcd..36db105 100644
--- a/pysnmp/entity/rfc3413/oneliner/cmdgen.py
+++ b/pysnmp/entity/rfc3413/oneliner/cmdgen.py
@@ -13,6 +13,7 @@ usmNoAuthProtocol = config.usmNoAuthProtocol
# Privacy protocol
usmDESPrivProtocol = config.usmDESPrivProtocol
+usmAesCfb128Protocol = config.usmAesCfb128Protocol
usmNoPrivProtocol = config.usmNoPrivProtocol
class CommunityData:
diff --git a/pysnmp/entity/rfc3413/oneliner/ntforg.py b/pysnmp/entity/rfc3413/oneliner/ntforg.py
index 467cc90..bc29431 100644
--- a/pysnmp/entity/rfc3413/oneliner/ntforg.py
+++ b/pysnmp/entity/rfc3413/oneliner/ntforg.py
@@ -10,6 +10,7 @@ usmNoAuthProtocol = cmdgen.usmNoAuthProtocol
# Privacy protocol
usmDESPrivProtocol = cmdgen.usmDESPrivProtocol
+usmAesCfb128Protocol = cmdgen.usmAesCfb128Protocol
usmNoPrivProtocol = cmdgen.usmNoPrivProtocol
# Credentials
diff --git a/pysnmp/proto/secmod/rfc3414/priv/des.py b/pysnmp/proto/secmod/rfc3414/priv/des.py
index fd2c553..d8bb7e8 100644
--- a/pysnmp/proto/secmod/rfc3414/priv/des.py
+++ b/pysnmp/proto/secmod/rfc3414/priv/des.py
@@ -16,14 +16,11 @@ class Des(base.AbstractEncryptionService):
serviceID = (1, 3, 6, 1, 6, 3, 10, 1, 2, 2) # usmDESPrivProtocol
_localInt = long(random.random()*0xffffffffL)
# 8.1.1.1
- def __getEncryptionKey(self, mibInstrumController, privKey):
+ def __getEncryptionKey(self, privKey, snmpEngineBoots):
desKey = privKey[:8]
preIV = privKey[8:16]
- snmpEngineBoots, = mibInstrumController.mibBuilder.importSymbols(
- '__SNMP-FRAMEWORK-MIB', 'snmpEngineBoots'
- )
- securityEngineBoots = long(snmpEngineBoots.syntax)
+ securityEngineBoots = long(snmpEngineBoots)
salt = [
securityEngineBoots>>24&0xff,
@@ -44,28 +41,30 @@ class Des(base.AbstractEncryptionService):
string.join(map(lambda x: chr(x), salt), ''), \
string.join(map(lambda x,y: chr(x^ord(y)), salt, preIV), '')
- def __getDecryptionKey(self, mibInstrumController, privKey, salt):
+ def __getDecryptionKey(self, privKey, salt):
return privKey[:8], string.join(
map(lambda x,y: chr(ord(x)^ord(y)), salt, privKey[8:16]), ''
)
# 8.2.4.1
- def encryptData(self, mibInstrumController, encryptKey, dataToEncrypt):
+ def encryptData(self, encryptKey, privParameters, dataToEncrypt):
if DES is None:
raise error.StatusInformation(
errorIndication='encryptionError'
)
+
+ snmpEngineBoots, snmpEngineTime, salt = privParameters
# 8.3.1.1
desKey, salt, iv = self.__getEncryptionKey(
- mibInstrumController, str(encryptKey)
+ str(encryptKey), snmpEngineBoots
)
# 8.3.1.2
privParameters = univ.OctetString(salt)
# 8.1.1.2
- desObj = DES.new(desKey, DES.MODE_CBC, iv) # XXX
+ desObj = DES.new(desKey, DES.MODE_CBC, iv)
plaintext = dataToEncrypt + '\x00' * (8 - len(dataToEncrypt) % 8)
ciphertext = desObj.encrypt(plaintext)
@@ -73,26 +72,25 @@ class Des(base.AbstractEncryptionService):
return univ.OctetString(ciphertext), privParameters
# 8.2.4.2
- def decryptData(self, mibInstrumController, decryptKey,
- privParameters, encryptedData):
+ def decryptData(self, decryptKey, privParameters, encryptedData):
if DES is None:
raise error.StatusInformation(
errorIndication='decryptionError'
)
+
+ snmpEngineBoots, snmpEngineTime, salt = privParameters
# 8.3.2.1
- if len(privParameters) != 8:
+ if len(salt) != 8:
raise error.StatusInformation(
errorIndication='decryptionError'
)
# 8.3.2.2
- salt = str(privParameters)
+ salt = str(salt)
# 8.3.2.3
- desKey, iv = self.__getDecryptionKey(
- mibInstrumController, str(decryptKey), salt
- )
+ desKey, iv = self.__getDecryptionKey(str(decryptKey), salt)
# 8.3.2.4 -> 8.1.1.3
if len(encryptedData) % 8 != 0:
diff --git a/pysnmp/proto/secmod/rfc3414/service.py b/pysnmp/proto/secmod/rfc3414/service.py
index 90c2cfa..2e07337 100644
--- a/pysnmp/proto/secmod/rfc3414/service.py
+++ b/pysnmp/proto/secmod/rfc3414/service.py
@@ -2,6 +2,7 @@
from pysnmp.proto.secmod.base import AbstractSecurityModel
from pysnmp.proto.secmod.rfc3414.auth import hmacmd5, hmacsha, noauth
from pysnmp.proto.secmod.rfc3414.priv import des, nopriv
+from pysnmp.proto.secmod.rfc3826.priv import aes
from pysnmp.proto.secmod.rfc3414 import localkey
from pysnmp.smi.error import NoSuchInstanceError
from pysnmp.proto import rfc1155, error
@@ -33,6 +34,7 @@ class SnmpUSMSecurityModel(AbstractSecurityModel):
}
privServices = {
des.Des.serviceID: des.Des(),
+ aes.Aes.serviceID: aes.Aes(),
nopriv.NoPriv.serviceID: nopriv.NoPriv()
}
_securityParametersSpec = UsmSecurityParameters()
@@ -159,7 +161,8 @@ class SnmpUSMSecurityModel(AbstractSecurityModel):
pysnmpUsmKeyPrivLocalized = pysnmpUsmKeyEntry.getNode(
pysnmpUsmKeyEntry.name + (2,) + tblIdx
)
- if usmUserPrivProtocol.syntax == des.Des.serviceID:
+ if usmUserPrivProtocol.syntax == des.Des.serviceID or \
+ usmUserPrivProtocol.syntax == aes.Aes.serviceID:
if usmUserAuthProtocol.syntax == hmacsha.HmacSha.serviceID:
localPrivKey = localkey.localizeKeySHA(
pysnmpUsmKeyPriv.syntax, securityEngineID
@@ -277,38 +280,6 @@ class SnmpUSMSecurityModel(AbstractSecurityModel):
scopedPDUData = msg.setComponentByPosition(3).getComponentByPosition(3)
scopedPDUData.setComponentByPosition(0, scopedPDU)
- # 3.1.4a
- if securityLevel == 3:
- privHandler = self.privServices.get(usmUserPrivProtocol)
- if privHandler is None:
- raise error.StatusInformation(
- errorIndication = 'encryptionError'
- )
- dataToEncrypt = encoder.encode(scopedPDU)
-
- debug.logger & debug.flagSM and debug.logger('__generateRequestOrResponseMsg: scopedPDU encoded')
-
- try:
- ( encryptedData,
- privParameters ) = privHandler.encryptData(
- snmpEngine.msgAndPduDsp.mibInstrumController,
- usmUserPrivKeyLocalized, dataToEncrypt
- )
- except error.StatusInformation, statusInformation:
- raise
-
- debug.logger & debug.flagSM and debug.logger('__generateRequestOrResponseMsg: scopedPDU cyphered')
-
- securityParameters.setComponentByPosition(5, privParameters)
- scopedPDUData.setComponentByPosition(1, encryptedData)
-
- # 3.1.4b
- elif securityLevel == 1 or securityLevel == 2:
- securityParameters.setComponentByPosition(5, '')
-
- # 3.1.5
- securityParameters.setComponentByPosition(0, securityEngineID)
-
# 3.1.6a
if securityStateReference is None and ( # request type check added
securityLevel == 3 or securityLevel == 2
@@ -338,7 +309,41 @@ class SnmpUSMSecurityModel(AbstractSecurityModel):
debug.logger & debug.flagSM and debug.logger('__generateRequestOrResponseMsg: assuming zero snmpEngineBoots, snmpEngineTime')
debug.logger & debug.flagSM and debug.logger('__generateRequestOrResponseMsg: use snmpEngineBoots %s snmpEngineTime %s for securityEngineID %s' % (snmpEngineBoots, snmpEngineTime, securityEngineID))
+
+ # 3.1.4a
+ if securityLevel == 3:
+ privHandler = self.privServices.get(usmUserPrivProtocol)
+ if privHandler is None:
+ raise error.StatusInformation(
+ errorIndication = 'encryptionError'
+ )
+ dataToEncrypt = encoder.encode(scopedPDU)
+
+ debug.logger & debug.flagSM and debug.logger('__generateRequestOrResponseMsg: scopedPDU encoded')
+
+ try:
+ ( encryptedData,
+ privParameters ) = privHandler.encryptData(
+ usmUserPrivKeyLocalized,
+ ( snmpEngineBoots, snmpEngineTime, None ),
+ dataToEncrypt
+ )
+ except error.StatusInformation, statusInformation:
+ raise
+
+ securityParameters.setComponentByPosition(5, privParameters)
+ scopedPDUData.setComponentByPosition(1, encryptedData)
+
+ debug.logger & debug.flagSM and debug.logger('__generateRequestOrResponseMsg: scopedPDU ciphered')
+
+ # 3.1.4b
+ elif securityLevel == 1 or securityLevel == 2:
+ securityParameters.setComponentByPosition(5, '')
+
+ debug.logger & debug.flagSM and debug.logger('__generateRequestOrResponseMsg: %s' % scopedPDUData.prettyPrint())
+ # 3.1.5
+ securityParameters.setComponentByPosition(0, securityEngineID)
securityParameters.setComponentByPosition(1, snmpEngineBoots)
securityParameters.setComponentByPosition(2, snmpEngineTime)
@@ -699,7 +704,7 @@ class SnmpUSMSecurityModel(AbstractSecurityModel):
)
scopedPduData = msg.getComponentByPosition(3)
-
+
# 3.2.8a
if securityLevel == 3:
privHandler = self.privServices.get(usmUserPrivProtocol)
@@ -709,16 +714,19 @@ class SnmpUSMSecurityModel(AbstractSecurityModel):
)
encryptedPDU = scopedPduData.getComponentByPosition(1)
if encryptedPDU is None: # no ciphertext
- raise error.StatusInformation(
+ raise error.StatusInformation(
errorIndication = 'decryptionError'
- )
+ )
+
try:
- decryptedData = privHandler.decryptData(
- snmpEngine.msgAndPduDsp.mibInstrumController, usmUserPrivKeyLocalized,
- securityParameters.getComponentByPosition(5),
+ decryptedData = privHandler.decryptData(
+ usmUserPrivKeyLocalized,
+ ( securityParameters.getComponentByPosition(1),
+ securityParameters.getComponentByPosition(2),
+ securityParameters.getComponentByPosition(5) ),
encryptedPDU
)
- debug.logger & debug.flagSM and debug.logger('processIncomingMsg: PDU decyphered')
+ debug.logger & debug.flagSM and debug.logger('processIncomingMsg: PDU deciphered')
except error.StatusInformation:
usmStatsDecryptionErrors, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-USER-BASED-SM-MIB', 'usmStatsDecryptionErrors')
usmStatsDecryptionErrors.syntax = usmStatsDecryptionErrors.syntax+1
@@ -732,9 +740,15 @@ class SnmpUSMSecurityModel(AbstractSecurityModel):
maxSizeResponseScopedPDU=maxSizeResponseScopedPDU
)
scopedPduSpec = scopedPduData.setComponentByPosition(0).getComponentByPosition(0)
- scopedPDU, rest = decoder.decode(
- decryptedData, asn1Spec=scopedPduSpec
- )
+ try:
+ scopedPDU, rest = decoder.decode(
+ decryptedData, asn1Spec=scopedPduSpec
+ )
+ except PyAsn1Error, why:
+ debug.logger & debug.flagSM and debug.logger('processIncomingMsg: PDU decoder failed %s' % why)
+ raise error.StatusInformation(
+ errorIndication = 'decryptionError'
+ )
else:
# 3.2.8b
scopedPDU = scopedPduData.getComponentByPosition(0)
diff --git a/pysnmp/proto/secmod/rfc3826/__init__.py b/pysnmp/proto/secmod/rfc3826/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pysnmp/proto/secmod/rfc3826/__init__.py
diff --git a/pysnmp/proto/secmod/rfc3826/priv/__init__.py b/pysnmp/proto/secmod/rfc3826/priv/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pysnmp/proto/secmod/rfc3826/priv/__init__.py
diff --git a/pysnmp/proto/secmod/rfc3826/priv/aes.py b/pysnmp/proto/secmod/rfc3826/priv/aes.py
new file mode 100644
index 0000000..d1286c8
--- /dev/null
+++ b/pysnmp/proto/secmod/rfc3826/priv/aes.py
@@ -0,0 +1,115 @@
+import random, string
+from pysnmp.proto.secmod.rfc3414.priv import base
+from pyasn1.type import univ
+from pysnmp.proto import error
+
+try:
+ from Crypto.Cipher import AES
+except ImportError:
+ AES = None
+
+random.seed()
+
+# RFC3826
+
+#
+
+class Aes(base.AbstractEncryptionService):
+ serviceID = (1, 3, 6, 1, 6, 3, 10, 1, 2, 4) # usmAesCfb128Protocol
+ _localInt = long(random.random()*0xffffffffffffffffL)
+ # 3.1.2.1
+ def __getEncryptionKey(self, privKey, snmpEngineBoots, snmpEngineTime):
+ salt = [
+ self._localInt>>56&0xff,
+ self._localInt>>48&0xff,
+ self._localInt>>40&0xff,
+ self._localInt>>32&0xff,
+ self._localInt>>24&0xff,
+ self._localInt>>16&0xff,
+ self._localInt>>8&0xff,
+ self._localInt&0xff
+ ]
+
+ if self._localInt == 0xffffffffffffffffL:
+ self._localInt = 0
+ else:
+ self._localInt = self._localInt + 1
+
+ salt = string.join(map(lambda x: chr(x), salt), '')
+
+ return self.__getDecryptionKey(privKey, snmpEngineBoots,
+ snmpEngineTime, salt) + ( salt, )
+
+ def __getDecryptionKey(self, privKey, snmpEngineBoots,
+ snmpEngineTime, salt):
+ snmpEngineBoots, snmpEngineTime, salt = (
+ long(snmpEngineBoots), long(snmpEngineTime), str(salt)
+ )
+
+ iv = [
+ snmpEngineBoots>>24&0xff,
+ snmpEngineBoots>>16&0xff,
+ snmpEngineBoots>>8&0xff,
+ snmpEngineBoots&0xff,
+ snmpEngineTime>>24&0xff,
+ snmpEngineTime>>16&0xff,
+ snmpEngineTime>>8&0xff,
+ snmpEngineTime&0xff,
+ ord(salt[7]),
+ ord(salt[6]),
+ ord(salt[5]),
+ ord(salt[4]),
+ ord(salt[3]),
+ ord(salt[2]),
+ ord(salt[1]),
+ ord(salt[0])
+ ]
+
+ return privKey[:16], string.join(map(lambda x: chr(x), iv), '')
+
+
+ # 3.2.4.1
+ def encryptData(self, encryptKey, privParameters, dataToEncrypt):
+ if AES is None:
+ raise error.StatusInformation(
+ errorIndication='encryptionError'
+ )
+
+ snmpEngineBoots, snmpEngineTime, salt = privParameters
+
+ # 3.3.1.1
+ aesKey, iv, salt = self.__getEncryptionKey(
+ str(encryptKey), snmpEngineBoots, snmpEngineTime
+ )
+
+ # 3.3.1.3
+ aesObj = AES.new(aesKey, AES.MODE_CFB, iv)
+ ciphertext = aesObj.encrypt(dataToEncrypt)
+
+ # 3.3.1.4
+ return univ.OctetString(ciphertext), salt
+
+ # 3.2.4.2
+ def decryptData(self, decryptKey, privParameters, encryptedData):
+ if AES is None:
+ raise error.StatusInformation(
+ errorIndication='decryptionError'
+ )
+
+ snmpEngineBoots, snmpEngineTime, salt = privParameters
+
+ # 3.3.2.1
+ if len(salt) != 8:
+ raise error.StatusInformation(
+ errorIndication='decryptionError'
+ )
+
+ # 3.3.2.3
+ aesKey, iv = self.__getDecryptionKey(
+ str(decryptKey), snmpEngineBoots, snmpEngineTime, salt
+ )
+
+ aesObj = AES.new(aesKey, AES.MODE_CFB, iv)
+
+ # 3.3.2.4-6
+ return aesObj.decrypt(str(encryptedData))
diff --git a/pysnmp/smi/mibs/SNMP-USM-AES-MIB.py b/pysnmp/smi/mibs/SNMP-USM-AES-MIB.py
new file mode 100644
index 0000000..8097260
--- /dev/null
+++ b/pysnmp/smi/mibs/SNMP-USM-AES-MIB.py
@@ -0,0 +1,28 @@
+# PySNMP SMI module. Autogenerated from smidump -f python SNMP-USM-AES-MIB
+# by libsmi2pysnmp-0.0.7-alpha at Mon Jul 9 17:29:49 2007,
+# Python version (2, 4, 3, 'final', 0)
+
+# Imported just in case new ASN.1 types would be created
+from pyasn1.type import constraint, namedval
+
+# Imports
+
+( Integer, ObjectIdentifier, OctetString, ) = mibBuilder.importSymbols("ASN1", "Integer", "ObjectIdentifier", "OctetString")
+( snmpPrivProtocols, ) = mibBuilder.importSymbols("SNMP-FRAMEWORK-MIB", "snmpPrivProtocols")
+( Bits, Integer32, ModuleIdentity, MibIdentifier, ObjectIdentity, TimeTicks, snmpModules, ) = mibBuilder.importSymbols("SNMPv2-SMI", "Bits", "Integer32", "ModuleIdentity", "MibIdentifier", "ObjectIdentity", "TimeTicks", "snmpModules")
+
+# Objects
+
+usmAesCfb128Protocol = MibIdentifier((1, 3, 6, 1, 6, 3, 10, 1, 2, 4))
+snmpUsmAesMIB = ModuleIdentity((1, 3, 6, 1, 6, 3, 20)).setRevisions(("2004-06-14 00:00",))
+
+# Augmentions
+
+# Exports
+
+# Module identity
+mibBuilder.exportSymbols("SNMP-USM-AES-MIB", PYSNMP_MODULE_ID=snmpUsmAesMIB)
+
+# Objects
+mibBuilder.exportSymbols("SNMP-USM-AES-MIB", usmAesCfb128Protocol=usmAesCfb128Protocol, snmpUsmAesMIB=snmpUsmAesMIB)
+