# Path: sippy/SipGenericHF.py
# class SipGenericHF(object):
#     hf_names = None	# Set this in each subclass!!
#     body = None
#     parsed = False
# 
#     def __init__(self, body, name = None):
#         self.body = body
#         if name != None:
#             self.hf_names = (name.lower(),)
# 
#     def parse(self):
#         pass
# 
#     def localStr(self, local_addr = None, local_port = None):
#         return self.__str__()
# 
#     def __str__(self):
#         return self.body
# 
#     def getCopy(self):
#         return self.__class__(self.body)
# 
#     def getCanName(self, name, compact = False):
#         return name.capitalize()
# 
# Path: sippy/Security/SipNonce.py
# class HashOracle(object):
#     try: key
#     except: key = Random.new().read(AES.block_size * 2)
#     ac = None
#     vtime = 32 * 10**9
# 
#     def __init__(self):
#         self.ac = AESCipher(self.key)
# 
#     def emit_challenge(self, cmask):
#         ts128 = clock_getntime(CLOCK_MONOTONIC) << len(DGST_PRIOS)
#         for ms in cmask:
#             ts128 |= ms
#         cryptic = self.ac.encrypt(to_bytes_be(ts128, AES.block_size))
#         #return cryptic
#         return cryptic.decode()
# 
#     def validate_challenge(self, cryptic, cmask):
#         new_ts = clock_getntime(CLOCK_MONOTONIC)
#         decryptic = from_bytes_be(self.ac.decrypt(cryptic.encode()))
#         for ms in cmask:
#             if (ms & decryptic) == 0:
#                 return False
#         orig_ts = decryptic >> len(DGST_PRIOS)
#         tsdiff = new_ts - orig_ts
#         if tsdiff < 0 or tsdiff > self.vtime:
#             return False
#         return True
# 
# DGST_MD5        = (1 << 0)
# 
# DGST_MD5SESS    = (1 << 1)
# 
# DGST_SHA256     = (1 << 2)
# 
# DGST_SHA256SESS = (1 << 3)
# 
# DGST_SHA512     = (1 << 4)
# 
# DGST_SHA512SESS = (1 << 5)


from sippy.SipGenericHF import SipGenericHF
from sippy.Security.SipNonce import HashOracle, DGST_MD5, DGST_MD5SESS, \
  DGST_SHA256, DGST_SHA256SESS, DGST_SHA512, DGST_SHA512SESS
from hashlib import md5, sha256
from time import time
from Crypto.Hash import SHA512
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.




class sha512_256(object):
    d = None

    def __init__(self):
        self.d = SHA512.new(truncate = '256')

    def update(self, arg):
        self.d.update(arg)

    def digest(self):
        return self.d.digest()

    def hexdigest(self):
        return self.d.hexdigest()

_HASH_FUNC = {None:(md5, DGST_MD5), 'MD5':(md5, DGST_MD5), 'MD5-sess':(md5, DGST_MD5SESS), \
  'SHA-256':(sha256, DGST_SHA256), 'SHA-256-sess':(sha256, DGST_SHA256SESS), \

# Path: sippy/SipGenericHF.py
# class SipGenericHF(object):
#     hf_names = None	# Set this in each subclass!!
#     body = None
#     parsed = False
# 
#     def __init__(self, body, name = None):
#         self.body = body
#         if name != None:
#             self.hf_names = (name.lower(),)
# 
#     def parse(self):
#         pass
# 
#     def localStr(self, local_addr = None, local_port = None):
#         return self.__str__()
# 
#     def __str__(self):
#         return self.body
# 
#     def getCopy(self):
#         return self.__class__(self.body)
# 
#     def getCanName(self, name, compact = False):
#         return name.capitalize()
# 
# Path: sippy/Security/SipNonce.py
# class HashOracle(object):
#     try: key
#     except: key = Random.new().read(AES.block_size * 2)
#     ac = None
#     vtime = 32 * 10**9
# 
#     def __init__(self):
#         self.ac = AESCipher(self.key)
# 
#     def emit_challenge(self, cmask):
#         ts128 = clock_getntime(CLOCK_MONOTONIC) << len(DGST_PRIOS)
#         for ms in cmask:
#             ts128 |= ms
#         cryptic = self.ac.encrypt(to_bytes_be(ts128, AES.block_size))
#         #return cryptic
#         return cryptic.decode()
# 
#     def validate_challenge(self, cryptic, cmask):
#         new_ts = clock_getntime(CLOCK_MONOTONIC)
#         decryptic = from_bytes_be(self.ac.decrypt(cryptic.encode()))
#         for ms in cmask:
#             if (ms & decryptic) == 0:
#                 return False
#         orig_ts = decryptic >> len(DGST_PRIOS)
#         tsdiff = new_ts - orig_ts
#         if tsdiff < 0 or tsdiff > self.vtime:
#             return False
#         return True
# 
# DGST_MD5        = (1 << 0)
# 
# DGST_MD5SESS    = (1 << 1)
# 
# DGST_SHA256     = (1 << 2)
# 
# DGST_SHA256SESS = (1 << 3)
# 
# DGST_SHA512     = (1 << 4)
# 
# DGST_SHA512SESS = (1 << 5)


# Path: sippy/SipAuthorization.py
from sippy.SipGenericHF import SipGenericHF
from sippy.Security.SipNonce import HashOracle, DGST_MD5, DGST_MD5SESS, \
  DGST_SHA256, DGST_SHA256SESS, DGST_SHA512, DGST_SHA512SESS
from hashlib import md5, sha256
from time import time
from Crypto.Hash import SHA512

# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.




class sha512_256(object):
    d = None

    def __init__(self):
        self.d = SHA512.new(truncate = '256')

    def update(self, arg):
        self.d.update(arg)

    def digest(self):
        return self.d.digest()

    def hexdigest(self):
        return self.d.hexdigest()

_HASH_FUNC = {None:(md5, DGST_MD5), 'MD5':(md5, DGST_MD5), 'MD5-sess':(md5, DGST_MD5SESS), \
  'SHA-256':(sha256, DGST_SHA256), 'SHA-256-sess':(sha256, DGST_SHA256SESS), \

  'SHA-512-256':(sha512_256, DGST_SHA512), 'SHA-512-256-sess':(sha512_256, DGST_SHA512SESS)}