Ejemplo n.º 1
0
def submit_candidate():
    now = int(time.time())
    if now < app.config['STARTING_DATE']:
        return render_template('submit_candidate_before_starting_date.html',
                               active_page='submit_candidate',
                               starting_date=format_timestamp(
                                   app.config['STARTING_DATE']))

    if now > app.config['POSTING_DEADLINE']:
        return render_template('submit_candidate_deadline_exceeded.html',
                               active_page='submit_candidate',
                               posting_deadline=format_timestamp(
                                   app.config['POSTING_DEADLINE']))

    form = WhiteboxSubmissionForm()
    if request.method != 'POST':
        return render_template('submit_candidate.html',
                               form=form,
                               active_page='submit_candidate',
                               testing=app.testing)
    elif not form.validate_on_submit():
        crx_flash("CHALLENGE_INVALID")
        return render_template('submit_candidate.html',
                               form=form,
                               active_page='submit_candidate',
                               testing=app.testing), 400
    else:
        upload_folder = app.config['UPLOAD_FOLDER']
        basename = ''.join(
            random.SystemRandom().choice(string.ascii_lowercase +
                                         string.digits) for _ in range(32))
        filename = basename + '.c'
        pubkey = form.pubkey.data
        proof_of_knowledge = form.proof_of_knowledge.data
        form_data = form.program.data
        form_data.save(os.path.join(upload_folder, filename))
        Program.create(basename=basename,
                       pubkey=pubkey,
                       proof_of_knowledge=proof_of_knowledge,
                       user=current_user)
        try:
            db.session.commit()
        except sqlalchemy.exc.IntegrityError as e:
            db.session.rollback()
            crx_flash("DUPLICATE_KEY")
            app.logger.error(e)
            new_form = WhiteboxSubmissionForm()
            return render_template('submit_candidate.html',
                                   form=new_form,
                                   active_page='submit_candidate',
                                   testing=app.testing), 400
        else:
            return redirect(url_for('submit_candidate_ok'))
Ejemplo n.º 2
0
def break_candidate(identifier):
    now = int(time.time())
    if now < app.config['STARTING_DATE']:
        crx_flash('BEFORE_STARTING_DATE')
        return redirect(url_for('index'))
    if now > app.config['FINAL_DEADLINE']:
        crx_flash('EXCEED_DEADLINE')
        return render_template('break_candidate_deadline_exceeded.html',
                               final_deadline=format_timestamp(
                                   app.config['FINAL_DEADLINE']))

    # Only published programs can be broken
    program = Program.get_unbroken_or_broken_by_id(identifier)
    if program is None or not program.is_published:
        return redirect(url_for('index'))

    # If the current user is the one who submitted the program, redirect to index
    if program.user == current_user:
        crx_flash('CANNOT_BREAK_OWN')
        return redirect(url_for('index'))

    # A user cannot break the same challenge twice
    wb_break = WhiteboxBreak.get(current_user, program)
    if wb_break is not None:
        crx_flash('CANNOT_BREAK_TWICE')
        return redirect(url_for('index'))

    form = WhiteboxBreakForm()
    if request.method != 'POST' or not form.validate_on_submit():
        return render_template('break_candidate.html',
                               form=form,
                               strawberries=program.strawberries_last,
                               identifier=identifier,
                               testing=app.testing)

    submitted_prikey = form.prikey.data

    if program.pubkey is None:
        return redirect(url_for('index'))

    if validate_private_key(submitted_prikey, program.pubkey):
        app.logger.info(f"Implementation is broken at {now}")
        program.set_status_to_broken(current_user, now)
        db.session.commit()

        return redirect(url_for('break_candidate_ok', identifier=identifier))
    else:
        app.logger.info("Invalid private key")
        return render_template('challenge_break_ko.html',
                               identifier=identifier,
                               current_user=current_user,
                               submitted_prikey=submitted_prikey,
                               pubkey=program.pubkey)
Ejemplo n.º 3
0
def submit_candidate():
    now = int(time.time())
    if now < app.config['STARTING_DATE']:
        return render_template('submit_candidate_before_starting_date.html',
                               active_page='submit_candidate',
                               starting_date=utils.format_timestamp(
                                   app.config['STARTING_DATE']))
    if now > app.config['POSTING_DEADLINE']:
        return render_template('submit_candidate_deadline_exceeded.html',
                               active_page='submit_candidate',
                               posting_deadline=utils.format_timestamp(
                                   app.config['POSTING_DEADLINE']))
    form = WhiteboxSubmissionForm()
    if request.method != 'POST':
        return render_template('submit_candidate.html',
                               form=form,
                               active_page='submit_candidate',
                               testing=app.testing)
    elif not form.validate_on_submit():
        return render_template('submit_candidate.html',
                               form=form,
                               active_page='submit_candidate',
                               testing=app.testing), 400
    else:
        upload_folder = app.config['UPLOAD_FOLDER']
        basename = ''.join(
            random.SystemRandom().choice(string.ascii_lowercase +
                                         string.digits) for _ in range(32))
        filename = basename + '.c'
        key = form.key.data
        form_data = form.program.data
        form_data.save(os.path.join(upload_folder, filename))
        Program.create(basename=basename, key=key, user=current_user)
        db.session.commit()
        utils.launch_compilation_and_test()
        return redirect(url_for('submit_candidate_ok'))
Ejemplo n.º 4
0
 def datetime_first_break(self):
     if self._timestamp_first_break is None:
         return None
     else:
         return utils.format_timestamp(self._timestamp_first_break)
Ejemplo n.º 5
0
 def datetime_published(self):
     return utils.format_timestamp(self._timestamp_published)
Ejemplo n.º 6
0
 def datetime_strawberries_next_update(self):
     return utils.format_timestamp(self._timestamp_strawberries_next_update)
Ejemplo n.º 7
0
 def datetime_submitted(self):
     return utils.format_timestamp(self._timestamp_submitted)
Ejemplo n.º 8
0
def break_candidate(identifier):
    now = int(time.time())
    if now < app.config['STARTING_DATE']:
        return redirect(url_for('index'))
    if now > app.config['FINAL_DEADLINE']:
        return render_template('break_candidate_deadline_exceeded.html',
                               active_page='submit_candidate',
                               final_deadline=utils.format_timestamp(
                                   app.config['FINAL_DEADLINE']))

    # Only published programs can be broken
    program = Program.get_unbroken_or_broken_by_id(identifier)
    if program is None or not program.is_published:
        return redirect(url_for('index'))

    # If the current user is the one who submitted the program, redirect to index
    if program.user == current_user:
        crx_flash('CANNOT_BREAK_OWN')
        return redirect(url_for('index'))

    # A user cannot break the same challenge twice
    wb_break = WhiteboxBreak.get(current_user, program)
    if wb_break is not None:
        crx_flash('CANNOT_BREAK_TWICE')
        return redirect(url_for('index'))

    form = WhiteboxBreakForm()
    if request.method != 'POST' or not form.validate_on_submit():
        return render_template('break_candidate.html',
                               form=form,
                               datetime_strawberries_next_update=program.
                               datetime_strawberries_next_update,
                               strawberries=program.strawberries_last,
                               identifier=identifier,
                               testing=app.testing)

    if program.plaintexts is None or program.ciphertexts is None:
        return redirect(url_for('index'))
    if len(program.plaintexts) != len(program.ciphertexts):
        return redirect(url_for('index'))
    if len(program.plaintexts) % 16 != 0:
        return redirect(url_for('index'))

    number_of_test_vectors = len(program.plaintexts) // 16
    key = bytes.fromhex(form.key.data)
    try:
        aes = AES.new(key, AES.MODE_ECB)
    except:
        return redirect(url_for('index'))
    for i in range(number_of_test_vectors):
        plaintext = program.plaintexts[16 * i:16 * (i + 1)]
        ciphertext = program.ciphertexts[16 * i:16 * (i + 1)]
        try:
            computed_ciphertext = aes.encrypt(plaintext)
        except:
            computed_ciphertext = None
        if computed_ciphertext is None or ciphertext != computed_ciphertext:
            plaintext_as_text = binascii.hexlify(plaintext).decode()
            ciphertext_as_text = binascii.hexlify(ciphertext).decode()
            return render_template('challenge_break_ko.html',
                                   identifier=identifier,
                                   current_user=current_user,
                                   plaintext=plaintext_as_text,
                                   ciphertext=ciphertext_as_text)

    # If we reach this point, the submitted key is correct
    program.set_status_to_broken(current_user, now)
    db.session.commit()

    return redirect(url_for('break_candidate_ok', identifier=identifier))