Example #1
0
    def _restore_master_secret(self, backup_file, encrypt_master_secret, passphrase, salt):
        """Restore secret from file.

        Decode secret if encrypted.
        """
        try:
            with open(backup_file) as json_file:
                backup = json.load(json_file)
        except ValueError:
            raise SecretsError('Master Secret backup file is corrupted.')

        if encrypt_master_secret:
            tag, plaintext = crypto.aes_gcm_decrypt(
                aes_key=generate_aes_key(passphrase, salt),
                iv=str(backup['IV'].decode('hex')),
                header=str(backup['startTime']),
                ciphertext=str(backup['ciphertext'].decode('hex')))

            # Check authentication tag
            if backup['tag'] != tag:
                raise SecretsError('AES-GSM Decryption Failed. Authentication tag is not correct')

            self.start_time = Time.ISOtoDateTime(str(backup['startTime']))
            master_secret = plaintext.decode('hex')
        else:
            self.start_time = Time.ISOtoDateTime(backup['startTime'])
            master_secret = backup['master_secret_hex'].decode('hex')

        return master_secret, self.start_time
Example #2
0
    def generate_qr(self, wId):
        webOTT = secrets.generate_ott(options.OTTLength,
                                      self.application.server_secret.rng,
                                      "hex")

        nowTime = Time.syncedNow()
        expirePinPadTime = nowTime + datetime.timedelta(
            seconds=options.accessNumberExpireSeconds)
        expireTime = expirePinPadTime + datetime.timedelta(
            seconds=options.accessNumberExtendValiditySeconds)

        self.storage.add(stage="auth",
                         expire_time=expireTime,
                         webOTT=webOTT,
                         wid=wId)

        qrUrl = options.rpsBaseURL + "#" + wId

        params = {
            "ttlSeconds": options.accessNumberExpireSeconds,
            "qrUrl": qrUrl,
            "webOTT": webOTT,
            "localTimeStart": Time.DateTimetoEpoch(nowTime),
            "localTimeEnd": Time.DateTimetoEpoch(expirePinPadTime)
        }

        return params
    def _verifySignature(self):
        identity = self.get_argument("i", default="")
        expires = self.get_argument("e", default="")
        signature = self.get_argument("s", default="")

        log.debug("/mpinActivate request for identity: {0}".format(identity))

        try:
            data = json.loads(identity.decode("hex"))
            userid = data["userID"]
            issued = data["issued"]
            sIssued = Time.DateTimetoHuman(Time.ISOtoDateTime(issued))

            mobile = int(data.get("mobile") or 0)

        except Exception as E:
            log.error("Error parsing the verification email: {0}".format(E))
            userid, issued, sIssued = None, None, None

        if userid:
            if expires < datetime.datetime.utcnow().isoformat(b"T").split(
                    ".")[0] + "Z":
                isValid = False
                info = "Link expired"
            else:
                isValid = True
                info = ""

            deviceName = mobile and "Mobile" or "PC"

        else:
            log.error("/mpinActivate: Invalid IDENTITY: {0}".format(identity))
            isValid, info = False, "Invalid identity"
            deviceName, issued = "", ""

        params = {
            "isValid": isValid,
            "identity": identity,
            "errorMessage": info,
            "userid": userid,
            "issued": issued,
            "humanIssued": sIssued,
            "activated": False,
            "deviceName": deviceName,
            "activateKey": signature
        }

        return params
    def _schedule_expiration_check(self):
        if self._timeout:
            self.ioloop.remove_timeout(self._timeout)
            self._timeout = None

        while len(self._expires_list) > 0:
            item_expiration, item_id = self._expires_list[0]

            try:
                item = self._items[item_id]
            except KeyError:
                del self._expires_list[0]
                continue

            now = Time.syncedNow()
            if not item._active or item_expiration < now:
                del self._expires_list[0]
                del self._items[item_id]
                self._delete_from_indexes(item)
                continue

            # No more expired items, schedule next check
            self._timeout = self.ioloop.add_timeout(
                item_expiration - now + datetime.timedelta(milliseconds=100),
                self._schedule_expiration_check)
            break

        self._storage_change()
    def _schedule_expiration_check(self):
        if self._timeout:
            self.ioloop.remove_timeout(self._timeout)
            self._timeout = None

        while len(self._expires_list) > 0:
            item_expiration, item_id = self._expires_list[0]

            try:
                item = self._items[item_id]
            except KeyError:
                del self._expires_list[0]
                continue

            now = Time.syncedNow()
            if not item._active or item_expiration < now:
                del self._expires_list[0]
                del self._items[item_id]
                self._delete_from_indexes(item)
                continue

            # No more expired items, schedule next check
            self._timeout = self.ioloop.add_timeout(
                item_expiration - now + datetime.timedelta(milliseconds=100),
                self._schedule_expiration_check
            )
            break

        self._storage_change()
 def get(self):
     reason = "OK"
     self.set_status(200, reason=reason)
     start_time_str = Time.DateTimeToISO(
         self.application.master_secret.start_time),
     self.write({
         'startTime': start_time_str,
         'service_name': 'D-TA server',
         'message': reason
     })
     return
Example #7
0
    def _get_server_secret(self):
        expires = Time.syncedISO(seconds=SIGNATURE_EXPIRES_OFFSET_SECONDS)
        certivox_server_secret = self._get_certivox_server_secret_share(expires)
        customer_server_secret = self._get_customer_server_secret_share(expires)

        try:
            server_secret_hex = crypto.mpin_recombine_g2(certivox_server_secret, customer_server_secret)
        except crypto.CryptoError as e:
            log.error(e)
            raise SecretsError('M-Pin Server Secret Generation Failed')

        return server_secret_hex.decode("hex")
Example #8
0
    def validate_pass2_value(self, mpin_id, u, ut, y, v):
        """Validate pass2 value.

        y - pass 1 values
        v - pass 2 value in question
        """
        date = crypto.today()
        check_dates = [date]
        if Time.syncedNow().hour < 1:
            check_dates.append(date - 1)

        for date in check_dates:
            hid, htid = crypto.mpin_server_1(mpin_id, date)
            success, _, _ = crypto.mpin_server_2(self.server_secret, v, date, hid, htid, y, u, ut)
            if success != -19:
                break

        return success
    def __init__(self, storage, expire_time, **kwargs):
        '''expireTime should be in ISO format'''
        self.__fields = ["_id", "_active", "_expires"]
        self.__storage = storage

        self._id = uuid.uuid1().hex

        if isinstance(expire_time, datetime.datetime):
            self._expires = expire_time.isoformat()
        else:
            self._expires = expire_time

        self._update_item(**kwargs)

        self._expiration_datetime = None
        if self._expires:
            self._expiration_datetime = Time.ISOtoDateTime(self._expires)

        self.__storage.update_index(self)
    def generate_qr(self, wId):
        webOTT = secrets.generate_ott(options.OTTLength, self.application.server_secret.rng, "hex")

        nowTime = Time.syncedNow()
        expirePinPadTime = nowTime + datetime.timedelta(seconds=options.accessNumberExpireSeconds)
        expireTime = expirePinPadTime + datetime.timedelta(seconds=options.accessNumberExtendValiditySeconds)

        self.storage.add(stage="auth", expire_time=expireTime, webOTT=webOTT, wid=wId)

        qrUrl = options.rpsBaseURL + "#" + wId

        params = {
            "ttlSeconds": options.accessNumberExpireSeconds,
            "qrUrl": qrUrl,
            "webOTT": webOTT,
            "localTimeStart": Time.DateTimetoEpoch(nowTime),
            "localTimeEnd": Time.DateTimetoEpoch(expirePinPadTime)
        }

        return params
    def __init__(self):
        handlers = [
            (r"/clientSecret", ClientSecretHandler),
            (r"/serverSecret", ServerSecretHandler),
            (r"/timePermit", TimePermitHandler),
            (r"/timePermits", TimePermitsHandler),
            (r"/status", StatusHandler),
            (r"/(.*)", DefaultHandler),
        ]
        settings = dict(xsrf_cookies=False)
        super(Application, self).__init__(handlers, **settings)

        Seed.getSeed(options.EntropySources
                     )  # Get seed value for random number generator
        self.master_secret = secrets.MasterSecret(
            passphrase=options.passphrase,
            salt=options.salt,
            seed=Seed.seedValue,
            backup_file=options.backup_file,
            encrypt_master_secret=options.encrypt_master_secret,
            time=Time.syncedNow())
 def add(self, key, expires, value):
     if expires:
         self._execute("setex", key, (expires - Time.syncedNow()), value)
     else:
         self._execute("set", key, value)
def today():
    """Return time in slots since epoch using synced time"""
    utc_dt = datetime.datetime.utcfromtimestamp(0)
    return int((Time.syncedNow() - utc_dt).total_seconds() / 86400)
    def get(self):
        # Remote request information
        if 'User-Agent' in self.request.headers.keys():
            UA = self.request.headers['User-Agent']
        else:
            UA = 'unknown'
        request_info = '%s %s %s %s ' % (
            self.request.method, self.request.path, self.request.remote_ip, UA)

        # Get arguments
        try:
            app_id = str(self.get_argument('app_id'))
            expires = self.get_argument('expires')
            signature = self.get_argument('signature')
        except tornado.web.MissingArgumentError as ex:
            reason = ex.log_message
            log.error("%s %s" % (request_info, reason))
            self.set_status(403, reason=reason)
            self.content_type = 'application/json'
            self.write({'message': reason})
            self.finish()
            return
        request_info = request_info + app_id

        # Get path used for signature
        path = self.request.path
        path = path.replace("/", "")

        # Check signature is valid and that timestamp has not expired
        M = str("%s%s%s" % (path, Keys.app_id, expires))
        valid, reason, code = verifySignature(M, signature, Keys.app_key,
                                              expires)
        if not valid:
            return_data = {'code': code, 'message': reason}
            log.error("%s %s" % (request_info, reason))
            self.set_status(status_code=code, reason=reason)
            self.content_type = 'application/json'
            self.write(return_data)
            self.finish()
            return

        try:
            server_secret_hex = self.application.master_secret.get_server_secret(
            )
        except secrets.SecretsError as e:
            log.error(
                'M-Pin Server Secret Generation Failed: {0}. Request info: {1}'
                .format(e, request_info))
            return_data = {
                'errorCode': e.message,
                'reason': 'M-Pin Server Secret Generation Failed',
            }
            self.set_status(500, reason=reason)
            self.content_type = 'application/json'
            self.write(return_data)
            self.finish()
            return

        # Hash server secret share
        server_secret = server_secret_hex.decode("hex")
        hash_server_secret_hex = hashlib.sha256(server_secret).hexdigest()
        log.info("%s hash_server_secret_hex: %s" %
                 (request_info, hash_server_secret_hex))

        # Returned data
        reason = "OK"
        self.set_status(200, reason=reason)
        self.content_type = 'application/json'
        return_data = {
            'serverSecret':
            server_secret_hex,
            'startTime':
            Time.DateTimeToISO(self.application.master_secret.start_time),
            'message':
            reason
        }
        self.write(return_data)
        log.debug("%s %s" % (request_info, return_data))
        self.finish()
        return
Example #15
0
def today():
    """Return time in slots since epoch using synced time"""
    utc_dt = datetime.datetime.utcfromtimestamp(0)
    return int((Time.syncedNow() - utc_dt).total_seconds() / 86400)
    try:
        credentialsFile = options.credentialsFile
        Keys.loadFromFile(credentialsFile)
    except Exception as E:
        log.error(
            "Error opening the credentials file: {0}".format(credentialsFile))
        log.error(E)
        sys.exit(1)

    # TMP fix for 'ValueError: I/O operation on closed epoll fd'
    # Fixed in Tornado 4.2
    tornado.ioloop.IOLoop.instance()

    # Sync time to CertiVox time server
    if options.syncTime:
        Time.getTime(wait=True)

    if options.backup and options.encrypt_master_secret and not options.passphrase:
        options.passphrase = getpass.getpass("Please enter passphrase:")

    http_server = Application()
    http_server.listen(options.port, options.address, xheaders=True)
    io_loop = tornado.ioloop.IOLoop.instance()

    if options.autoReload:
        log.debug("Starting autoreloader")
        tornado.autoreload.watch(CONFIG_FILE)
        tornado.autoreload.start(io_loop)

    if options.syncTime and (options.timePeriod > 0):
        scheduler = tornado.ioloop.PeriodicCallback(Time.getTime,
Example #17
0
 def add(self, key, expires, value):
     if expires:
         self._execute("setex", key, (expires - Time.syncedNow()), value)
     else:
         self._execute("set", key, value)