Ejemplo n.º 1
0
def get(filename):

    # Locate document. This sample should not ocntinue if the file is not found.
    if not os.path.exists(os.path.join(current_app.config['APPDATA_FOLDER'],
                                       filename)):
        # Return "Not found" code.
        abort(404)
        return

    # Get an instance of the PadesTimestamper class, used to timestamp a PDF
    # file.
    stamper = PadesTimestamper()

    # Set PKI default (see utils.py).
    set_pki_defaults(stamper)

    # Set the PDF to be timestamped.
    stamper.set_pdf_from_path(os.path.join(current_app.config['APPDATA_FOLDER'],
                                                              filename))

    # Generate path for output file and add to the stamper.
    create_app_data() # Guarantees that "app_data" folder exists.
    output_file = '%s.pdf' % str(uuid.uuid4())
    stamper.output_file_path = os.path.join(
        current_app.config['APPDATA_FOLDER'], output_file)

    # Add a timestmap to the PDF file.
    stamper.stamp()

    # Return the stamped PDF as a downloadable file.
    return send_from_directory(current_app.config['APPDATA_FOLDER'],
                               output_file)
def index():

    # Get an instance of the Authentication class.
    auth = Authentication()

    # Set PKI default options (see utils.py).
    set_pki_defaults(auth)

    # Start the authentication. Receive as response a AuthStartResult instance
    # containing the following fields:
    # - nonce: The nonce to be signed. This value is also used on "complete"
    #          action.
    # - digest_algorithm: The digest algorithm that will inform the Web PKI
    #                     component to compute the signature.
    result = auth.start()

    # Render the fields received form start() method as hidden field to be used
    # on the javascript and on the "complete" step. We pass the nonce as base64
    # to be rendered on page.
    response = make_response(
        render_template('authentication_express/index.html',
                        nonce=result.nonce,
                        digest_algorithm=result.digest_algorithm))

    # The nonce acquired above can only be used for a single authentication
    # attempt. In order to retry the signature it is necessary to get a new
    # token. This can be a problem if the user uses the back button of the
    # browser, since the browser might show a cached page that we rendered
    # previously, with a now stale token. To prevent this from happening, we
    # call the method set_no_cache_headers(), which sets HTTP headers to prevent
    # caching of the page.
    get_expired_page_headers(response.headers)

    return response
Ejemplo n.º 3
0
def start():
    """

    This method starts the signature. In this sample, it will be called
    programatically after the user press the "Sign File" button (see method
    readCertificate() on static/js/signature-start-form.js).

    """
    userfile = None
    try:
        # Recover variables from the POST arguments to be used on this step.
        cert_thumb = request.form['certThumbField']
        cert_content = request.form['certContentField']
        if request.form['userfileField'] != 'None':
            userfile = request.form['userfileField']

        # Get an instance of the CadesSignatureStarter class, responsible for
        # receiving the signature elements and start the signature process.
        signature_starter = CadesSignatureStarter()

        # Set PKI default options (see utils.py).
        set_pki_defaults(signature_starter)

        # Set signature policy.
        signature_starter.signature_policy = \
            standard_signature_policies.PKI_BRAZIL_CADES_ADR_BASICA

        # Set file to be signed. If the file is a CMS, PKI Express will
        # recognize that and will co-sign that file.
        if userfile:
            signature_starter.set_file_to_sign_from_path(
                os.path.join(current_app.config['APPDATA_FOLDER'], userfile))
        else:
            signature_starter.set_file_to_sign_from_path(get_sample_doc_path())

        # Set Base64-encoded certificate's content to signature starter.
        signature_starter.set_certificate_from_base64(cert_content)

        # Set 'encapsulated content' option (default: True).
        signature_starter.encapsulated_content = True

        # Start the signature process. Receive as response the following fields:
        # - to_sign_hash:     The hash to be signed.
        # - digest_algorithm: The digest algorithm that will inform the Web PKI
        #                     component to compute the signature.
        # - transfer_file:    A temporary file to be passed to "complete" step.
        response = signature_starter.start()

        # Render the field from start() method as hidden fields to be used on
        # the javascript or on the "complete" step.
        return render_template('cades_signature/start.html',
                               to_sign_hash=response['toSignHash'],
                               digest_algorithm=response['digestAlgorithm'],
                               transfer_file=response['transferFile'],
                               cert_thumb=cert_thumb,
                               userfile=userfile)

    except Exception as e:
        flash(str(e))
        return redirect(url_for('cades_signature.index', userfile=userfile))
Ejemplo n.º 4
0
def attached(file_id1, file_id2):
    """

    This function performs a merge of CAdES signature using PKI Express
    when both signatures have encapsulated content

    """
    # Get an instance of the CadesSignatureEditor class, responsible for
    # receiving the files and merge them.
    signature_editor = CadesSignatureEditor()

    # Set PKI default options (see utils.py).
    set_pki_defaults(signature_editor)

    # Guarantees that "app data" folder exists.
    create_app_data()

    # Generate output filename
    output_file = '%s.p7s' % (str(uuid.uuid4()))

    # Add both signatures
    signature_editor.add_cms_file_from_path(
        os.path.join(current_app.config['APPDATA_FOLDER'], file_id1))
    signature_editor.add_cms_file_from_path(
        os.path.join(current_app.config['APPDATA_FOLDER'], file_id2))

    # Set path to output file
    signature_editor.output_file = os.path.join(
        current_app.config['APPDATA_FOLDER'], output_file)

    # Merge files
    signature_editor.merge()
    return render_template('merge_cades_express/index.html',
                           output_file=output_file)
Ejemplo n.º 5
0
def complete():
    # Recover variables from the POST arguments to be used on this step.
    file_id = request.form['id']
    transfer_file = request.form['transferFile']
    signature = request.form['signature']

    # Get an instance of the SignatureFinisher class, responsible for completing
    # the signature process.
    signature_finisher = SignatureFinisher()

    # Set PKI default options (see utils.py).
    set_pki_defaults(signature_finisher)

    # Set the file to be signed. It's the same file we use don "start" method.
    signature_finisher.set_file_to_sign_from_path(
        get_sample_batch_doc_path(file_id))

    # Set the transfer file.
    signature_finisher.set_transfer_file_from_path(transfer_file)

    # Set the signature file.
    signature_finisher.signature = signature

    # Generate path for output file and add to the signature finisher.
    create_app_data()  # Guarantees that "app data" folder exists.
    filename = '%s.p7s' % (str(uuid.uuid4()))
    signature_finisher.output_file = \
        join(current_app.config['APPDATA_FOLDER'], filename)

    # Complete the signature process.
    signature_finisher.complete()

    return jsonify(filename)
Ejemplo n.º 6
0
def index(file_id):

    # Locate document. This sample should not continue if the file is not found.
    if not exists(join(current_app.config['APPDATA_FOLDER'], file_id)):
        return render_template('error.html', msg='File not found')

    # Get an instance of the PadesTimestamper class, used to timestamp a PDF
    # file.
    stamper = PadesTimestamper()

    # Set PKI default (see utils.py).
    set_pki_defaults(stamper)

    # Set the PDF to be timestamped.
    stamper.set_pdf_from_path(join(current_app.config['APPDATA_FOLDER'],
                                   file_id))

    # Generate path for output file and add to the stamper.
    create_app_data()  # Guarantees that "app_data" folder exists.
    output_file = '%s.pdf' % str(uuid.uuid4())
    output_file_path = join(current_app.config['APPDATA_FOLDER'], output_file)
    stamper.output_file_path = output_file_path

    # Add a timestamp to the PDF file.
    stamper.stamp()

    # Return the stamped PDF as a downloadable file.
    return send_from_directory(current_app.config['APPDATA_FOLDER'],
                               output_file)
Ejemplo n.º 7
0
def start():
    # Recover variables from the POST arguments to be used in this step.
    file_id = request.form['id']
    cert_content = request.form['certContent']

    # Get an instance of the CadesSignatureStarter class, responsible for
    # receiving the signature elements and start the signature process.
    signature_starter = CadesSignatureStarter()

    # Set PKI default options (see utils.py).
    set_pki_defaults(signature_starter)

    # Set signature policy.
    signature_starter.signature_policy = \
        standard_signature_policies.PKI_BRAZIL_CADES_ADR_BASICA

    # Set file to be signed based on its ID.
    signature_starter.set_file_to_sign_from_path(
        get_sample_batch_doc_path(file_id))

    # Set Base64-encoded certificate's content to signature starter.
    signature_starter.set_certificate_from_base64(cert_content)

    # Set 'encapsulated content' option (default: True).
    signature_starter.encapsulated_content = True

    # Start the signature process. Receive as response the following fields:
    # - to_sign_hash:     The hash to be signed.
    # - digest_algorithm: The digest algorithm that will inform the Web PKI
    #                     component to compute the signature.
    # - transfer_file:    A temporary file to be passed to "complete" step.
    response = signature_starter.start()

    return jsonify(response)
Ejemplo n.º 8
0
def index(file_id):

    # Verify if the provided userfile exists.
    file_path = os.path.join(current_app.config['APPDATA_FOLDER'], file_id)
    if not os.path.exists(file_path):
        return render_template('error.html', msg='File not found')

    # Get an instance of the PadesSignatureExplorer class, used to open/validate
    # PDF signatures.
    sig_explorer = PadesSignatureExplorer()

    # Set PKI default options (see utils.py)
    set_pki_defaults(sig_explorer)

    # Specify that we want to validate the signatures in the file, not only
    # inspect them.
    sig_explorer.validate = True

    # Set the PDF file to be inspected.
    sig_explorer.set_signature_file_from_path(file_path)

    # Call the open() method, which returns the signature file's information.
    signature = sig_explorer.open()

    # Render the signature opening page.
    return render_template('open_pades_express/index.html',
                           signature=signature)
def start(file_id):
    """

    This method starts the signature. In this sample, it will be called
    programatically after the user press the "Sign File" button (see method
    readCertificate() on static/js/signature-start-form.js).

    """
    try:
        # Recover variables from the POST arguments to be used on this step.
        cert_thumb = request.form['certThumbField']
        cert_content = request.form['certContentField']

        # Get an instance of the PadesSignatureStarter class, responsible for
        # receiving the signature elements and start the signature process.
        signature_starter = PadesSignatureStarter()

        # Set PKI default options (see utils.py).
        set_pki_defaults(signature_starter)

        # Set signature policy.
        signature_starter.signature_policy = \
            standard_signature_policies.PADES_BASIC_WITH_LTV

        # Set PDF to be signed
        signature_starter.set_pdf_to_sign_from_path(
            os.path.join(current_app.config['APPDATA_FOLDER'], file_id))

        # Set Base64-encoded certificate's content to signature starter.
        signature_starter.set_certificate_from_base64(cert_content)

        # Set a file reference for the stamp file. Note that this file can be
        # referenced later by "fref://{alias}" at the "url" field on the visual
        # representation (see static/vr.json or get_visual_representation()
        # method).
        signature_starter.add_file_reference('stamp', get_pdf_stamp_path())

        # Set the visual representation. We provided a dictionary that
        # represents the visual representation JSON model.
        signature_starter.set_visual_representation(
            PadesVisualElementsExpress.get_visual_representation())

        # Start the signature process. Receive as response the following fields:
        # - to_sign_hash:     The hash to be signed.
        # - digest_algorithm: The digest algorithm that will inform the Web PKI
        #                     component to compute the signature.
        # - transfer_file:    A temporary file to be passed to "complete" step.
        response = signature_starter.start()

        # Render the field from start() method as hidden field to be used on the
        # javascript or on the "complete" step.
        return render_template('pades_signature_express/start.html',
                               cert_thumb=cert_thumb,
                               transfer_file_id=response['transferFile'],
                               to_sign_hash=response['toSignHash'],
                               digest_algorithm=response['digestAlgorithm'])

    except Exception as e:
        return render_template('error.html', msg=e)
Ejemplo n.º 10
0
def index(userfile):

    try:

        # Verify if the provided userfile exists.
        if not os.path.exists(
                os.path.join(current_app.config['APPDATA_FOLDER'], userfile)):
            return render_template('error.html', msg='File not found')

        # Get an instance of the PadesSigner class, responsible for receiving
        # the signature elements and performing the local signature.
        signer = PadesSigner()

        # Set PKI default options (see utils.py).
        set_pki_defaults(signer)

        # Set signature policy.
        signer.signature_policy = \
            standard_signature_policies.PADES_BASIC_WITH_LTV

        # Set PDF to be signed.
        signer.set_pdf_to_sign_from_path(
            os.path.join(current_app.config['APPDATA_FOLDER'], userfile))

        # The PKCS #12 certificate path.
        signer.set_pkcs12_from_path(
            os.path.join(current_app.static_folder, 'Pierre de Fermat.pfx'))
        # Set the certificate's PIN.
        signer.cert_password = '******'

        # Set a file reference for the stamp file. Note that this file can be
        # referenced later by "fref://{alias}" at the "url" field on the visual
        # representation (see content/vr.json or get_visual_representation()
        # method).
        signer.add_file_reference('stamp', get_pdf_stamp_path())

        # Set visual representation. We provide a dictionary that represents the
        # visual representation JSON model.
        signer.set_visual_representation(get_visual_representation())

        # Generate path for output file and add to signer object.
        create_app_data()  # Guarantees that "app data" folder exists.
        output_file = '%s.pdf' % (str(uuid.uuid4()))
        signer.output_file = os.path.join(current_app.config['APPDATA_FOLDER'],
                                          output_file)

        # Perform the signature.
        signer_cert = signer.sign(get_cert=True)

        response = make_response(
            render_template('pades_signature_server_key/index.html',
                            signer_cert=signer_cert,
                            filename=output_file))
        response.headers = get_expired_page_headers()
        return response

    except Exception as e:
        return render_template('error.html', msg=e)
Ejemplo n.º 11
0
def complete():
    """

    This function completes the signature, it will be called programatically
    after the Web PKI component perform the signature and submit the form (see
    method sign() on static/js/signature-complete-form.js).

    """
    userfile = None
    try:

        # Recover variables from the POST arguments to be used on this step.
        transfer_file = request.form['transferFileField']
        signature = request.form['signatureField']
        if request.form['userfileField'] != 'None':
            userfile = request.form['userfileField']

        # Get an instance of the SignatureFinisher class, responsible for
        # completing the signature process.
        signature_finisher = SignatureFinisher()

        # Set PKI default options (see utils.py).
        set_pki_defaults(signature_finisher)

        # Set the file to be signed. It's the same file we used on "start"
        # method.
        if userfile:
            signature_finisher.set_file_to_sign_from_path(
                os.path.join(current_app.config['APPDATA_FOLDER'], userfile))
        else:
            signature_finisher.set_file_to_sign_from_path(
                get_sample_doc_path())

        # Set the transfer file.
        signature_finisher.set_transfer_file_from_path(transfer_file)

        # Set the signature file.
        signature_finisher.signature = signature

        # Generate path for output file and add to the signature finisher.
        create_app_data()  # Guarantees that "app data" folder exists.
        filename = '%s.p7s' % (str(uuid.uuid4()))
        signature_finisher.output_file = \
            os.path.join(current_app.config['APPDATA_FOLDER'], filename)

        # Complete the signature process.
        signer_cert = signature_finisher.complete(get_cert=True)

        return render_template('cades_signature/signature-info.html',
                               signer_cert=signer_cert,
                               filename=filename)

    except Exception as e:
        flash(str(e))
        return redirect(url_for('cades_signature.index', userfile=userfile))
def index(userfile):

    try:

        # Verify if the provided userfile exists.
        if not os.path.exists(
                os.path.join(current_app.config['APPDATA_FOLDER'], userfile)):
            return render_template('error.html', msg='File not found')

        # Get an instance of the CadesSigner class, responsible for receiving
        # the signature elements and performing the local signature.
        signer = CadesSigner()

        # Set PKI default options (see utils.py).
        set_pki_defaults(signer)

        # Set signature policy.
        signer.signature_policy = \
            standard_signature_policies.PKI_BRAZIL_CADES_ADR_BASICA

        # Set file to be signed. If the file is a CSM, the PKI Express will
        # recognize that and will co-sign that file.
        signer.set_file_to_sign_from_path(
            os.path.join(current_app.config['APPDATA_FOLDER'], userfile))

        # The PKCS #12 certificate path.
        signer.set_pkcs12_from_path(
            os.path.join(current_app.static_folder, 'Pierre de Fermat.pfx'))
        # Set the certificate's PIN.
        signer.cert_password = '******'

        # Set 'encapsulate content' option (default: True).
        signer.encapsulated_content = True

        # Generate path for output file and add to signer object.
        create_app_data()  # Guarantees that "app_data" folder exists.
        output_file = '%s.p7s' % (str(uuid.uuid4()))
        signer.output_file = os.path.join(current_app.config['APPDATA_FOLDER'],
                                          output_file)

        # Perform the signature.
        signer_cert = signer.sign(get_cert=True)

        response = make_response(
            render_template('cades_signature_server_key/index.html',
                            signer_cert=signer_cert,
                            filename=output_file))
        response.headers = get_expired_page_headers()
        return response

    except Exception as e:
        return render_template('error.html', msg=e)
Ejemplo n.º 13
0
def start():
    """

    This method is called asynchronously via AJAX by the batch signature page
    for each document being signed. It receives the ID of the document and
    initiates a PAdES signature using PKI Express and returns a JSON with the
    data needed in the next signature steps (see batch-signature-form.js).

    """

    # Recover variables from the POST arguments to be used in this step.
    file_id = request.form['id']
    cert_content = request.form['certContent']

    # Get an instance of the PadesSignatureStarter, responsible for receiving
    # the signature elements and start the signature process.
    signature_starter = PadesSignatureStarter()

    # Set PKI default options (see utils.py).
    set_pki_defaults(signature_starter)

    # Set signature policy.
    signature_starter.signature_policy = \
        standard_signature_policies.PADES_BASIC_WITH_LTV

    # Set PDF to be signed based on its ID.
    signature_starter.set_pdf_to_sign_from_path(
        get_sample_batch_doc_path(file_id))

    # Set Base64-encoded certificate's content to signature starter.
    signature_starter.set_certificate_from_base64(cert_content)

    # Set a file reference for the stamp file. Note that this file can be
    # referenced later by "fref://{alias}" at the "url" field on the visual
    # representation (see static/vr.json or get_visual_representation()
    # method).
    signature_starter.add_file_reference('stamp', get_pdf_stamp_path())

    # Set the visual representation. We provided a dictionary that
    # represents the visual representation JSON model.
    signature_starter.set_visual_representation(
        PadesVisualElementsExpress.get_visual_representation())

    # Start the signature process. Receive as response the following fields:
    # - to_sign_hash:     The hash to be signed.
    # - digest_algorithm: The digest algorithm that will inform the Web PKI
    #                     component to compute the signature.
    # - transfer_file:    A temporary file to be passed to "complete" step.
    response = signature_starter.start()

    return jsonify(response)
Ejemplo n.º 14
0
def index(code):

    # On printer_version_pades_express, we stored the unformatted version of the
    # verification code (without hyphens), but used the formatted version (with
    # hyphens) on the printer-friendly PDF. Now, we remove the hyphens before
    # looking it up.
    verification_code = parse_verification_code(code)

    # Get document associated with verification code.
    file_id = lookup_verification_code(verification_code)
    if file_id is None:
        # Invalid code given!
        # Small delay to slow down brute-force attacks (if you want to be extra
        # careful you might want to add a CAPTCHA to the process)
        sleep(2)
        # Return "Not Found" page.
        return render_template('error.html', msg='File not found')

    # Locate document from storage.
    file_path = os.path.join(current_app.config['APPDATA_FOLDER'], file_id)

    # Get an instance of the PadesSignatureExplorer class, used to open/validate
    # PDF signatures.
    sig_explorer = PadesSignatureExplorer()

    # Set PKI default options (see utils.py)
    set_pki_defaults(sig_explorer)

    # Specify that we want to validate the signatures in the file, not only
    # inspect them.
    sig_explorer.validate = True

    # Set the PDF file to be inspected.
    sig_explorer.set_signature_file_from_path(file_path)

    # Call the open() method, which returns the signature file's information.
    signature = sig_explorer.open()

    # Render the signature opening page.
    return render_template('check_pades_express/index.html',
                           signature=signature,
                           file_id=file_id)
def complete():
    """

    This method is called asynchronously via AJAX by the batch signature page
    for each document being signed. It completes the CAdES signature using
    PKI Express and returns a JSON with the saved filename so that the page can
    render a link to it.

    """

    # Recover variables from the POST arguments to be used on this step.
    file_id = request.form['id']
    transfer_file = request.form['transferFile']
    signature = request.form['signature']

    # Get an instance of the SignatureFinisher class, responsible for completing
    # the signature process.
    signature_finisher = SignatureFinisher()

    # Set PKI default options (see utils.py).
    set_pki_defaults(signature_finisher)

    # Set the file to be signed. It's the same file we use don "start" method.
    signature_finisher.set_file_to_sign_from_path(
        get_sample_batch_doc_path(file_id))

    # Set the transfer file.
    signature_finisher.set_transfer_file_from_path(transfer_file)

    # Set the signature file.
    signature_finisher.signature = signature

    # Generate path for output file and add to the signature finisher.
    create_app_data()  # Guarantees that "app data" folder exists.
    filename = '%s.p7s' % (str(uuid.uuid4()))
    signature_finisher.output_file = \
        os.path.join(current_app.config['APPDATA_FOLDER'], filename)

    # Complete the signature process.
    signature_finisher.complete()

    return jsonify(filename)
Ejemplo n.º 16
0
def action():

    # Retrieve the values necessary to complete the authentication (rendered in
    # hidden inputs, see authentication/index.html template):
    # - nonce: The cryptographic nonce encoded as Base64.
    # - certContent: The content of the certificate, which is being
    #                 authenticated encoded as Base64.
    # - signature: The computed signature encoded as Base64.
    nonce_base64 = request.form['nonce']
    cert_content_base64 = request.form['certContent']
    signature_base64 = request.form['signature']

    # Get an instance of the Authentication class.
    auth = Authentication()

    # Set PKI default options (see utils.py).
    set_pki_defaults(auth)

    # Set the nonce. This value is generate on "start" action and passed by a
    # hidden field.
    auth.nonce_base64 = nonce_base64

    # Set the Base64-encoded certificate content.
    auth.certificate_base64 = cert_content_base64

    # Set the signature.
    auth.signature_base64 = signature_base64

    # Complete the authentication. Receive as response a AuthCompleteResult
    # instance containing the following fields:
    # - The certificate information;
    # - The validation results.
    result = auth.complete()

    # Check the authentication result.
    vr = result.validation_results
    if not vr.is_valid:

        # If the Authentication was not successful, we render a page showing
        # that what went wrong.

        # The __str__() method of the ValidationResults object can be used to
        # obtain the checks performed, but the string contains tabs and new line
        # characters for formatting, which we'll convert to <br>'s and &nbsp;'s.
        vr_html = str(vr)\
            .replace('\n', '<br>')\
            .replace('\t', '&nbsp;&nbsp;&nbsp;&nbsp;')

        # Render the authentication failed page
        # (templates/authentication_express/failed.html)
        return render_template('authentication_express/failed.html',
                               vr_html=vr_html)

    # At this point, you have assurance that the certificate is valid. Now,
    # you'd typically query your database for a user that matches one of the
    # certificate's fields, such as user_cert.email_address or
    # user_cert.pki_brazil.cpf (the actual field to be used as key depends on
    # your application's business logic) and set the user as authenticated
    # with whatever web security framework your application uses. For
    # demonstration purposes. we'll just render the user's certificate
    # information.
    user_cert = result.certificate

    # Render the authentication succeeded page
    # (templates/authentication_express/success.html).
    return render_template('authentication_express/success.html',
                           user_cert=user_cert)
def complete():
    """

    This action will complete the authentication process and create a signature using a session
    token returned by user. Also, we recover the parameter "customState" containing the id of the
    file that will be signed.

    """
    try:
        # Recover variables from query parameters.
        code = request.args.get('code')
        state = request.args.get('state')

        # Get an instance of the TrustServiceManager class, responsible for communicating with 
        # PSCs and handling the OAuth flow.
        manager = TrustServicesManager()

        # Complete the authentication process, recovering the session info to be used on the
        # signature and the custom state (fileId).
        result = manager.complete_auth(code, state)

        # Recover file id on custom state parameter.
        file_id = result.custom_state

        # Verify if the provided file_id exists.
        file_path = join(current_app.config['APPDATA_FOLDER'], file_id)
        if not exists(file_path):
            return render_template('error.html', msg='File not found')

        # Get an instance of the PadesSigner class, responsible for receiving
        # the signature elements and performing the local signature.
        signer = PadesSigner()

        # Set PKI default options (see utils.py).
        set_pki_defaults(signer)

        # Set signature policy.
        signer.signature_policy = standard_signature_policies.PADES_BASIC_WITH_LTV

        # Set PDF to be signed.
        signer.set_pdf_to_sign_from_path(file_path)

        # Set trust session acquired on the following steps of this sample.
        signer.trust_service_session = result.session

        # Set a file reference for the stamp file. Note that this file can be
        # referenced later by "fref://{alias}" at the "url" field on the visual
        # representation (see content/vr.json or get_visual_representation()
        # method).
        signer.add_file_reference('stamp', get_pdf_stamp_path())

        # Set visual representation. We provide a dictionary that represents the
        # visual representation JSON model.
        signer.set_visual_representation(
            PadesVisualElementsExpress.get_visual_representation())

        # Generate path for output file and add to signer object.
        create_app_data()  # Guarantees that "app data" folder exists.
        output_file = '%s.pdf' % (str(uuid.uuid4()))
        signer.output_file = join(current_app.config['APPDATA_FOLDER'], output_file)

        # Perform the signature.
        signer_cert = signer.sign(get_cert=False)

        response = make_response(render_template(
            'pades_cloud_oauth_express/signature-info.html',
            signed_pdf=output_file))
        get_expired_page_headers(response.headers)

        return response

    except Exception as e:
        return render_template('error.html', msg=e)
def generate_printer_friendly_version(pdf_path, verification_code):
    # The verification code is generated without hyphens to save storage space
    # and avoid copy-and-paste problems. On the PDF generation, we use the
    # "formatted" version, with hyphens (which will later be discarded on the
    # verification page)
    formatted_verification_code = format_verification_code(verification_code)

    # Build the verification link from the constant "VERIFICATION_LINK_FORMAT"
    # (see above) and the formatted verification code.
    verification_link = VERIFICATION_LINK_FORMAT % formatted_verification_code

    # 1. Inspect signatures on the uploaded PDF

    # Get and instance of the PadesSignatureExplorer class, used to
    # open/validate PDF signatures.
    sig_explorer = PadesSignatureExplorer()
    # Set PKI default options (see utils.py).
    set_pki_defaults(sig_explorer)
    # Specify that we want to validate the signatures in the file, not only
    # inspect them.
    sig_explorer.validate = True
    # Set the PDF file to be inspected.
    sig_explorer.set_signature_file_from_path(pdf_path)
    # Call the open() method, which returns the signature file's information.
    signature = sig_explorer.open()

    # 2. Create PDF with the verification information from uploaded PDF.

    # Get an instance of the PdfMarker class, used to apply marks on the PDF.
    pdf_marker = PdfMarker()
    # Set PKI default options (see utils.py).
    set_pki_defaults(pdf_marker)
    # Specify the file to be marked.
    pdf_marker.set_file_from_path(pdf_path)

    # Build string with joined names of signers (see method get_display_name
    # below)
    signer_names_list = []
    for signer in signature.signers:
        signer_names_list.append(get_display_name(signer.certificate))
    signer_names = join_strings_pt(signer_names_list)
    all_pages_message = "This document was digitally signed by %s.\n" \
                        "To check the signatures, visit %s at %s and inform this code %s." % (signer_names, VERIFICATION_SITE_NAME_WITH_ARTICLE, VERIFICATION_SITE, formatted_verification_code)

    # PdfHelper is a class from the PKI Express's "fluent API" that helps
    # creating elements and parameters for the PdfMarker.
    pdf = PdfHelper()

    # ICP-Brasil logo on bottom-right corner of every page (except on the page
    # which will be created at the end of the document)
    pdf_marker.marks.append(pdf.mark().on_all_pages().on_container(
        pdf.container().width(1.0).anchor_right(1.0).height(1.0).anchor_bottom(
            1.0)).add_element(
                pdf.image_element().with_opacity(75).with_image_content(
                    get_icp_brasil_logo_content(), "image/png")))

    # Summary on bottom margin of every page (except on the page which will be
    # created at the end of the document)
    pdf_marker.marks.append(pdf.mark().on_all_pages().on_container(
        pdf.container().height(2.0).anchor_bottom().var_width().margins(
            1.5, 3.5)).add_element(pdf.text_element().with_opacity(
                75).add_section_from_text(all_pages_message)))

    # Summary on right margin of every page (except on the page which will be
    # created at the end of the document), rotated 90 degrees counterclockwise
    # (text goes up).
    pdf_marker.marks.append(pdf.mark().on_all_pages().on_container(
        pdf.container().width(2.0).anchor_right().var_height().margins(
            1.5, 3.5)).add_element(
                pdf.text_element().rotate_90_counter_clockwise().with_opacity(
                    75).add_section_from_text(all_pages_message)))

    # Create a "manifest" mark on a new page added on the end of the document.
    # We'll add several elements to this mark.
    manifest_mark = pdf.mark()\
        .on_new_page()\
        .on_container(
            pdf.container()
            .var_width_and_height()
            .margins(2.54, 2.54))

    # We'll keep track of our "vertical offset" as we add elements to the mark.
    vertical_offset = 0

    element_height = 3
    # ICP-Brasil logo on the upper-left corner. Using elementHeight as width
    # because the image is a square.
    manifest_mark.add_element(pdf.image_element().on_container(
        pdf.container().height(element_height).anchor_top(vertical_offset).
        width(element_height).anchor_left()).with_image_content(
            get_icp_brasil_logo_content(), "image/png"))

    # QR Code with the verification link on the upper-right corner. Using
    # elementHeight as width because the image is a square.
    manifest_mark.add_element(pdf.qr_code_element().on_container(
        pdf.container().height(element_height).anchor_top(
            vertical_offset).width(element_height).anchor_right(
            )).with_qr_code_data(verification_link).draw_quiet_zones())

    manifest_mark.add_element(pdf.text_element().on_container(
        pdf.container().height(element_height).anchor_top(
            vertical_offset *
            0.2).full_width()).align_text_center().add_section(
                pdf.text_section().with_font_size(
                    NORMAL_FONT_SIZE * 1.6).with_text('SIGNATURE\nCHECK')))
    vertical_offset += element_height

    # Vertical padding.
    vertical_offset += 1.7

    # Header with verification code.
    element_height = 2
    manifest_mark.add_element(pdf.text_element().on_container(
        pdf.container().height(element_height).anchor_top(
            vertical_offset).full_width()).align_text_center().add_section(
                pdf.text_section().with_font_size(
                    NORMAL_FONT_SIZE * 1.2).with_text(
                        "Verification code: %s" %
                        formatted_verification_code)))
    vertical_offset += element_height

    # Paragraph saving "this document was signed by the following signers etc"
    # and mentioning the timezone of the date/times below.
    element_height = 2.5
    manifest_mark.add_element(pdf.text_element().on_container(
        pdf.container().height(element_height).anchor_top(
            vertical_offset).full_width()
    ).add_section(pdf.text_section(
    ).with_font_size(NORMAL_FONT_SIZE).with_text(
        "This document was digitally signed by the following signers on the indicated dates (%s):"
        % TIME_ZONE_DISPLAY_NAME)))
    vertical_offset += element_height

    # Iterate signers.
    for signer in signature.signers:

        element_height = 1.5
        # Green "check" or red "X" icon depending on result of validation for
        # this signer.
        manifest_mark.add_element(pdf.image_element().on_container(
            pdf.container().height(0.5).anchor_top(vertical_offset + 0.2).
            width(0.5).anchor_left()).with_image_content(
                get_validation_result_icon(signer.validation_results.is_valid),
                'image/png'))

        # Description of signer (see method  get_signer_description() below).
        manifest_mark.add_element(pdf.text_element().on_container(
            pdf.container().height(element_height).anchor_top(vertical_offset).
            var_width().margins(0.8, 0.0)).add_section(
                pdf.text_section().with_font_size(NORMAL_FONT_SIZE).with_text(
                    get_signer_description(signer))))

        vertical_offset += element_height

    # Some vertical padding for last signer.
    vertical_offset += 1.0

    # Paragraph with link to verification site and citing both the verification
    # code above and the verification link below.
    element_height = 2.5
    manifest_mark.add_element(pdf.text_element().on_container(
        pdf.container().height(element_height).anchor_top(
            vertical_offset).full_width()).add_section(
                pdf.text_section().with_font_size(NORMAL_FONT_SIZE).with_text(
                    "In order to check the signatures, visit %s at " %
                    VERIFICATION_SITE_NAME_WITH_ARTICLE)
            ).add_section(
                pdf.text_section().with_font_size(NORMAL_FONT_SIZE).with_color(
                    Color.BLUE).with_text(VERIFICATION_SITE)
            ).add_section(
                pdf.text_section().with_font_size(NORMAL_FONT_SIZE).with_text(
                    ' and inform the code above or access the link below:')))
    vertical_offset += element_height

    # Verification link.
    element_height = 1.5
    manifest_mark.add_element(pdf.text_element().on_container(
        pdf.container().height(element_height).anchor_top(vertical_offset).
        full_width()).add_section(
            pdf.text_section().with_font_size(NORMAL_FONT_SIZE).with_color(
                Color.BLUE).with_text(verification_link)).align_text_center())

    # Add marks.
    pdf_marker.marks.append(manifest_mark)

    # Generate path for output file and add the marker.
    pfv_filename = "%s.pdf" % str(uuid.uuid4())
    pdf_marker.output_file = join(current_app.config['APPDATA_FOLDER'],
                                  pfv_filename)

    # Apply marks.
    pdf_marker.apply()

    # Return path for output file.
    return pfv_filename
def index(file_id):
    
    # Verify if the provided "file_id" exists.
    file_path = join(current_app.config['APPDATA_FOLDER'], file_id)
    if not exists(file_path):
        return render_template('error.html', msg='File not found')

    # Get an instance of the PadesSigner class, responsible for receiving
    # the signature elements and performing the local signature.
    signer = PadesSigner()

    # Set PKI default options (see utils.py).
    set_pki_defaults(signer)

    # Set signature policy.
    signer.signature_policy = standard_signature_policies.PADES_BASIC_WITH_LTV

    # Set PDF to be signed.
    signer.set_pdf_to_sign_from_path(file_path)

    # Set the PKCS #12 certificate path. There is a logic for choosing the generate the PKCS #12
    # from "issue certificate" samples or a sample PKCS #12. If no "certId" parameter is passed,
    # this example will use a default PFX file "Pierre de Fermat.pfx" stored at static/ folder.
    if request.args.get('certId', None) is None:
        # The PKCS #12 certificate path.
        signer.set_pkcs12_from_path(join(current_app.static_folder,
                                         'Pierre de Fermat.pfx'))
        # Set the certificate's PIN.
        signer.cert_password = '******'
    else:
        # Verify if the provided certId refers to an existing certificate file and key.
        cert_id = request.args.get('certId', None)
        if not exists(join(current_app.config['APPDATA_FOLDER'], cert_id)):
            return render_template('error.html', msg='File not found')

        # Set generate PKCS #12 and its password
        signer.set_pkcs12_from_path(join(current_app.config['APPDATA_FOLDER'], cert_id))
        signer.cert_password = '******'

    # Set a file reference for the stamp file. Note that this file can be
    # referenced later by "fref://{alias}" at the "url" field on the visual
    # representation (see content/vr.json or get_visual_representation()
    # method).
    signer.add_file_reference('stamp', get_pdf_stamp_path())

    # Set visual representation. We provide a dictionary that represents the
    # visual representation JSON model.
    signer.set_visual_representation(
        PadesVisualElementsExpress.get_visual_representation())

    # Generate path for output file and add to signer object.
    create_app_data()  # Guarantees that "app data" folder exists.
    output_file = '%s.pdf' % (str(uuid.uuid4()))
    signer.output_file = join(current_app.config['APPDATA_FOLDER'], output_file)

    # Perform the signature.
    signer_cert = signer.sign(get_cert=True)

    response = make_response(render_template(
        'pades_server_key_express/index.html',
        signer_cert=signer_cert,
        signed_pdf=output_file))
    get_expired_page_headers(response.headers)

    return response
Ejemplo n.º 20
0
def authorize(file_id):
    """"

    This action is called after the form after the user press the button "Sign". 
    This action will receive the user's CPF and current password.

    """
    try:
        # Recover variables from the POST arguments.
        cpf = request.form['cpf']
        service = request.form['service']
        password = request.form['password']

        # Process cpf, removing all formatting.
        plainCpf = cpf.replace(".", "").replace("-", "")

        # Get an instance of the TrustServiceManager class, responsible for communicating with 
        # PSCs and handling the password flow.
        manager = TrustServicesManager()

        # Complete authentication using CPF and current password. The following method has three sessionTypes:
        # - SINGLE_SIGNATURE: The returned token can only be used for one single signature request.
        # - MULTI_SIGNATURE: The returned token can only be used for one multi signature request.
        # - SIGNATURE_SESSION: The return token can only be used for one or more signature requests.
        result = manager.password_authorize(service, plainCpf, password, trust_service_session_types.SIGNATURE_SESSION)

        # Verify if the provided file_id exists.
        file_path = join(current_app.config['APPDATA_FOLDER'], file_id)
        if not exists(file_path):
            return render_template('error.html', msg='File not found')
        
        # Get an instance of the PadesSigner class, responsible for receiving
        # the signature elements and performing the local signature.
        signer = PadesSigner()

        # Set PKI default options (see utils.py).
        set_pki_defaults(signer)

        # Set signature policy.
        signer.signature_policy = standard_signature_policies.PADES_BASIC_WITH_LTV

        # Set PDF to be signed.
        signer.set_pdf_to_sign_from_path(file_path)

        # Set trust session acquired on the following steps of this sample.
        signer.trust_service_session = result.session

        # Set a file reference for the stamp file. Note that this file can be
        # referenced later by "fref://{alias}" at the "url" field on the visual
        # representation (see content/vr.json or get_visual_representation()
        # method).
        signer.add_file_reference('stamp', get_pdf_stamp_path())

        # Set visual representation. We provide a dictionary that represents the
        # visual representation JSON model.
        signer.set_visual_representation(
            PadesVisualElementsExpress.get_visual_representation())

        # Generate path for output file and add to signer object.
        create_app_data()  # Guarantees that "app data" folder exists.
        output_file = '%s.pdf' % (str(uuid.uuid4()))
        signer.output_file = join(current_app.config['APPDATA_FOLDER'], output_file)

        # Perform the signature.
        signer_cert = signer.sign(get_cert=False)

        response = make_response(render_template(
            'pades_cloud_pwd_express/signature-info.html',
            signed_pdf=output_file))
        get_expired_page_headers(response.headers)

        return response

    except Exception as e:
        return render_template('error.html', msg=e)