6 from kmsBase
import kmsBase
7 from structure
import Structure
9 class kmsRequestV5(kmsBase
):
10 class RequestV5(Structure
):
11 class Message(Structure
):
15 ('encrypted', '236s'), #kmsBase.kmsRequestStruct
21 ('bodyLength1', '<I'),
22 ('bodyLength2', '<I'),
23 ('versionMinor', '<H'),
24 ('versionMajor', '<H'),
25 ('message', ':', Message
),
28 class DecryptedRequest(Structure
):
32 ('request', ':', kmsBase
.kmsRequestStruct
),
35 class ResponseV5(Structure
):
38 ('bodyLength1', '<I=2 + 2 + len(salt) + len(encrypted)'),
39 ('unknown', '!I=0x00000200'),
40 ('bodyLength2', '<I=2 + 2 + len(salt) + len(encrypted)'),
41 ('versionMinor', '<H'),
42 ('versionMajor', '<H'),
44 ('encrypted', ':'), #DecryptedResponse
48 class DecryptedResponse(Structure
):
51 ('response', ':', kmsBase
.kmsResponseStruct
),
56 key
= bytearray([ 0xCD, 0x7E, 0x79, 0x6F, 0x2A, 0xB2, 0x5D, 0xCB, 0x55, 0xFF, 0xC8, 0xEF, 0x83, 0x64, 0xC4, 0x70 ])
62 def executeRequestLogic(self
):
63 self
.requestData
= self
.RequestV5(self
.data
)
65 decrypted
= self
.decryptRequest(self
.requestData
)
67 responseBuffer
= self
.serverLogic(decrypted
['request'])
69 iv
, encrypted
= self
.encryptResponse(self
.requestData
, decrypted
, responseBuffer
)
71 self
.responseData
= self
.generateResponse(iv
, encrypted
)
73 def decryptRequest(self
, request
):
74 encrypted
= bytearray(str(request
['message']))
75 iv
= bytearray(request
['message']['salt'])
77 moo
= aes
.AESModeOfOperation()
79 decrypted
= moo
.decrypt(encrypted
, 256, moo
.modeOfOperation
["CBC"], self
.key
, moo
.aes
.keySize
["SIZE_128"], iv
)
80 decrypted
= aes
.strip_PKCS7_padding(decrypted
)
82 return self
.DecryptedRequest(decrypted
)
84 def encryptResponse(self
, request
, decrypted
, response
):
85 randomSalt
= self
.getRandomSalt()
86 sha256
= hashlib
.sha256()
87 sha256
.update(str(randomSalt
))
88 result
= sha256
.digest()
90 iv
= bytearray(request
['message']['salt'])
92 randomStuff
= bytearray(16)
94 randomStuff
[i
] = (bytearray(decrypted
['salt'])[i
] ^ iv
[i
] ^ randomSalt
[i
]) & 0xff
96 responsedata
= self
.DecryptedResponse()
97 responsedata
['response'] = response
98 responsedata
['keys'] = str(randomStuff
)
99 responsedata
['hash'] = result
101 padded
= aes
.append_PKCS7_padding(str(responsedata
))
102 moo
= aes
.AESModeOfOperation()
104 mode
, orig_len
, crypted
= moo
.encrypt(padded
, moo
.modeOfOperation
["CBC"], self
.key
, moo
.aes
.keySize
["SIZE_128"], iv
)
106 return str(iv
), str(bytearray(crypted
))
108 def decryptResponse(self
, response
):
109 paddingLength
= response
['bodyLength1'] % 8
110 iv
= bytearray(response
['salt'])
111 encrypted
= bytearray(response
['encrypted'][:-paddingLength
])
113 moo
= aes
.AESModeOfOperation()
115 decrypted
= moo
.decrypt(encrypted
, 256, moo
.modeOfOperation
["CBC"], self
.key
, moo
.aes
.keySize
["SIZE_128"], iv
)
116 decrypted
= aes
.strip_PKCS7_padding(decrypted
)
118 return self
.DecryptedResponse(decrypted
)
120 def getRandomSalt(self
):
121 return bytearray(random
.getrandbits(8) for i
in range(16))
123 def generateResponse(self
, iv
, encryptedResponse
):
124 bodyLength
= 4 + len(iv
) + len(encryptedResponse
)
125 response
= self
.ResponseV5()
126 response
['versionMinor'] = self
.requestData
['versionMinor']
127 response
['versionMajor'] = self
.requestData
['versionMajor']
128 response
['salt'] = iv
129 response
['encrypted'] = encryptedResponse
130 response
['padding'] = self
.getResponsePadding(bodyLength
)
132 if self
.config
['debug']:
133 print "KMS V%d Response: %s" % (self
.ver
, response
.dump())
134 print "KMS V%d Structue Bytes: %s" % (self
.ver
, binascii
.b2a_hex(str(response
)))
138 def getResponse(self
):
139 return self
.responseData
141 def generateRequest(self
, requestBase
):
142 esalt
= self
.getRandomSalt()
144 moo
= aes
.AESModeOfOperation()
146 dsalt
= moo
.decrypt(esalt
, 16, moo
.modeOfOperation
["CBC"], self
.key
, moo
.aes
.keySize
["SIZE_128"], esalt
)
147 dsalt
= bytearray(dsalt
)
149 decrypted
= self
.DecryptedRequest()
150 decrypted
['salt'] = str(dsalt
)
151 decrypted
['request'] = requestBase
153 padded
= aes
.append_PKCS7_padding(str(decrypted
))
154 mode
, orig_len
, crypted
= moo
.encrypt(padded
, moo
.modeOfOperation
["CBC"], self
.key
, moo
.aes
.keySize
["SIZE_128"], esalt
)
156 message
= self
.RequestV5
.Message(str(bytearray(crypted
)))
158 bodyLength
= len(message
) + 2 + 2
160 request
= self
.RequestV5()
161 request
['bodyLength1'] = bodyLength
162 request
['bodyLength2'] = bodyLength
163 request
['versionMinor'] = requestBase
['versionMinor']
164 request
['versionMajor'] = requestBase
['versionMajor']
165 request
['message'] = message
167 if self
.config
['debug']:
168 print "Request V%d Data: %s" % (self
.ver
, request
.dump())
169 print "Request V%d: %s" % (self
.ver
, binascii
.b2a_hex(str(request
)))