modified: myjupyterlab.sh
[GalaxyCodeBases.git] / etc / Windows / py-kms / kmsRequestV4.py
blob4b0af3d3dd91b9ddb2b02dd3d7662f28ac3009b6
1 import binascii
2 import struct
3 import time
4 from kmsBase import kmsBase
5 from structure import Structure
7 from aes import AES
9 # v4 AES Key
10 key = bytearray([0x05, 0x3D, 0x83, 0x07, 0xF9, 0xE5, 0xF0, 0x88, 0xEB, 0x5E, 0xA6, 0x68, 0x6C, 0xF0, 0x37, 0xC7, 0xE4, 0xEF, 0xD2, 0xD6])
12 # Xor Buffer
13 def xorBuffer(source, offset, destination, size):
14 for i in range(0, size):
15 destination[i] ^= source[i + offset]
17 class kmsRequestV4(kmsBase):
18 class RequestV4(Structure):
19 commonHdr = ()
20 structure = (
21 ('bodyLength1', '<I'),
22 ('bodyLength2', '<I'),
23 ('request', ':', kmsBase.kmsRequestStruct),
24 ('hash', '16s'),
25 ('padding', ':'),
28 class ResponseV4(Structure):
29 commonHdr = ()
30 structure = (
31 ('bodyLength1', '<I=len(response) + len(hash)'),
32 ('unknown', '!I=0x00000200'),
33 ('bodyLength2', '<I=len(response) + len(hash)'),
34 ('response', ':', kmsBase.kmsResponseStruct),
35 ('hash', '16s'),
36 ('padding', ':'),
39 def executeRequestLogic(self):
40 requestData = self.RequestV4(self.data)
42 response = self.serverLogic(requestData['request'])
43 hash = self.generateHash(bytearray(str(response)))
45 self.responseData = self.generateResponse(response, hash)
47 time.sleep(1) # request sent back too quick for Windows 2008 R2, slow it down.
49 def generateHash(self, message):
50 """
51 The KMS v4 hash is a variant of CMAC-AES-128. There are two key differences:
52 * The 'AES' used is modified in particular ways:
53 * The basic algorithm is Rjindael with a conceptual 160bit key and 128bit blocks.
54 This isn't part of the AES standard, but it works the way you'd expect.
55 Accordingly, the algorithm uses 11 rounds and a 192 byte expanded key.
56 * The trailing block is not XORed with a generated subkey, as defined in CMAC.
57 This is probably because the subkey generation algorithm is only defined for
58 situations where block and key size are the same.
59 """
60 aes = AES()
62 messageSize = len(message)
63 lastBlock = bytearray(16)
64 hashBuffer = bytearray(16)
66 # MessageSize / Blocksize
67 j = messageSize >> 4
69 # Remainding bytes
70 k = messageSize & 0xf
72 # Hash
73 for i in range(0, j):
74 xorBuffer(message, i << 4, hashBuffer, 16)
75 hashBuffer = bytearray(aes.encrypt(hashBuffer, key, len(key)))
77 # Bit Padding
78 ii = 0
79 for i in range(j << 4, k + (j << 4)):
80 lastBlock[ii] = message[i]
81 ii += 1
82 lastBlock[k] = 0x80
84 xorBuffer(lastBlock, 0, hashBuffer, 16)
85 hashBuffer = bytearray(aes.encrypt(hashBuffer, key, len(key)))
87 return str(hashBuffer)
89 def generateResponse(self, responseBuffer, hash):
90 bodyLength = len(responseBuffer) + len(hash)
91 response = self.ResponseV4()
92 response['response'] = responseBuffer
93 response['hash'] = hash
94 response['padding'] = self.getResponsePadding(bodyLength)
96 if self.config['debug']:
97 print "KMS V4 Response:", response.dump()
98 print "KMS V4 Response Bytes:", binascii.b2a_hex(str(response))
100 return str(response)
102 def getResponse(self):
103 return self.responseData
105 def generateRequest(self, requestBase):
106 hash = str(self.generateHash(bytearray(str(requestBase))))
108 bodyLength = len(requestBase) + len(hash)
110 request = kmsRequestV4.RequestV4()
111 request['bodyLength1'] = bodyLength
112 request['bodyLength2'] = bodyLength
113 request['request'] = requestBase
114 request['hash'] = hash
115 request['padding'] = self.getResponsePadding(bodyLength)
117 if self.config['debug']:
118 print "Request V4 Data:", request.dump()
119 print "Request V4:", binascii.b2a_hex(str(request))
121 return request