#!/usr/bin/env python2
# -*- coding: utf-8 -*-
#
#    LinOTP - the open source solution for two factor authentication
#    Copyright (C) 2010 - 2019 KeyIdentity GmbH
#
#    This file is part of LinOTP server.
#
#    This program is free software: you can redistribute it and/or
#    modify it under the terms of the GNU Affero General Public
#    License, version 3, as published by the Free Software Foundation.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the
#               GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#
#    E-mail: linotp@keyidentity.com
#    Contact: www.linotp.org
#    Support: www.keyidentity.com
#

'''
Used to decrypt the OTP key (HMAC key) from the LinOTP database
You may read the encrypted OTP and the IV from the database
mysql> select LinOtpTokenSerialnumber,  LinOtpKeyEnc, LinOtpKeyIV from Token;
'''

import binascii
from getopt import getopt, GetoptError
import sys


def aes_decrypt(value_bin, iv_bin, key_bin):
    import base64
    import binascii
    from Cryptodome.Cipher import AES

    aesObj = AES.new(key_bin, AES.MODE_CBC, iv_bin)
    output = aesObj.decrypt(value_bin)
    eof = output.rfind(u"\x01\x02")
    if eof >= 0: output = output[:eof]

    output = binascii.a2b_hex(output)

    return output


def usage():
    print  '''
    Parameter:
    --otp=<encrypted OTP key, LinOtpKeyEnc>
    --iv=<LinOtpKeyIV>
    --enckey=/etc/linotp2/encKey  (Filename of enckey)

    program can be called this way:
    linotp-decrypt-otpkey --otp=1c224d3e174ef69272413a0ece198215fa5c7fda12446ff9ac9406377b700d62246e151e0f4314ab7f25e76f27a5d979363ba46e0c0f80b51ea64b68ef4a36e38d290129641fb1670899c570010263ef8724b94ea5d08f91c0d106aab4d703e4 --iv=14c6d84d04b4e2a7a5f04e1134761f7e --enckey=/etc/linotp2/encKey

    response would be:
    CB4F416398FA7725F521DBCCCC19F3E9F8DF4727

    You may read the encrypted OTP and the IV from the database
    mysql> select LinOtpTokenSerialnumber,  LinOtpKeyEnc, LinOtpKeyIV from Token;
'''

def main():
    try:
        opts, args = getopt(sys.argv[1:], "",
                ["help", "otp=", "iv=", "enckey="])

    except GetoptError:
        print "There is an error in your parameter syntax:"
        usage()
        sys.exit(1)


    filename = ""
    otp = ""
    iv = ""

    for opt, arg in opts:
        if opt in ('--help'):
            usage()
            sys.exit(0)
        elif opt in ('--otp'):
            otp = arg
        elif opt in ('--enckey'):
            filename = arg
        elif opt in ('--iv'):
            iv = arg

    if "" == filename or "" == otp or "" == iv:
        print "missing parameter"
        usage()
        sys.exit(1)

    f = open(filename, 'r')
    enckey = f.read()[:32]
    f.close()

    result = aes_decrypt(binascii.unhexlify(otp), binascii.unhexlify(iv), enckey)
    print result


if __name__ == '__main__':
    main()
