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'))
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)
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'))
def datetime_first_break(self): if self._timestamp_first_break is None: return None else: return utils.format_timestamp(self._timestamp_first_break)
def datetime_published(self): return utils.format_timestamp(self._timestamp_published)
def datetime_strawberries_next_update(self): return utils.format_timestamp(self._timestamp_strawberries_next_update)
def datetime_submitted(self): return utils.format_timestamp(self._timestamp_submitted)
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))