Beispiel #1
0
def decrypt_token(token, _from):
    '''
    Decrypt a token.
    '''
    try:
        token_key = '{0}{1}'.format(hashlib.sha256(token).hexdigest(), _from)
    except Exception:
        raise TokenDecryptionError('Authentication error.')
    if token_key not in TOKENS:
        try:
            token = base64.b64decode(token)
            with stats.timer('kms_decrypt_token'):
                data = kms.decrypt(
                    CiphertextBlob=token,
                    EncryptionContext={
                        # This key is sent to us.
                        'to': app.config['AUTH_CONTEXT'],
                        # From a service.
                        'from': _from
                    })
            # Decrypt doesn't take KeyId as an argument. We need to verify the
            # correct key was used to do the decryption.
            # Annoyingly, the KeyId from the data is actually an arn.
            key_arn = data['KeyId']
            if key_arn != get_key_arn(app.config['AUTH_KEY']):
                raise TokenDecryptionError('Authentication error.')
            plaintext = data['Plaintext']
            payload = json.loads(plaintext)
        # We don't care what exception is thrown. For paranoia's sake, fail
        # here.
        except Exception:
            log.exception('Failed to validate token.')
            raise TokenDecryptionError('Authentication error.')
    else:
        payload = TOKENS[token_key]
    time_format = "%Y%m%dT%H%M%SZ"
    now = datetime.datetime.utcnow()
    try:
        not_before = datetime.datetime.strptime(payload['not_before'],
                                                time_format)
        not_after = datetime.datetime.strptime(payload['not_after'],
                                               time_format)
    except Exception:
        log.exception(
            'Failed to get not_before and not_after from token payload.')
        raise TokenDecryptionError('Authentication error.')
    delta = (not_after - not_before).seconds / 60
    if delta > app.config['AUTH_TOKEN_MAX_LIFETIME']:
        log.warning('Token used which exceeds max token lifetime.')
        raise TokenDecryptionError('Authentication error.')
    if not (now >= not_before) and (now <= not_after):
        log.warning('Expired token used.')
        raise TokenDecryptionError('Authentication error.')
    TOKENS[token_key] = payload
    return payload
Beispiel #2
0
def grants_exist(service_name):
    try:
        role = iam.Role(name=service_name)
        role.load()
    except ClientError:
        return {'encrypt_grant': False, 'decrypt_grant': False}
    try:
        grants = get_grants()
        encrypt_grant, decrypt_grant = _grants_exist(role, grants)
    except ClientError:
        log.exception('Failed to get grants for {0}.'.format(service_name))
        raise ServiceGetGrantError()
    return {'encrypt_grant': encrypt_grant, 'decrypt_grant': decrypt_grant}
Beispiel #3
0
def ensure_grants(service_name):
    '''
    Add encryption and decryption grants for the service.

    TODO: We should probably orchestrate this, rather than doing it in
          confidant.
    '''
    try:
        role = iam.Role(name=service_name)
        role.load()
        grants = get_grants()
        _ensure_grants(role, grants)
    except ClientError:
        log.exception('Failed to ensure grants for {0}.'.format(service_name))
        raise ServiceCreateGrantError()
Beispiel #4
0
def ensure_grants(service_name):
    '''
    Add encryption and decryption grants for the service.

    TODO: We should probably orchestrate this, rather than doing it in
          confidant.
    '''
    try:
        role = iam.Role(name=service_name)
        role.load()
        grants = get_grants()
        _ensure_grants(role, grants)
    except ClientError:
        log.exception('Failed to ensure grants for {0}.'.format(service_name))
        raise ServiceCreateGrantError()
Beispiel #5
0
def grants_exist(service_name):
    try:
        role = iam.Role(name=service_name)
        role.load()
    except ClientError:
        return {
            'encrypt_grant': False,
            'decrypt_grant': False
        }
    try:
        grants = get_grants()
        encrypt_grant, decrypt_grant = _grants_exist(role, grants)
    except ClientError:
        log.exception('Failed to get grants for {0}.'.format(service_name))
        raise ServiceGetGrantError()
    return {
        'encrypt_grant': encrypt_grant,
        'decrypt_grant': decrypt_grant
    }
Beispiel #6
0
def decrypt_token(token, _from):
    '''
    Decrypt a token.
    '''
    try:
        token_key = '{0}{1}'.format(
            hashlib.sha256(token).hexdigest(),
            _from
        )
    except Exception:
        raise TokenDecryptionError('Authentication error.')
    if token_key not in TOKENS:
        try:
            token = base64.b64decode(token)
            with stats.timer('kms_decrypt_token'):
                data = kms.decrypt(
                    CiphertextBlob=token,
                    EncryptionContext={
                        # This key is sent to us.
                        'to': app.config['AUTH_CONTEXT'],
                        # From a service.
                        'from': _from
                    }
                )
            # Decrypt doesn't take KeyId as an argument. We need to verify the
            # correct key was used to do the decryption.
            # Annoyingly, the KeyId from the data is actually an arn.
            key_arn = data['KeyId']
            if key_arn != get_key_arn(app.config['AUTH_KEY']):
                raise TokenDecryptionError('Authentication error.')
            plaintext = data['Plaintext']
            payload = json.loads(plaintext)
        # We don't care what exception is thrown. For paranoia's sake, fail
        # here.
        except Exception:
            log.exception('Failed to validate token.')
            raise TokenDecryptionError('Authentication error.')
    else:
        payload = TOKENS[token_key]
    time_format = "%Y%m%dT%H%M%SZ"
    now = datetime.datetime.utcnow()
    try:
        not_before = datetime.datetime.strptime(
            payload['not_before'],
            time_format
        )
        not_after = datetime.datetime.strptime(
            payload['not_after'],
            time_format
        )
    except Exception:
        log.exception(
            'Failed to get not_before and not_after from token payload.'
        )
        raise TokenDecryptionError('Authentication error.')
    delta = (not_after - not_before).seconds / 60
    if delta > app.config['AUTH_TOKEN_MAX_LIFETIME']:
        log.warning('Token used which exceeds max token lifetime.')
        raise TokenDecryptionError('Authentication error.')
    if not (now >= not_before) and (now <= not_after):
        log.warning('Expired token used.')
        raise TokenDecryptionError('Authentication error.')
    TOKENS[token_key] = payload
    return payload