# Path: resources/lib/nvhttp/pairinghash/sha256pairinghash.py
# class Sha256PairingHash(AbstractPairingHash):
#     def get_hash_length(self):
#         return 32
# 
#     def hash_data(self, data):
#         m = hashlib.sha256()
#         m.update(data)
#         return bytearray(m.digest())
# 
# Path: resources/lib/nvhttp/pairinghash/sha1pairinghash.py
# class Sha1PairingHash(AbstractPairingHash):
#     def get_hash_length(self):
#         return 20
# 
#     def hash_data(self, data):
#         m = hashlib.sha1()
#         m.update(data)
#         return bytearray(m.digest())
# 
# Path: resources/lib/nvhttp/pairingmanager/abstractpairingmanager.py
# class AbstractPairingManager(object):
#     __metaclass__ = ABCMeta
# 
#     STATE_NOT_PAIRED = 0
#     STATE_PAIRED = 1
#     STATE_PIN_WRONG = 2
#     STATE_FAILED = 3
# 
#     @abstractmethod
#     def pair(self, request_service, server_info, dialog):
#         pass
# 
#     def unpair(self, request_service, server_info):
#         try:
#             request_service.open_http_connection(
#                 request_service.base_url_http + '/unpair?' + request_service.build_uid_uuid_string(),
#                 True
#             )
#         except ValueError:
#             # Unpairing a host needs to be fire and forget
#             pass
# 
#     @staticmethod
#     def get_pair_state(request_service, server_info):
#         if request_service.get_xml_string(server_info, 'PairStatus') != '1':
#             return AbstractPairingManager.STATE_NOT_PAIRED
#         else:
#             return AbstractPairingManager.STATE_PAIRED
# 
#     @staticmethod
#     def generate_pin_string():
#         return '%s%s%s%s' % (random.randint(0, 9), random.randint(0, 9), random.randint(0, 9), random.randint(0, 9))
# 
#     @staticmethod
#     def update_dialog(pin, dialog):
#         pin_message = 'Please enter the PIN: %s' % pin
#         dialog.update(0, pin_message)


import binascii
import hashlib
import random
from Crypto.Cipher import AES
from Crypto.Util import asn1
from M2Crypto import X509
from resources.lib.nvhttp.pairinghash.sha256pairinghash import Sha256PairingHash
from resources.lib.nvhttp.pairinghash.sha1pairinghash import Sha1PairingHash
from resources.lib.nvhttp.pairingmanager.abstractpairingmanager import AbstractPairingManager
        return data + ((((len(data) + 15) / 16) * 16) - len(data)) * chr(0)

    @staticmethod
    def _encrypt_aes(data, key):
        data = AdvancedPairingManager._pad(data)
        cipher = AES.new(buffer(key))
        return cipher.encrypt(buffer(data))

    @staticmethod
    def _decrypt_aes(data, key):
        data = AdvancedPairingManager._pad(data)
        cipher = AES.new(buffer(key))
        return cipher.decrypt(buffer(data))

    @staticmethod
    def _concat_bytes(a, b):
        c = bytearray(len(a) + len(b))
        c[:] = a
        c[len(a):len(a) + len(b)] = b
        return c

    @staticmethod
    def _verify_signature(data, signature, cert):
        pubkey = cert.get_pubkey()
        pubkey.reset_context(md='sha256')
        pubkey.verify_init()
        pubkey.verify_update(data)
        return pubkey.verify_final(signature)

    @staticmethod

# Path: resources/lib/nvhttp/pairinghash/sha256pairinghash.py
# class Sha256PairingHash(AbstractPairingHash):
#     def get_hash_length(self):
#         return 32
# 
#     def hash_data(self, data):
#         m = hashlib.sha256()
#         m.update(data)
#         return bytearray(m.digest())
# 
# Path: resources/lib/nvhttp/pairinghash/sha1pairinghash.py
# class Sha1PairingHash(AbstractPairingHash):
#     def get_hash_length(self):
#         return 20
# 
#     def hash_data(self, data):
#         m = hashlib.sha1()
#         m.update(data)
#         return bytearray(m.digest())
# 
# Path: resources/lib/nvhttp/pairingmanager/abstractpairingmanager.py
# class AbstractPairingManager(object):
#     __metaclass__ = ABCMeta
# 
#     STATE_NOT_PAIRED = 0
#     STATE_PAIRED = 1
#     STATE_PIN_WRONG = 2
#     STATE_FAILED = 3
# 
#     @abstractmethod
#     def pair(self, request_service, server_info, dialog):
#         pass
# 
#     def unpair(self, request_service, server_info):
#         try:
#             request_service.open_http_connection(
#                 request_service.base_url_http + '/unpair?' + request_service.build_uid_uuid_string(),
#                 True
#             )
#         except ValueError:
#             # Unpairing a host needs to be fire and forget
#             pass
# 
#     @staticmethod
#     def get_pair_state(request_service, server_info):
#         if request_service.get_xml_string(server_info, 'PairStatus') != '1':
#             return AbstractPairingManager.STATE_NOT_PAIRED
#         else:
#             return AbstractPairingManager.STATE_PAIRED
# 
#     @staticmethod
#     def generate_pin_string():
#         return '%s%s%s%s' % (random.randint(0, 9), random.randint(0, 9), random.randint(0, 9), random.randint(0, 9))
# 
#     @staticmethod
#     def update_dialog(pin, dialog):
#         pin_message = 'Please enter the PIN: %s' % pin
#         dialog.update(0, pin_message)


# Path: resources/lib/nvhttp/pairingmanager/advancedpairingmanager.py
import binascii
import hashlib
import random
from Crypto.Cipher import AES
from Crypto.Util import asn1
from M2Crypto import X509
from resources.lib.nvhttp.pairinghash.sha256pairinghash import Sha256PairingHash
from resources.lib.nvhttp.pairinghash.sha1pairinghash import Sha1PairingHash
from resources.lib.nvhttp.pairingmanager.abstractpairingmanager import AbstractPairingManager

        return data + ((((len(data) + 15) / 16) * 16) - len(data)) * chr(0)

    @staticmethod
    def _encrypt_aes(data, key):
        data = AdvancedPairingManager._pad(data)
        cipher = AES.new(buffer(key))
        return cipher.encrypt(buffer(data))

    @staticmethod
    def _decrypt_aes(data, key):
        data = AdvancedPairingManager._pad(data)
        cipher = AES.new(buffer(key))
        return cipher.decrypt(buffer(data))

    @staticmethod
    def _concat_bytes(a, b):
        c = bytearray(len(a) + len(b))
        c[:] = a
        c[len(a):len(a) + len(b)] = b
        return c

    @staticmethod
    def _verify_signature(data, signature, cert):
        pubkey = cert.get_pubkey()
        pubkey.reset_context(md='sha256')
        pubkey.verify_init()
        pubkey.verify_update(data)
        return pubkey.verify_final(signature)

    @staticmethod

    def _sign_data(data, key):