#!/usr/bin/python3
#
# Repeatable RSA key generator using the system authseed
# this uses python-rsa but monkey patches os.urandom to
# an iterated sha512 stream seeded by the system authseed
#

#
# Usage: $0 <unique-key-name> <nbits>
#

# TODO: Error handling when authseed is missing

import sys
import os
from hashlib import sha512
import hmac
import rsa


#
# Iterated SHA-512 HMAC based PRNG
#
class hmac_prng():
        def __init__(self, seed):
                self.pos   = 0
                self.init  = sha512(seed).digest()
                self.state = sha512(self.init).digest()
                self.block = hmac.new(self.init, self.state, sha512).digest()

        def __call__(self, nbytes):
                buf = ''
                while (len(buf) < nbytes):
                        # bytes required?
                        rbytes = nbytes - len(buf)
                        # bytes remaining in this state (block)
                        abytes = 64 - (self.pos % 64)

                        if (abytes > 0):
                                buf += self.block[(self.pos%64):min(rbytes,abytes)]
                                self.pos += min(rbytes,abytes);

                        if (self.pos % 64 == 0):
                                self.state = sha512(self.state).digest()
                                self.block = hmac.new(self.init, self.state, sha512).digest()

                return buf

seed = open('/etc/sysconfig/authseed', 'r').read();
seed = hmac.new(seed, sys.argv[1], sha512).digest()

sys.argv.pop(1);

os.__dict__['urandom'] = hmac_prng(seed)

from pkg_resources import load_entry_point

if __name__ == '__main__':
    sys.exit(
        load_entry_point('rsa', 'console_scripts', 'pyrsa-keygen')()
    )

